Multi-Trainer Speed & Memory (v0.35.0)

v0.35 finishes the v0.28 → v0.33 → v0.35 expansion: the four big speed-and-memory features now wire into every transformer-backend trainer.

What's now multi-trainer

Featurev0.28v0.33v0.35
use_cut_ceSFTSFT, DPO, Pretrain13 tasks
quantization_aware: "fp8"SFTSFT, DPO, Pretrain13 tasks
kernel_auto_composeSFTSFT, DPO, Pretrain13 tasks accepted; the SFT trainer never reads it
activation_offloadingSFTSFT, DPO, Pretrain13 tasks

"13 tasks" = SFT, DPO, Pretrain, GRPO, PPO, KTO, ORPO, SimPO, IPO, BCO, the unified preference dispatcher, Reward-Model and Embedding. That is the allowlist in utils/v028_features.py, and it is narrower than "every trainer": ten of the 23 tasks are still refused at config load rather than silently ignored — prm, tts, classifier, reranker, cross_encoder, distill, unlearn, moe_lora_routing, online_dpo and asr. So use_cut_ce: true with task: distill or task: asr raises, even though both are transformers-backend text tasks. The MLX backend and an unknown task each emit their own message so you get the right fix.

Wired is not the same as engaged. use_cut_ce takes effect only when the third-party cut-cross-entropy package imports and has a patcher for the architecture; otherwise the run continues without it and says so in a yellow line, see Cut Cross-Entropy.

fp8 / int8 QAT guard

Six trainer wrappers (GRPO / KTO / ORPO / SimPO / IPO / PPO) had if tcfg.quantization_aware: which would route the string "fp8" into the legacy int8 prepare_model_for_qat path. Each guard is now quantization_aware != "fp8" (matches the DPO / Pretrain pattern).

Activation offloading hooks installed everywhere

The shared helper in utils/v028_features.py now enforces is_under_cwd containment for activation_offloading="disk" and reduces the offending path to os.path.basename in the ValueError message so absolute $HOME paths don't leak. All thirteen supported trainer wrappers wrap trainer.train() with this context manager — closes a v0.33 oversight where DPO / Pretrain accepted the flag but never installed offload hooks.

Kernel benchmarking forward-only

benchmark_kernel_combos runs forward-only under torch.no_grad() — corruption hazard from gradient accumulation onto the live training model is eliminated. Caller-supplied bounds are clamped (bs ≤ 32, sl ≤ 512, steps ≤ 50, vocab ≤ 200_000) so a misconfigured caller cannot OOM the CI runner. Returns a NEW list — input candidates are never mutated.

Quant menu kwarg allowlist

vLLM quantization kwarg is now an explicit named parameter on create_vllm_engine (not a **kwargs splat) and is validated against the closed allowlist {awq, gptq, fp8}. The earlier kwarg-splat path could have leaked arbitrary AsyncEngineArgs fields to the engine constructor — eliminated by the named-param refactor.

Error redaction on model load fallback

When every candidate fails to load, the RuntimeError message includes only type(last_error).__name__ + ": " + str(last_error) instead of repr(last_error) — repr of a FileNotFoundError would embed $HOME-prefixed checkpoint paths.

See also

Soup is free and Apache-2.0. If it saved you a training run, starring the repo costs nothing and helps most. You can also fund the GPU time behind the work a 4 GB laptop cannot reach.