The test job loads sshleifer/tiny-gpt2 and hf-internal-testing/tiny-random-gpt2
from HF Hub. Under transient HF rate-limiting (429) a single matrix cell would
fail the model download (test_v07111.py::TestMiniLLM::test_anchor_term_with_file)
and drop coverage under the 77% gate — observed reding 3 commits today (~2/7
cells per run).
Add a best-effort pre-test step that snapshot_downloads both tiny models with
6 retries + backoff so the tests read from the warmed cache (verified locally:
the test passes with HF_HUB_OFFLINE=1 once the cache is warm). The step never
fails the job — it emits a :⚠️: if warming can't complete.
CI-only; no version bump.
mypy findings are surfaced as a warning annotation + step log instead of
failing the job. The workflow was already green (job-level continue-on-error),
but the type-check job itself rendered as a red X in the commit checks. Move
the tolerance to the step and emit a :⚠️: so the check stays green while
type annotations are adopted incrementally.
- add src/soup_cli/py.typed (PEP 561); verified it ships in the built wheel
- add .pre-commit-config.yaml (ruff lint+format + standard file-hygiene hooks)
- add mypy>=1.8.0 + pre-commit to the [dev] extra; lenient [tool.mypy] config
- add a non-blocking type-check CI job (mypy, continue-on-error: true)
- add CHANGELOG.md (Keep a Changelog; [Unreleased] + link to GitHub Releases)
- replace the ~221KB per-version security log in SECURITY.md with a concise policy
- raise the coverage gate 50% -> 77% (measured 79% on the suite; real-2 margin)
No version bump: hygiene/docs only — rides into the 0.71.0 deps-split release.
Move soup_cli/ -> src/soup_cli/ (history preserved via git mv). src-layout
forces the test suite to import the installed package instead of the
repo-root source tree, surfacing packaging bugs that flat-layout masks —
e.g. the v0.53.8 double-shipped-fixtures regression, invisible because
`pytest tests/` imports ./soup_cli directly and never from the wheel.
- pyproject: packages = ["src/soup_cli"]; artifacts globs -> src/soup_cli/...
The import name is unchanged, so the `soup` entry point, --cov=soup_cli,
and report_to/module-path strings stay `soup_cli`.
- CI / ownership: ruff lint path (ci.yml), recipe-validation `paths:` filters,
CODEOWNERS patterns, and the PR-template checklist all repointed to
src/soup_cli/.
- tests: source-grep regression tests that read package files by repo-relative
path repointed to src/soup_cli/ (64 files; 170 path literals). Lines pushed
over 100 chars by the prefix were wrapped to keep ruff E501 clean. Module
references (`import soup_cli`, `-m soup_cli`, mock.patch("soup_cli.x")) and
the `--cov=soup_cli` coverage target are deliberately unchanged.
- docs: AGENTS.md + CONTRIBUTING.md structure tree and lint commands.
Verified locally: ruff clean (src/soup_cli + tests); `import soup_cli`
resolves to src/soup_cli/__init__.py; built wheel ships
soup_cli/data/_fixtures/*.jsonl (10 files, no duplicates, no src/ prefix);
3174 tests across every touched test file pass. Packaging-only — no version bump.
The test-count badge step ran the gist PATCH with `curl -s -o /dev/null
-w "%{http_code}"` — discarded body, never set a non-zero exit code on
HTTP 4xx / 5xx. When GIST_TOKEN expired the gist returned 401 but CI
stayed green and the badge silently stuck on a stale value (2061
through several releases despite test count growing to 3818).
Switched to `curl --fail-with-body -sS` so:
- Non-2xx responses produce a non-zero exit code (CI fails loudly)
- Response body prints to stderr (so the operator sees the actual
GitHub error, e.g. "Bad credentials")
- Successful PATCH stays quiet (no progress bar)
Operator action required when this fires: rotate GIST_TOKEN at
https://github.com/settings/tokens (scope: gist) and update the
GIST_TOKEN secret at https://github.com/MakazhanAlpamys/Soup/settings/secrets/actions
Docs-only / CI-only change: no version bump, no soup_cli/ touched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Expand the recipe catalog from 46 to 80 entries — every popular open-weight
model family now has a validated Soup recipe.
Part A — Vision (6 recipes): Llama-3.2-Vision-90B, Pixtral-12B, Qwen2-VL
(7B + 72B), InternVL 2.5, MiniCPM-V 2.6
Part B — Audio (3 recipes): Qwen2-Audio, SeamlessM4T v2, Whisper-large-v3
Part C — Reasoning (7 recipes): completes the 6 DeepSeek-R1-Distill sizes,
plus Qwen3-Coder, Qwen3-30B-A3B reasoning, Phi-4 reasoning
Part D — Edge (8 recipes): SmolLM2 (135M / 360M / 1.7B), Qwen2.5
(0.5B / 1.5B / 3B), Gemma 2 2B, Phi-3.5-mini
Part E — Domain (8 recipes): BioMistral, Meditron, CodeLlama (13B / 70B),
Magicoder, Mathstral, Nemotron-4 340B, Llama-2-13b-finance
Part F — Multimodal reasoning (2 recipes): Llama-3.2-Vision GRPO, Pixtral DPO
Part G — Recipe-validation CI workflow on every PR touching recipe / config /
data code (.github/workflows/recipe-validation.yml)
Part H — 750 parametrized tests covering catalog-wide invariants:
model-id safety (no `..`/`://`/null bytes), lora.target_modules non-empty,
max_length within schema bounds, GRPO recipes wire reward_fn +
num_generations >= 2, vision recipes set image_dir, audio recipes set
audio_dir, default data path is non-empty + relative
Live 100-step per-recipe smoke train (requires GPU runner) deferred to v0.31.1.
Tests: 2886 → 3607 (+721). Catalog: 46 → 80 (target met).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two tests in tests/test_bugfixes.py::TestGRPOCPUMinNewTokens fail on
windows-latest / Python 3.11 when importing trl.trainer.grpo_trainer:
RuntimeError: Failed to import trl.trainer.grpo_trainer because of
the following error:
'charmap' codec can't decode byte 0x90 in position 6555: character
maps to <undefined>
Root cause: upstream trl reads an auxiliary file without an explicit
encoding, so Python uses the system default. On Windows that is cp1252
('charmap'), which chokes on non-ASCII bytes present in the file. This
is an upstream issue but Soup needs a green CI.
Two-layer fix:
1. .github/workflows/ci.yml — set PYTHONUTF8=1 and PYTHONIOENCODING=utf-8
as job-level env. Python's UTF-8 mode makes all file I/O default to
UTF-8 regardless of locale, which is the correct global fix for this
class of bug.
2. tests/test_bugfixes.py — add a _trl_grpo_importable() helper that
returns False on UnicodeDecodeError / ImportError / RuntimeError, and
use it as a belt-and-braces skip in both TestGRPOCPUMinNewTokens
tests. Ensures the tests skip cleanly instead of erroring out if a
future CI change accidentally drops PYTHONUTF8.
Local verification: both tests pass with 'pytest tests/test_bugfixes.py::
TestGRPOCPUMinNewTokens -v' (Python 3.10, Windows).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add Dockerfile with CUDA 12.1 and Python 3.11 for Soup
* feat: add docker-compose.yml with GPU passthrough and volume mounts
* chore: add .dockerignore to exclude caching and local data from image
* ci: add GitHub action to build and publish Docker image to GHCR
* docs: add Docker installation and usage instructions to README
pytest junitxml wraps results in <testsuites><testsuite tests="N">,
the count is on the child element, not the root.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CI now parses pytest junitxml output and updates a public Gist with the
exact test count. Shields.io reads the Gist as an endpoint badge.
Requires GIST_TOKEN secret (PAT with gist scope).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Triggers on `git tag v0.2.0 && git push --tags`.
Uses PyPI trusted publisher (OIDC) — no token needed in secrets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Typer CLI: soup init, soup train, soup data inspect/validate
- Pydantic config schema with YAML loader and validation
- Data pipeline: JSONL/JSON/CSV/Parquet + HuggingFace datasets
- Format detection: Alpaca, ShareGPT, ChatML (auto-detect)
- SFT trainer wrapper over transformers + peft + trl
- QLoRA/LoRA support with auto batch size estimation
- GPU detection (CUDA/MPS/CPU) and memory calculation
- Rich live terminal dashboard for training monitoring
- Config templates: chat, code, medical
- Tests (pytest) + GitHub Actions CI
- MIT license
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>