From 894cb632dd9039193a23e1c28141e7d073201c4d Mon Sep 17 00:00:00 2001 From: Alpamys Date: Mon, 1 Jun 2026 12:27:08 +0500 Subject: [PATCH] =?UTF-8?q?chore:=20release=20v0.71.0=20=E2=80=94=20split?= =?UTF-8?q?=20heavy=20deps=20into=20[train]=20extra?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Heavy training stack (torch, transformers, peft, trl, datasets, bitsandbytes, accelerate) moves out of the core install into a new [train] optional-dependency extra. `pip install soup-cli` is now a light CLI + data-tools install with no PyTorch; `pip install 'soup-cli[train]'` adds the training stack. - pyproject: new [train] + [all] extras; [dev] self-references [train] so CI (`pip install -e ".[dev]"`) still gets torch. Pins unchanged. - errors.py: missing torch/transformers/peft/trl/datasets/bitsandbytes/ accelerate now surface a single 'install soup-cli[train]' fix. - Dockerfile: install soup-cli[train,serve,data,eval] so the GPU image can still fine-tune. - README + docs/models.md: split install into light core vs [train]. - CHANGELOG: cut [0.71.0]; bump version 0.70.0 -> 0.71.0. --- CHANGELOG.md | 20 ++++++++++++++++++- Dockerfile | 6 ++++-- README.md | 21 ++++++++++++-------- docs/models.md | 5 ++++- pyproject.toml | 25 ++++++++++++++++++------ src/soup_cli/__init__.py | 2 +- src/soup_cli/utils/errors.py | 38 ++++++++++++++++++++++++++++++------ tests/test_errors.py | 18 +++++++++++++++++ 8 files changed, 110 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f30cee6..88b8251 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,11 +12,28 @@ reproducing 70+ versions of notes. ## [Unreleased] +## [0.71.0] - 2026-06-01 + ### Changed +- **Breaking — install split.** The heavy training stack (`torch`, + `transformers`, `peft`, `trl`, `datasets`, `bitsandbytes`, `accelerate`) moved + out of the core install into a new `[train]` extra. `pip install soup-cli` is + now a light CLI + data-tools install with **no PyTorch**; run + `pip install 'soup-cli[train]'` (or `[all]`) to fine-tune. Existing users who + train must reinstall with `[train]`. Version pins are unchanged. +- Trimmed `README.md` to a ~238-line front door; the full feature reference now + lives under `docs/` (one topic page per area, indexed from the README). +- Raised the pytest coverage gate from 50% to 77% (`--cov-fail-under=77`). - Migrated to a `src/` layout (`src/soup_cli/`) for cleaner packaging and to stop tests accidentally importing the in-tree package. ### Added +- `[train]` and `[all]` optional-dependency extras (`[all]` pulls + `train`, `serve`, `ui`, `data`). `[dev]` self-references `[train]` so CI and + contributors still get the full stack from `pip install -e ".[dev]"`. +- Friendly error mapping: a missing heavy dependency (`torch`, `transformers`, + `peft`, `trl`, `datasets`, `bitsandbytes`, `accelerate`) now surfaces + "Training needs the [train] extra. Run: pip install 'soup-cli[train]'". - `py.typed` marker (PEP 561) so downstream type checkers pick up Soup's inline type hints. - `.pre-commit-config.yaml` with ruff (lint + format) and standard file-hygiene @@ -29,4 +46,5 @@ reproducing 70+ versions of notes. `SECURITY.md` (~220 KB). `SECURITY.md` is now a concise security policy; the detailed hardening notes remain in git history and the GitHub Releases notes. -[Unreleased]: https://github.com/MakazhanAlpamys/Soup/compare/v0.70.0...HEAD +[Unreleased]: https://github.com/MakazhanAlpamys/Soup/compare/v0.71.0...HEAD +[0.71.0]: https://github.com/MakazhanAlpamys/Soup/compare/v0.70.0...v0.71.0 diff --git a/Dockerfile b/Dockerfile index 348b273..ca22be1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,8 +23,10 @@ RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 1 # Set working directory WORKDIR /workspace -# Install Soup from PyPI (always the latest published release, not local source) -RUN pip install --no-cache-dir "soup-cli[serve,data,eval]" +# Install Soup from PyPI (always the latest published release, not local source). +# v0.71.0 split the training stack into the [train] extra — include it so the +# GPU image can still fine-tune. +RUN pip install --no-cache-dir "soup-cli[train,serve,data,eval]" # Default entrypoint and command ENTRYPOINT ["soup"] diff --git a/README.md b/README.md index e235e11..10b094b 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Soup turns the pain of LLM fine-tuning into a simple workflow. One config, one command, done. ```bash -pip install soup-cli +pip install 'soup-cli[train]' # add [train] to fine-tune; bare `soup-cli` is the light CLI soup init --template chat soup train ``` @@ -49,10 +49,10 @@ infrastructure instead of improving models. Soup fixes that. ## What's New -**v0.70.0 — Loop Hardening.** Six surfaces that protect the training loop from the failure -modes that cost a real GPU-hour: a reward-hacking detector (InfoRM / RM-ensemble), cross-tokenizer -distillation (ULD), MiniLLM reverse-KL distillation, mid-epoch RL checkpoints, an iterative-DPO -loop driver, and a RAGEN echo-trap detector. See [`docs/training.md`](docs/training.md). +**v0.71.0 — Lighter install.** The heavy training stack (PyTorch, Transformers, PEFT, TRL, +datasets, bitsandbytes, accelerate) moved into a `[train]` extra. `pip install soup-cli` is now a +light CLI + data-tools install with no PyTorch; `pip install 'soup-cli[train]'` adds everything you +need to fine-tune. **Breaking:** existing users who train must reinstall with `[train]`. Full history: [CHANGELOG.md](CHANGELOG.md) · [GitHub Releases](https://github.com/MakazhanAlpamys/Soup/releases). @@ -61,10 +61,14 @@ Full history: [CHANGELOG.md](CHANGELOG.md) · [GitHub Releases](https://gi ### 1. Install ```bash -pip install soup-cli # from PyPI +pip install soup-cli # light: CLI + config + data tools (no PyTorch) +pip install 'soup-cli[train]' # add the training stack (torch, transformers, peft, trl, …) pip install git+https://github.com/MakazhanAlpamys/Soup.git # latest dev ``` +`soup init`, `soup data …`, and the other data/inspection commands work on the light install. +Fine-tuning (`soup train`) needs the `[train]` extra. + ### 2. Create a config ```bash @@ -203,8 +207,9 @@ docker compose up # or build locally - 8 GB+ VRAM for 7B models with QLoRA All training tasks run on CPU for testing (quantization auto-disabled). Optional extras -(`fast`, `vision`, `qat`, `serve`, `serve-fast`, `ui`, `eval`, `deepspeed`, `liger`, `mlx`, -`onnx`, `tensorrt`, …) are listed in [`docs/models.md`](docs/models.md#optional-extras). +(`train`, `all`, `fast`, `vision`, `qat`, `serve`, `serve-fast`, `ui`, `eval`, `deepspeed`, +`liger`, `mlx`, `onnx`, `tensorrt`, …) are listed in +[`docs/models.md`](docs/models.md#optional-extras). ## Troubleshooting diff --git a/docs/models.md b/docs/models.md index a23e95a..803db59 100644 --- a/docs/models.md +++ b/docs/models.md @@ -50,10 +50,13 @@ Soup works with **any** of the **340,000+** text-generation models on [HuggingFa ## Optional Extras -The core `pip install soup-cli` is enough to train. Install extras only when you need them: +The core `pip install soup-cli` is a light install — the CLI, config system, and data tools, with +no PyTorch. Add `[train]` to fine-tune, or install other extras only when you need them: | Extra | Install | What it adds | |---|---|---| +| `train` | `pip install 'soup-cli[train]'` | Training stack: torch, transformers, peft, trl, datasets, bitsandbytes, accelerate | +| `all` | `pip install 'soup-cli[all]'` | `train` + `serve` + `ui` + `data` in one shot | | `fast` | `pip install 'soup-cli[fast]'` | Unsloth backend (2-5x faster, lower VRAM) | | `vision` | `pip install 'soup-cli[vision]'` | Vision / multimodal fine-tuning (Pillow) | | `audio` | `pip install 'soup-cli[audio]'` | Audio / speech fine-tuning (librosa, soundfile) | diff --git a/pyproject.toml b/pyproject.toml index 316b545..4f4106e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "soup-cli" -version = "0.70.0" +version = "0.71.0" description = "Fine-tune LLMs in one command. No SSH, no config hell." readme = "README.md" license = "Apache-2.0" @@ -21,11 +21,23 @@ classifiers = [ "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering :: Artificial Intelligence", ] +# Core install (`pip install soup-cli`) is intentionally light: the CLI, config +# system, and data tools — no PyTorch. v0.71.0 split the heavy training stack +# (torch / transformers / peft / trl / datasets / bitsandbytes / accelerate) +# into the `[train]` extra below. dependencies = [ "typer>=0.9.0,<0.21.0", "rich>=13.0.0", "pydantic>=2.0.0", "pyyaml>=6.0", + "huggingface-hub>=0.16.0", + "plotext>=5.2.0", +] + +[project.optional-dependencies] +# v0.71.0 — heavy training stack. `pip install 'soup-cli[train]'` to fine-tune. +# These were core dependencies through v0.70.0; pins are unchanged. +train = [ "torch>=2.0.0", "transformers>=4.36.0,<5.0.0", "peft>=0.7.0", @@ -33,15 +45,16 @@ dependencies = [ "datasets>=2.14.0", "bitsandbytes>=0.41.0", "accelerate>=0.25.0", - "huggingface-hub>=0.16.0", - "plotext>=5.2.0", ] - -[project.optional-dependencies] +# v0.71.0 — convenience meta-extra pulling the main optional stacks. +all = ["soup-cli[train,serve,ui,data]"] eval = ["lm-eval>=0.4.0"] data = ["datasketch>=1.6.0"] wandb = ["wandb>=0.15.0,<0.18.0"] -dev = ["pytest>=7.0", "ruff>=0.1.0", "pytest-cov>=4.0", "httpx>=0.24.0", "mypy>=1.8.0", "pre-commit>=3.5.0"] +# Self-references `[train]` so CI / contributors get the full training stack +# (CI runs `pip install -e ".[dev]"`; without this every test would fail at +# `import torch`). +dev = ["soup-cli[train]", "pytest>=7.0", "ruff>=0.1.0", "pytest-cov>=4.0", "httpx>=0.24.0", "mypy>=1.8.0", "pre-commit>=3.5.0"] ui = ["fastapi>=0.104.0", "uvicorn>=0.24.0"] serve = ["fastapi>=0.104.0", "uvicorn>=0.24.0"] serve-fast = ["vllm>=0.4.0", "fastapi>=0.104.0", "uvicorn>=0.24.0"] diff --git a/src/soup_cli/__init__.py b/src/soup_cli/__init__.py index 55f682c..191374b 100644 --- a/src/soup_cli/__init__.py +++ b/src/soup_cli/__init__.py @@ -1,3 +1,3 @@ """Soup CLI — Fine-tune LLMs in one command.""" -__version__ = "0.70.0" +__version__ = "0.71.0" diff --git a/src/soup_cli/utils/errors.py b/src/soup_cli/utils/errors.py index 1af38e2..56af71e 100644 --- a/src/soup_cli/utils/errors.py +++ b/src/soup_cli/utils/errors.py @@ -7,6 +7,12 @@ from rich.panel import Panel console = Console(stderr=True) +# v0.71.0 — the heavy training stack (torch / transformers / peft / trl / +# datasets / bitsandbytes / accelerate) moved out of the core install into the +# `[train]` extra. A missing one of these surfaces this single, actionable fix. +# The `\\[` escapes the literal `[` for Rich markup (it renders as `[train]`). +_TRAIN_FIX = "Training needs the \\[train] extra. Run: pip install 'soup-cli\\[train]'" + # Map known error patterns to (short message, fix suggestion) ERROR_MAP = [ # CUDA OOM @@ -62,21 +68,41 @@ ERROR_MAP = [ "httpx is not installed (needed for data generate).", "Run: pip install 'soup-cli\\[generate]'", ), - # Peft / transformers incompatibility + # Heavy training stack — all moved to the [train] extra in v0.71.0. + ( + "No module named 'torch'", + "PyTorch is not installed (needed for training).", + _TRAIN_FIX, + ), + ( + "No module named 'transformers'", + "Transformers is not installed (needed for training).", + _TRAIN_FIX, + ), ( "No module named 'peft'", - "PEFT is not installed.", - "Run: pip install peft>=0.7.0", + "PEFT is not installed (needed for LoRA training).", + _TRAIN_FIX, ), ( "No module named 'trl'", - "TRL is not installed.", - "Run: pip install trl>=0.7.0", + "TRL is not installed (needed for training).", + _TRAIN_FIX, + ), + ( + "No module named 'datasets'", + "Datasets is not installed (needed for training).", + _TRAIN_FIX, ), ( "No module named 'bitsandbytes'", "BitsAndBytes is not installed (needed for quantization).", - "Run: pip install bitsandbytes>=0.41.0", + _TRAIN_FIX, + ), + ( + "No module named 'accelerate'", + "Accelerate is not installed (needed for training).", + _TRAIN_FIX, ), # CPU / quantization issues ( diff --git a/tests/test_errors.py b/tests/test_errors.py index 9d95239..73d6686 100644 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -3,6 +3,7 @@ from io import StringIO from unittest.mock import patch +import pytest from rich.console import Console from typer.testing import CliRunner @@ -72,6 +73,23 @@ def test_missing_deepspeed_error(): assert "soup-cli[deepspeed]" in output +@pytest.mark.parametrize( + "module", + ["torch", "transformers", "peft", "trl", "datasets", "bitsandbytes", "accelerate"], +) +def test_missing_train_dep_points_at_train_extra(module): + """v0.71.0 — any missing heavy training dep points at the [train] extra.""" + buf = StringIO() + test_console = Console(file=buf, stderr=False) + with patch("soup_cli.utils.errors.console", test_console): + exc = ModuleNotFoundError(f"No module named '{module}'") + format_friendly_error(exc, verbose=False) + output = buf.getvalue() + # The `\[train]` escape renders to a literal `[train]` in the output. + assert "soup-cli[train]" in output + assert "[train] extra" in output + + def test_connection_error(): """Connection error gets friendly message.""" buf = StringIO()