What's New
Native Spectrum targeted training (closes #266). Fine-tune only the layers that matter — and find them on a CPU box.
soup spectrum scan --model <id|path> --top-percent 50 [--modules mlp,attn|all] [-o patch.yaml]streams a model's.safetensorsshards one tensor at a time (no model load — peak RAM is the largest single weight matrix) and computes a singular-value SNR per weight matrix with a Marchenko-Pastur noise threshold (arXiv:2406.06623). It prints a per-group SNR table and a ready-to-pastetraining.unfrozen_parametersYAML block; results cache under~/.soup/spectrum/.- Targeted full fine-tuning — with
training.unfrozen_parametersset,soup trainfreezes every parameter and unfreezes only the matched high-SNR layers (full FT, LoRA off). - The SNR kernel is pure-numpy and transpose-invariant; GPT-2
Conv1Dnaming (c_attn/c_fc/c_proj) is recognised alongside Llama-style names. The existingspectrumtrainer-plugin wrapper is untouched. LISA (per-step layer sampling) is the follow-up in #267.
Live-validated on Windows + RTX 3050: CPU scan of SmolLM2-135M + a real top-25% unfrozen full-FT train (loss 3.455 → 0.719).
Install / Upgrade
pip install -U soup-cli
# scanning a Hub model id needs torch for bf16 weights:
pip install -U 'soup-cli[train]'Security
unfrozen_parameterspatterns are validated at parse time: nested-unbounded-quantifier regexes (ReDoS) are rejected, along with null bytes and empties; count (50k) and length (512) are capped.- Hub downloads route through the SSRF-hardened, namespace-pinned loader; symlinked shards and matrices above a 2^31-element SVD cap are skipped;
--outputstays under cwd. - A real grad-checkpointing backward-pass bug (frozen embeddings) and the ReDoS hole were both caught in review and fixed before release.
Known Limitations
- Very large models need RAM ≈ the largest scanned weight matrix. The per-tensor stream keeps peak RSS to one matrix, but a 70B's biggest mlp/attn weight is still multi-GB; use
--modules mlp,attnto skip the giant embedding/lm_head matrices (which also exceed the 2^31-element SVD cap and are skipped underall). - bf16 weights require torch — the pure-numpy framework cannot read bf16; without
soup-cli[train]the scan raises a friendly error naming the install. - Spectrum is full fine-tuning —
unfrozen_parametersrequiresquantization: noneand is text / transformers /task=sftonly; QLoRA users keep LoRA and dropunfrozen_parameters. - A true 70B CPU scan is validated on N=0 (the streaming/cap/cache logic is unit-tested; the live scan was validated on SmolLM2-135M) — same infra class as the multi-GPU items.
Tests: 14184 → 14278 (+94).