What's New
v0.52.0 — Modality II lands TTS fine-tuning, classifier / reranker / cross-encoder tasks, knowledge distillation, BitNet 1.58-bit, Energy-Based FT, Generalized DPO, per-expert MoE quantization, and gpt-oss reasoning_effort schema. Schema-only this release; live trainer / loss / export wiring deferred to v0.52.1 (same stub-then-live pattern as v0.50.0 GRPO Plus + v0.51.0 hubs).
- TTS fine-tuning. New
task='tts'+modality='audio_out'with a closed allowlist of five model families (Orpheus, Sesame-CSM, Llasa, Spark, Oute). Orpheus + Oute support emotion conditioning via per-family allowlists (Orpheus 8 emotions, Oute 6). Five ready-made recipes:orpheus-tts-sft,sesame-csm-tts,llasa-tts,spark-tts,oute-tts. - Classifier / reranker / cross-encoder. New
taskvaluesclassifier,reranker,cross_encoderwithnum_labels(bounded [1, 1024] with bool-before-int guard),classifier_kind(single_label / multi_label),label_names(dedup + 1024-cap + null-byte rejection). - Knowledge distillation. New
task='distill'+teacher_model+distill_divergence(kl→ canonicalises toforward_kl;reverse_kl/jsalso accepted) +distill_temperature(bounded [0.05, 100.0], math.isfinite). - BitNet 1.58-bit. New
quantization='bitnet_1.58'(gated to non-MLX, text-modality, task ∈ {sft, pretrain, dpo}). New CLI:soup export --format bitnet/--format tq1_0accepts the flag and prints a yellow deferred-advisory panel; live conversion in v0.52.1. Newfalcon-e-bitnet-sftrecipe. - EBFT + GDPO. Energy-Based FT variants (
structured/strided+ boundedebft_temperature) gated to SFT. Generalized DPO variants (standard/length_normalized/margin) gated to DPO-family tasks. - MoE expert quant + router-only training.
moe_expert_quant: nf4 | int8_rowwiseandtrain_router_only: true— both requiremoe_lora=true(silent-no-op rejection at config-load). - gpt-oss
reasoning_effort(low | medium | high) +train_on_eot: bool. Both gated to the SFT-family task set; rejected on DPO / GRPO / PPO / etc. with named offenders. - +272 net new tests (7184 → 7456). 4 review agents (python, security, code, tdd) ran sequentially; every finding fixed.
Install/Upgrade
pip install --upgrade soup-cliRelease notes: https://github.com/MakazhanAlpamys/Soup/releases/tag/v0.52.0
PyPI: https://pypi.org/project/soup-cli/0.52.0/
Security
Every new validator follows the established hardening policy: closed frozenset allowlists wrapped in MappingProxyType so registries cannot be mutated at runtime; validate_* helpers reject non-string / bool / empty / null-byte / oversize / unknown inputs with case-insensitive normalisation; float validators (validate_distill_temperature, validate_ebft_temperature) gate on math.isfinite to reject NaN AND ±inf; field_validator(mode='before') on num_labels rejects bool before Pydantic's ge=1 coercion silently treats True as 1; _validate_classifier_compat uses a lazy-import early-return guard so the SFT hot path doesn't pay import cost. New CLI stubs (soup export --format bitnet/tq1_0) accept the flag and exit 0 with a deferred-advisory panel — no artifact written, no filesystem touch.
Known Limitations
- Every live trainer / loss / export path is deferred to v0.52.1 —
build_tts_trainer,build_classifier_trainer,build_distill_trainer,build_bitnet_trainer,export_bitnet_gguf,apply_ebft_loss,apply_gdpo_loss,apply_moe_expert_quantraiseNotImplementedErrorwith explicit v0.52.1 markers. modality='audio_out'is accepted on non-TTS tasks by design (so future ASR / V2A tasks can reuse it); v0.52.1 trainer dispatch must checktask == 'tts'to avoid silent routing.- Oute emotion allowlist is a tight 6-entry subset (neutral / happy / sad / angry / calm / excited) matching Oute's documented prosody set.
is_bitnet_modelis best-effort heuristic over name prefixes (bitnet,falcon-e,1bitllm,onebit). Detection, not gating.quantization='bitnet_1.58'gated to task ∈ {sft, pretrain, dpo} — extending to GRPO / PPO / RewardModel requires upstream onebitllms RL kernels.- TTS recipes use aspirational HF repo IDs that may surface as HF 404 until upstream publishes the corresponding repos (same policy as v0.51.0).