soup-cli 0.53.0__tar.gz → 0.53.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {soup_cli-0.53.0 → soup_cli-0.53.2}/CONTRIBUTING.md +6 -2
- {soup_cli-0.53.0 → soup_cli-0.53.2}/PKG-INFO +133 -9
- {soup_cli-0.53.0 → soup_cli-0.53.2}/README.md +132 -8
- {soup_cli-0.53.0 → soup_cli-0.53.2}/SECURITY.md +8 -4
- {soup_cli-0.53.0 → soup_cli-0.53.2}/pyproject.toml +1 -1
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/__init__.py +1 -1
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/autopilot/__init__.py +4 -0
- soup_cli-0.53.2/soup_cli/autopilot/decisions.py +391 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/autopilot/generate_config.py +10 -1
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/deploy.py +139 -6
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/export.py +238 -1
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/merge.py +70 -8
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/train.py +24 -1
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/loss_mask.py +68 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/sft_format.py +53 -8
- soup_cli-0.53.2/soup_cli/trainer/classifier.py +368 -0
- soup_cli-0.53.2/soup_cli/trainer/distill.py +428 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/dpo.py +4 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/sft.py +5 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/classifier.py +11 -7
- soup_cli-0.53.2/soup_cli/utils/deploy_measure.py +362 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/distill.py +11 -7
- soup_cli-0.53.2/soup_cli/utils/ebft_gdpo.py +472 -0
- soup_cli-0.53.2/soup_cli/utils/gguf_quant.py +643 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/paths.py +33 -0
- soup_cli-0.53.2/soup_cli/utils/reasoning_effort.py +97 -0
- soup_cli-0.53.2/soup_cli/utils/save_formats.py +420 -0
- soup_cli-0.53.2/tests/qa/v053_qa.md +193 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_awq_gptq_export.py +8 -4
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_onnx_tensorrt_export.py +4 -2
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0520.py +23 -12
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0530.py +18 -9
- soup_cli-0.53.2/tests/test_v0531_109.py +526 -0
- soup_cli-0.53.2/tests/test_v0531_139.py +365 -0
- soup_cli-0.53.2/tests/test_v0531_142.py +540 -0
- soup_cli-0.53.2/tests/test_v0531_82.py +296 -0
- soup_cli-0.53.2/tests/test_v0532.py +1664 -0
- soup_cli-0.53.0/soup_cli/autopilot/decisions.py +0 -185
- soup_cli-0.53.0/soup_cli/utils/ebft_gdpo.py +0 -191
- soup_cli-0.53.0/soup_cli/utils/gguf_quant.py +0 -292
- soup_cli-0.53.0/soup_cli/utils/reasoning_effort.py +0 -37
- soup_cli-0.53.0/soup_cli/utils/save_formats.py +0 -208
- {soup_cli-0.53.0 → soup_cli-0.53.2}/.dockerignore +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/.github/FUNDING.yml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/.github/pull_request_template.md +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/.github/workflows/ci.yml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/.github/workflows/docker.yml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/.github/workflows/publish.yml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/.github/workflows/recipe-validation.yml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/.gitignore +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/CODEOWNERS +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/CODE_OF_CONDUCT.md +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/Dockerfile +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/LICENSE +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/NOTICE +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/docker-compose.yml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/README.md +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/configs/dpo_chat.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/configs/dpo_example.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/configs/grpo_reasoning.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/configs/rlhf_step1_sft.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/configs/rlhf_step2_reward.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/configs/rlhf_step3_ppo.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/configs/sft_basic.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/configs/vision_llama.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/data/alpaca_tiny.jsonl +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/data/chat_preferences.jsonl +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/data/dpo_sample.jsonl +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/examples/data/reasoning_math.jsonl +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup.png +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/__main__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/autopilot/analyzer.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/cans/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/cans/pack.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/cans/publish.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/cans/run.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/cans/schema.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/cans/unpack.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/cans/verify.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/cli.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/adapters.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/agent.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/autopilot.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/bench.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/can.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/chat.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/cost.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/data.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/data_forge.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/data_mix.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/data_score.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/delinearize_llama4.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/diff.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/doctor.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/eval.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/fetch.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/generate.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/history.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/infer.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/init.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/llama.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/merge_sharded_fsdp_weights.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/migrate.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/monitor.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/plugins.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/profile.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/push.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/quantize.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/quickstart.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/recipes.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/registry.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/runs.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/serve.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/sweep.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/tui.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/ui.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/commands/why.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/config/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/config/loader.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/config/schema.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/augment.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/chat_templates.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/collators.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/formats.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/loader.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/providers/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/providers/_utils.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/providers/anthropic.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/providers/ollama.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/providers/vllm.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/templates/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/templates/code.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/templates/conversation.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/templates/preference.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/templates/qa.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/templates/reasoning.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/templates/tool_calling.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/templates/verifiable.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/traces/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/traces/pair_builder.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/traces/parsers.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/traces/quality.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/data/validator.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/eval/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/eval/arena.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/eval/benchmarks_v0_43.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/eval/calibrate.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/eval/checkpoint_intelligence.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/eval/custom.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/eval/forgetting.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/eval/gate.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/eval/human.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/eval/judge.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/eval/leaderboard.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/eval/quant_check.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/experiment/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/experiment/tracker.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/migrate/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/migrate/axolotl.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/migrate/common.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/migrate/llamafactory.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/migrate/unsloth.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/monitoring/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/monitoring/callback.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/monitoring/display.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/monitoring/hf_push.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/monitoring/trace_logger.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/plugins/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/recipes/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/recipes/catalog.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/registry/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/registry/attach.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/registry/diff.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/registry/hashing.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/registry/store.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/audio.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/bco.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/chat.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/code.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/embedding.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/fetch_examples/llama-3.1-8b-lora.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/fetch_examples/qwen2.5-7b-dpo.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/fetch_examples/zero3-cpu-offload.json +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/ipo.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/kto.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/longcontext.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/manifest.json +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/medical.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/moe.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/orpo.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/pretrain.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/reasoning.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/rlhf.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/simpo.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/tool-calling.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/templates/vision.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/bco.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/embedding.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/grpo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/ipo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/kto.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/mlx_dpo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/mlx_grpo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/mlx_routing.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/mlx_sft.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/orpo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/ppo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/preference.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/pretrain.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/reward_model.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/rewards.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/trainer/simpo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/tui_app.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/ui/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/ui/app.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/ui/plugins/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/ui/static/app.js +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/ui/static/index.html +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/ui/static/logo.png +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/ui/static/logo.svg +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/ui/static/style.css +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/activation_offload.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/advanced_precision.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/agent_forge.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/agent_rollout.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/anthropic_messages.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/auto_quant.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/batch_probe.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/bitnet.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/block_expansion.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/checkpoint_trigger.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/constants.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/convergence.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/crash.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/cross_doc_attn.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/curriculum.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/curriculum_dynamic.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/cut_ce.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/data_forge.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/data_mix.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/data_pipeline.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/data_score.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/deepspeed.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/delinearize_llama4.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/demo_bundles.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/deploy_autopilot.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/dpo_variants.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/encoding.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/errors.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/fetch_examples.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/flash_attn.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/fp8.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/freeze.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/fsdp.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/fsdp_consolidate.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/galore.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/gpu.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/gpu_monitor.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/graceful_save.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/grad_accum.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/gradient_ckpt.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/grpo_long_context.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/grpo_variants.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/hf.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/hf_space.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/hubs.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/integrations.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/jinja_analyzer.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/kernel_picker.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/kv_cache.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/launcher.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/liger.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/llama_proxy.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/llama_server_timings.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/loftq_init.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/log_level.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/long_context.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/longlora.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/lr_finder.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/lr_groups.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/metrics.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/mii.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/mixed_precision.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/mlx.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/moe.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/moe_quant.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/multipack.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/multipack_sampler.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/multipack_trainer.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/neat_packing.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/ngram_spec.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/nlg_metrics.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/ollama.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/onboarding.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/optimizer_zoo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/peft_builder.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/peft_patches.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/peft_wiring.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/pipeline.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/preference_combine.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/prm.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/profiler.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/profiling.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/profiling_v0_43.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/qat.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/qr_url.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/quality.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/quant_menu.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/reasoning_parser.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/recipe_dag.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/registry.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/relora.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/replay.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/ring_attention.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/run_cost.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/server_tools.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/sglang.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/shortcuts.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/spec_pairing.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/spike_recovery.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/sse_train_stream.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/structured_output.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/sweep_config.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/tail_latency.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/tool_outputs.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/topology.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/tracing.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/trackers.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/trainer_plugins.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/trust_remote.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/tts.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/ui_env.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/unsloth.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/v028_features.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/vllm.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/vscode_setup.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/warmup.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_cli/utils/why.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/soup_logo_svg.svg +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/templates/chat.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/templates/code.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/templates/medical.yaml +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/__init__.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/conftest.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_adapters.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_advanced_peft.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_assistant_mask.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_audio.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_auto_tuning.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_autopilot.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_batch_probe.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_bco.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_bench.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_bugfixes.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_callback.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_cans.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_chat.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_chat_template.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_cli.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_cli_subprocess.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_config.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_cost.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_crash_reporter.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_curriculum.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_data.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_data_augment.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_data_sample.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_data_split.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_data_tools.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_dataset_hub.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_dataset_registry.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_deepspeed.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_deploy_ollama.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_diff.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_display.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_doctor.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_dpo_example.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_dpo_variants.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_embedding.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_errors.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_eval.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_eval_gate.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_eval_platform.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_export.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_formats.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_fp8_recipe.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_freeze_training.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_generate.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_gpu.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_grpo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_hf_integration.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_infer.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_inference_advanced.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_init.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_ipo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_jinja_analyzer.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_kto.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_loader.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_log_level.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_loss_watchdog.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_merge.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_migrate.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_mlx_backend.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_moe.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_multi_adapter.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_multi_gpu.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_multipack_config.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_multipack_invariants.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_multipack_sampler.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_neat_packing.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_neftune_rslora.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_orpo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_packing.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_part_a_wave1.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_part_a_wave2.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_part_b.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_part_c.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_part_d.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_part_e.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_part_f_hardening.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_peft_methods.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_peft_patches.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_performance.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_pissa_init.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_ppo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_preference_dispatcher.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_preference_multi.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_preference_multi_runtime.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_pretrain.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_profile.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_profiling.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_progress.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_push.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_qat.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_quality_filter.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_quant_check.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_quant_menu.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_quickstart.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_rank_pattern.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_recipes.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_recipes_v031.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_registry.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_relora.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_replay.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_resume.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_rlvr.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_run_cost.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_runs.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_serve.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_server_generate.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_sglang_serve.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_simpo.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_smoke_train.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_speculative_decoding.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_sweep.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_synth_data_pro.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_templates_yaml.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_tensorboard.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_tool_calling.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_trace_to_pref.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_tracker.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_trainer_coverage_v035.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_trainer_init.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_training_intelligence.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_training_speed.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_trust_remote_code.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_tui.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_ui.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_ui_chat.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_ui_config_builder.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_ui_live_monitor.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_ui_metrics.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_unsloth.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0401_part_c.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0401_part_d.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0401_part_e.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0402_part_a.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0402_part_b.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0403_part_a.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0403_part_b.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0403_part_c.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0404_part_a.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0404_part_b.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0405_part_a.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0406_part_a.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0410_part_a.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0410_part_b.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0410_part_c.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0420.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0430_part_a.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0430_part_b.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0430_part_c.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0430_part_d.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0440_part_a.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0440_part_b.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0440_part_c.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0440_part_d.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0440_review_followups.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0450.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0460_part_a.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0460_part_b.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0470_part_a.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0470_part_b.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0480_part_a.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0480_part_b.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0490.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0500_part_a.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0500_part_b.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0500_part_c.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0500_part_d.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0500_part_e.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_v0510.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_validator.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_vision.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_vllm_serve.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_why.py +0 -0
- {soup_cli-0.53.0 → soup_cli-0.53.2}/tests/test_windows_encoding.py +0 -0
|
@@ -107,11 +107,11 @@ soup_cli/
|
|
|
107
107
|
cans/ - Shareable .can artifact format + run/publish orchestrator (v0.26.0 + v0.33.0)
|
|
108
108
|
data/traces/ - Trace-to-Preference harvester (v0.26.0)
|
|
109
109
|
data/collators.py - CrossDocCollator for sample packing (v0.33.0)
|
|
110
|
-
utils/ - GPU, errors, MoE, GaLore, QAT, Unsloth, vLLM, SGLang, Liger, FlashAttn, FSDP, Ring Attention, long-context, quality, curriculum, freeze, dataset-registry, mlx, peft_builder, paths, topology, launcher, mii, pipeline, cut_ce, fp8, gradient_ckpt, kernel_picker, cross_doc_attn, activation_offload, hf, spec_pairing, structured_output, metrics, tracing, auto_quant, lr_finder, grad_accum, mixed_precision, warmup, spike_recovery, convergence, v028_features, multipack_sampler, multipack, neat_packing, jinja_analyzer, quant_menu, relora, peft_patches, peft_wiring, dpo_variants, optimizer_zoo, lr_groups, loftq_init, block_expansion, tts, classifier, distill, bitnet, ebft_gdpo, moe_quant, reasoning_effort, gguf_quant, kv_cache, advanced_precision, save_formats
|
|
110
|
+
utils/ - GPU, errors, MoE, GaLore, QAT, Unsloth, vLLM, SGLang, Liger, FlashAttn, FSDP, Ring Attention, long-context, quality, curriculum, freeze, dataset-registry, mlx, peft_builder, paths, topology, launcher, mii, pipeline, cut_ce, fp8, gradient_ckpt, kernel_picker, cross_doc_attn, activation_offload, hf, spec_pairing, structured_output, metrics, tracing, auto_quant, lr_finder, grad_accum, mixed_precision, warmup, spike_recovery, convergence, v028_features, multipack_sampler, multipack, neat_packing, jinja_analyzer, quant_menu, relora, peft_patches, peft_wiring, dpo_variants, optimizer_zoo, lr_groups, loftq_init, block_expansion, tts, classifier, distill, bitnet, ebft_gdpo, moe_quant, reasoning_effort, gguf_quant, kv_cache, advanced_precision, save_formats, deploy_measure
|
|
111
111
|
templates/ - 17 built-in soup.yaml templates (YAML + manifest.json) with load_template loader (v0.39.0, +bco v0.40.0)
|
|
112
112
|
ui/ - Web UI (FastAPI + HTML/JS SPA)
|
|
113
113
|
|
|
114
|
-
tests/ - Test suite (
|
|
114
|
+
tests/ - Test suite (185 files, 7842 tests)
|
|
115
115
|
examples/ - Real-world config examples and datasets
|
|
116
116
|
```
|
|
117
117
|
|
|
@@ -263,6 +263,10 @@ pytest tests/ --cov=soup_cli --cov-report=html
|
|
|
263
263
|
| test_v0500_part_d.py | v0.50.0 Part D — 7 stability/efficiency knobs (`ref_model_ema_alpha` / `replay_buffer_size` / `async_grpo_prefetch` / `tis_threshold` / `mask_truncated_completions` / `defer_rerolling` / `skip_zero_advantage` / `off_policy_mask_threshold`); explicit bool-rejection field_validator across all numeric fields (tdd-guide HIGH fix); `mask_truncated_completions` requires `tis_threshold` cross-validator; SoupConfig task-gate naming every offending field; `grpo_fp16` task-gate (code-review HIGH fix) (v0.50.0 Part D) |
|
|
264
264
|
| test_v0500_part_e.py | v0.50.0 Part E — `task='prm'` (Process Reward Model) + `vision_grpo` flag; `validate_prm_compat` (data.format / modality / mlx gates); `validate_vision_grpo_compat` (task ∈ {grpo, ppo} / modality='vision' / non-mlx); `build_prm_trainer` deferred stub; SoupConfig integration with all rejection paths exercised (v0.50.0 Part E) |
|
|
265
265
|
| test_v0520.py | v0.52.0 Modality II — TTS / classifier / distill / BitNet / EBFT-GDPO / MoE quant / reasoning_effort: TTS family allowlist + per-family emotion allowlists (Orpheus + Oute) + validate_tts_compat; classifier / reranker / cross_encoder tasks + num_labels (with field_validator bool guard) + label_names dedup + classifier-only field gates; distill divergence (kl alias canonicalised, Literal excludes alias) + teacher_model + distill_temperature bounds; BitNet 1.58 quant + bitnet/tq1_0 export-format stubs + Falcon-E recipe + is_bitnet_model org-prefix detect; EBFT (structured/strided) + GDPO (standard/length_normalized/margin) variant allowlists + task gates; MoE expert quant (nf4/int8_rowwise) + train_router_only requiring moe_lora=true; reasoning_effort + train_on_eot with SFT-family task gate; 6 new recipes (5 TTS + Falcon-E BitNet); review-fix coverage (num_labels bool guard, Oute emotion allowlist, lazy-import in classifier validator, task gates, oversize / NaN / Inf matrices). Test count: 272 (v0.52.0) |
|
|
266
|
+
| test_v0531_82.py | v0.53.1 #82 autopilot pre-quantized detection: `detect_prequantized_format` + `decide_quantization(prequantized=...)` + `detect_prequantized_format_from_path` with cwd-containment + config.json symlink rejection + name/config aliases + word-boundary regex (v0.53.1) |
|
|
267
|
+
| test_v0531_142.py | v0.53.1 #142 merge_4bit + export_torchao live wiring: BNB-4bit single-stage merge + TorchAO PTQ with per-scheme kwarg allowlist + CLI `--save-format` + `--quant-config` + `load_quant_config` (yaml.safe_load + 256 KB cap + extension allowlist) + path TOCTOU (v0.53.1) |
|
|
268
|
+
| test_v0531_139.py | v0.53.1 #139 export_advanced_gguf live: 3-stage llama.cpp pipeline (convert → imatrix → quantize) + UD-prefix strip + subprocess argv shape + `_prepare_calibration_text` JSONL alias fallback + null-byte strip + 50 MB cap + POSIX O_NOFOLLOW + `_safe_stderr` Rich escape (v0.53.1) |
|
|
269
|
+
| test_v0531_109.py | v0.53.1 #109 deploy autopilot --measure: `compute_cache_key` + `sha_of_file` + `measure_candidate` OK/MINOR/MAJOR bands + `pick_best` soft-fallback (max-by-delta) + cache round-trip with symlink rejection on load AND save + CLI integration + `_MAX_CANDIDATES=32` cap + `render_measure_table` markup escape regression (v0.53.1) |
|
|
266
270
|
| test_v0530.py | v0.53.0 Quant Menu II — UD GGUFs + KV cache + NVFP4 + LF parity + save formats: Parts A+B GGUF (UD ladder 14 entries + IQ 12 + Apple/ARM 10 frozensets + non-overlap invariant + `validate_*` case-insensitive + rejection matrix + `is_advanced_gguf_format` union + `_LOWER_INDEX` O(1) lookup + MappingProxyType immutability + `validate_calibration_data_path` shape rejection + 4096-boundary + `export_advanced_gguf` v0.53.1 deferred stub); Part C KV cache (`KV_CACHE_TYPES` frozenset + `validate_kv_cache_type` case + bool/null/oversize/non-string rejection + `requires_hopper` delegates to spec + `get_kv_cache_spec` frozen + schema fp8-on-mlx rejected with specific message + q8_0-on-mlx allowed); Part D advanced precision (`fp8_attention` requires `quantization_aware='fp8'` BEFORE mlx-gate ordering + bool guards on every string param + schema rejects-without-fp8-qat; `nvfp4` mlx + vision rejection + bool guards; `unsloth_bnb_4bit` backend='unsloth' + quantization='4bit' rejection matrix; `apply_*` deferred); Part E LF parity (`bnb_4bit_use_double_quant` rejects none/8bit/gptq parametrize; `llm_int8` rejects default-none + 4bit; `quantize_ref_model` happy on dpo/grpo/kto + rejects sft/pretrain; `quantize_reward_model` happy on ppo/reward_model + rejects dpo; explicit `TypeError("v0.53.0 flag must be bool")` from `_validate_v053_bool_fields`; explicit-null surfaces as `valid boolean` ValidationError); Part F save formats (`MERGE_SAVE_FORMATS` lowercase normalisation + rejection matrix; `TORCHAO_PTQ_SCHEMES` CASE-SENSITIVE — `int4weightonly` rejected; `validate_quant_config_path` 4096-boundary; `MergeSaveSpec` + `TorchAOPTQSpec` frozen + MappingProxyType immutability; `merge_4bit` + `export_torchao` deferred); Cross-cutting (full 5-field YAML round-trip + cardinality invariant + tautological-assert replaced with allowlist + idempotent re-validate + `get_gguf_spec` unknown raises + bool guards on backend/modality/quantization across every Part D validator). Test count: 154 (v0.53.0) |
|
|
267
271
|
| test_v0510.py | v0.51.0 Model Catalog Expansion + Alternative Model Hubs: Part E hubs.py (`SUPPORTED_HUBS` + `validate_hub_name` + `validate_hub_endpoint` SSRF parity / CRLF rejection / IPv6 mapped private rejected / IPv6 loopback ok / control chars; `resolve_endpoint` env-var override; `default_endpoint` + `endpoint_env_var` + `required_hub_package` + `is_hf` with bool guards; MappingProxyType immutability); TrainingConfig `hub` field (default + Literal accept + None reject + case-insensitive normalisation + YAML round-trip) + SoupConfig `_validate_hub_supported` (mlx + non-hf rejected; mlx + hf accepted; modelers + transformers accepted); Part D MULTIPACK_ARCHITECTURES extension (20 new arches parametrize + legacy preserved + exact count=38 + frozenset immutability); Parts A/B/C 26 new recipes (parametrize over every name × {get_recipe / RecipeMeta / SoupConfig load / yaml.safe_load / model id no null/whitespace/empty parts / max_length bounds / GRPO required fields}); baichuan-sft uses `hub: modelscope`; total recipe count >= 105 (v0.51.0) |
|
|
268
272
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: soup-cli
|
|
3
|
-
Version: 0.53.
|
|
3
|
+
Version: 0.53.2
|
|
4
4
|
Summary: Fine-tune LLMs in one command. No SSH, no config hell.
|
|
5
5
|
Project-URL: Homepage, https://github.com/MakazhanAlpamys/Soup
|
|
6
6
|
Project-URL: Repository, https://github.com/MakazhanAlpamys/Soup
|
|
@@ -134,15 +134,14 @@ soup train
|
|
|
134
134
|
|
|
135
135
|
Latest highlights only. Full history: [GitHub Releases](https://github.com/MakazhanAlpamys/Soup/releases).
|
|
136
136
|
|
|
137
|
-
**v0.53.
|
|
137
|
+
**v0.53.2 — Modality II live trainers**: Four v0.52.0 deferred stubs lifted into real, end-to-end-trainable wrappers — knowledge distillation, sequence classification, EBFT / GDPO loss kernels, and gpt-oss-style `reasoning_effort` system-prompt injection.
|
|
138
138
|
|
|
139
|
-
-
|
|
140
|
-
-
|
|
141
|
-
- **
|
|
142
|
-
- **
|
|
143
|
-
- **
|
|
144
|
-
- **
|
|
145
|
-
- **+157 net new tests** (7453 → 7610) across 154 tests in `test_v0530.py`. Five review agents (python / code / security / tdd / verification) ran in parallel; every CRITICAL / HIGH / MEDIUM / LOW finding fixed or documented: O(1) `_LOWER_INDEX` for GGUF lookup, ref-task set extended with GRPO + KTO, `_validate_v053_bool_fields` no longer silently coerces `None`, `requires_hopper` reads from spec metadata, `fp8_attention` validator order swapped so the `quantization_aware='fp8'` error fires first, `validate_calibration_data_path` / `validate_quant_config_path` docstrings name the exact controls v0.53.1 CLI dispatch must add.
|
|
139
|
+
- **`soup train` with `task: distill`.** New `DistillTrainerWrapper`: student + frozen teacher both load via `AutoModelForCausalLM` (separate `trust_remote_code` resolution for each), KL / forward_KL / reverse_KL / JS divergence kernels scaled by `temperature**2` per the Hinton paper. Device-bridge: teacher inputs auto-move to the teacher's device, teacher logits move back onto the student's device before the KL kernel — survives HF Trainer's auto-CUDA promotion on a CPU-tagged run. `DataCollatorForSeq2Seq(label_pad_token_id=-100)` handles variable-length pre-tokenised loss-masked rows correctly.
|
|
140
|
+
- **`soup train` with `task: classifier | reranker | cross_encoder`.** New `ClassifierTrainerWrapper`: `AutoModelForSequenceClassification` with `num_labels` and `label_names`, auto-routes `single_label_classification` / `multi_label_classification` from `tcfg.classifier_kind`. Multi-label string labels resolved via the `label_names` map with a 1024-entry cap + dedup. Training Setup Panel renders `Head: num_labels=N, kind=...` instead of LoRA r/alpha for the classifier family.
|
|
141
|
+
- **EBFT structured / strided + GDPO standard / length_normalized / margin loss kernels.** `apply_ebft_loss` and `apply_gdpo_loss` exit the v0.52.0 `NotImplementedError` stubs with finite-only-input guards and bool-rejected numeric params. `attach_ebft_compute_loss(trainer, tcfg)` (SFT) and `attach_gdpo_compute_loss(trainer, tcfg)` (DPO) wrap `Trainer.compute_loss` idempotently — re-attach is a no-op via a marker attribute on the wrapped method. Auto-attached when the corresponding `*_variant` field is set on `TrainingConfig`.
|
|
142
|
+
- **gpt-oss `reasoning_effort` + `train_on_eot`.** `apply_reasoning_effort_prefix(messages, level)` injects `<|reasoning_effort|>{low,medium,high}<|/reasoning_effort|>` into the system turn (creates one if absent), returning a new list (caller's messages immutable). `build_assistant_only_labels(train_on_eot=True)` keeps the EOT/EOS token unmasked at the assistant-turn boundary so the model learns when to stop. Both gated to the SFT-family at config-load.
|
|
143
|
+
- **+120 net new tests** (7722 → 7842) across `test_v0532.py`. Four review agents (python / code / security / tdd) ran; every CRITICAL / HIGH / MEDIUM / LOW finding fixed — separate `trust_remote_code` resolution for student vs teacher, idempotent attach hooks with regression tests, 1024-entry multi-label cap, `dpo_margin` defaults to `None` (not `0.0`) so missing values raise rather than silently zero, source-grep regression guards on the trainer-routing call sites use the full instantiation expression (no comment-only false-positives), Panel renders the classifier head instead of LoRA r/alpha.
|
|
144
|
+
- **Local end-to-end CPU smoke** confirms both new wrappers train 2 steps with finite loss on `hf-internal-testing/tiny-random-gpt2`. Two real bugs surfaced and were fixed during the smoke (collator label padding + teacher / student device mismatch) — both have source-level regression guards in the test suite. ONNX export QA: pipeline integrity proven on tiny-gpt2; TinyLlama-1.1B full export is host-RAM-bound (documented in `tests/qa/v053_qa.md`).
|
|
146
145
|
|
|
147
146
|
## Why Soup?
|
|
148
147
|
|
|
@@ -367,6 +366,97 @@ soup init --template pretrain
|
|
|
367
366
|
soup train
|
|
368
367
|
```
|
|
369
368
|
|
|
369
|
+
## Knowledge Distillation
|
|
370
|
+
|
|
371
|
+
Train a small student model to match a larger teacher's output distribution.
|
|
372
|
+
|
|
373
|
+
```yaml
|
|
374
|
+
base: HuggingFaceTB/SmolLM2-135M
|
|
375
|
+
task: distill
|
|
376
|
+
modality: text
|
|
377
|
+
backend: transformers
|
|
378
|
+
|
|
379
|
+
data:
|
|
380
|
+
train: ./data/chat.jsonl
|
|
381
|
+
max_length: 2048
|
|
382
|
+
chat_template: chatml
|
|
383
|
+
|
|
384
|
+
training:
|
|
385
|
+
teacher_model: meta-llama/Llama-3.1-8B
|
|
386
|
+
distill_divergence: forward_kl # kl | forward_kl | reverse_kl | js
|
|
387
|
+
distill_temperature: 2.0
|
|
388
|
+
epochs: 3
|
|
389
|
+
lr: 5e-5
|
|
390
|
+
quantization: 4bit # quantizes student only
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Loss = student CE + (T**2) × KL(teacher_logits / T || student_logits / T).
|
|
394
|
+
Teacher is loaded once, frozen via `requires_grad_(False)` + `.eval()`, and its
|
|
395
|
+
inputs / logits are auto-bridged across CPU / CUDA devices.
|
|
396
|
+
|
|
397
|
+
## Sequence Classification
|
|
398
|
+
|
|
399
|
+
Train a classifier head on top of any base model — supports single-label,
|
|
400
|
+
multi-label, and cross-encoder reranking.
|
|
401
|
+
|
|
402
|
+
```yaml
|
|
403
|
+
base: BAAI/bge-base-en-v1.5
|
|
404
|
+
task: classifier # or `reranker`, `cross_encoder`
|
|
405
|
+
modality: text
|
|
406
|
+
backend: transformers
|
|
407
|
+
|
|
408
|
+
data:
|
|
409
|
+
train: ./data/labelled.jsonl # rows: {"text": "...", "label": "spam"} or {"text": "...", "label": [0, 1, 0]}
|
|
410
|
+
max_length: 256
|
|
411
|
+
|
|
412
|
+
training:
|
|
413
|
+
num_labels: 3
|
|
414
|
+
classifier_kind: single_label # or `multi_label`
|
|
415
|
+
label_names: [ham, spam, promo] # required when labels are strings
|
|
416
|
+
epochs: 5
|
|
417
|
+
lr: 2e-5
|
|
418
|
+
batch_size: 32
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Routes `classifier` / `reranker` / `cross_encoder` through
|
|
422
|
+
`AutoModelForSequenceClassification`. Multi-label heads cap at 1024 entries per
|
|
423
|
+
row, dedup via set conversion, and reject null bytes in label strings.
|
|
424
|
+
|
|
425
|
+
## Reasoning Effort + EOT Control
|
|
426
|
+
|
|
427
|
+
gpt-oss-style reasoning-effort control for instruction tuning.
|
|
428
|
+
|
|
429
|
+
```yaml
|
|
430
|
+
training:
|
|
431
|
+
reasoning_effort: high # low | medium | high
|
|
432
|
+
train_on_eot: true # do NOT mask the EOT/EOS token in the loss
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
`reasoning_effort` injects `<|reasoning_effort|>high<|/reasoning_effort|>` into
|
|
436
|
+
the system turn (creating one if absent). `train_on_eot=True` makes the model
|
|
437
|
+
learn when to stop generating by training on the trailing EOS token instead of
|
|
438
|
+
masking it out. Both are gated to the SFT-family of tasks.
|
|
439
|
+
|
|
440
|
+
## EBFT / GDPO Loss Variants
|
|
441
|
+
|
|
442
|
+
Entropy-regularised SFT (`ebft_variant: structured | strided`) and generalised
|
|
443
|
+
DPO (`gdpo_variant: standard | length_normalized | margin`) — both attach
|
|
444
|
+
idempotently via `compute_loss` wrappers and auto-fire when the corresponding
|
|
445
|
+
variant field is set on `TrainingConfig`.
|
|
446
|
+
|
|
447
|
+
```yaml
|
|
448
|
+
# SFT with EBFT structured
|
|
449
|
+
training:
|
|
450
|
+
ebft_variant: structured
|
|
451
|
+
ebft_temperature: 1.0
|
|
452
|
+
|
|
453
|
+
# DPO with GDPO length_normalized
|
|
454
|
+
task: dpo
|
|
455
|
+
training:
|
|
456
|
+
gdpo_variant: length_normalized
|
|
457
|
+
dpo_beta: 0.1
|
|
458
|
+
```
|
|
459
|
+
|
|
370
460
|
## MoE Model Support
|
|
371
461
|
|
|
372
462
|
Fine-tune Mixture of Experts models (Mixtral, Qwen3-30B-A3B, DeepSeek V3) with ScatterMoE LoRA — applies LoRA to both attention layers and expert FFN layers:
|
|
@@ -3732,6 +3822,40 @@ Cross-validator ordering picks the most actionable error: `quantization_aware='f
|
|
|
3732
3822
|
|
|
3733
3823
|
`soup export --format torchao --quant-config <yaml>` is the planned PTQ export surface for `torchao.quantize_` + `save_pretrained`. Four schemes are allowlisted: `Int4WeightOnly`, `Int8DynActInt4`, `Float8DynActFloat8`, `NVFP4`. CASE-SENSITIVE — these are PyTorch class names and `torchao.quantize_` looks them up by exact name. Diverges from `--save-format` (lowercase-normalised) on purpose; documented at both validators.
|
|
3734
3824
|
|
|
3825
|
+
## Quant Menu II + Export Pipeline (v0.53.1)
|
|
3826
|
+
|
|
3827
|
+
v0.53.1 lifts the v0.53.0 schema-only stubs to live wiring:
|
|
3828
|
+
|
|
3829
|
+
```bash
|
|
3830
|
+
# Single-stage BNB-4bit merged checkpoint (no dequant/merge/requant)
|
|
3831
|
+
soup merge -a ./adapter -o ./merged_4bit --save-format 4bit
|
|
3832
|
+
|
|
3833
|
+
# TorchAO PTQ export — closed per-scheme kwarg allowlist
|
|
3834
|
+
cat > q.yaml <<EOF
|
|
3835
|
+
scheme: Int4WeightOnly
|
|
3836
|
+
group_size: 32
|
|
3837
|
+
EOF
|
|
3838
|
+
soup export --model ./merged --format torchao --quant-config ./q.yaml --output ./out
|
|
3839
|
+
|
|
3840
|
+
# Unsloth Dynamic 2.0 / IQ / Apple-ARM GGUF via llama.cpp imatrix
|
|
3841
|
+
soup export --model ./merged --format gguf-ud \
|
|
3842
|
+
--gguf-flavour UD-Q4_K_XL \
|
|
3843
|
+
--calibration-data ./calib.jsonl \
|
|
3844
|
+
--output ./out/model.UD-Q4_K_XL.gguf
|
|
3845
|
+
|
|
3846
|
+
# Deploy autopilot with live Quant-Lobotomy measurement
|
|
3847
|
+
soup deploy autopilot --target rtx-4090-24gb \
|
|
3848
|
+
--base meta-llama/Llama-3.2-1B \
|
|
3849
|
+
--measure --tasks ./eval_tasks.jsonl \
|
|
3850
|
+
--measure-candidates 4bit,gptq,awq
|
|
3851
|
+
```
|
|
3852
|
+
|
|
3853
|
+
Autopilot also detects pre-quantized bases automatically — `TheBloke/Llama-2-7B-Chat-GPTQ` is recommended `gptq` instead of stacking 4-bit on top. Detection runs against the base-model name regex AND any local `config.json`'s `quantization_config.quant_method`. Out-of-cwd model paths are silently skipped (soft-probe semantics).
|
|
3854
|
+
|
|
3855
|
+
The advanced GGUF pipeline uses POSIX `O_NOFOLLOW` to defeat the TOCTOU race between the dispatch-time symlink check and the actual open of the calibration data — a crafted environment cannot race-swap the calibration file between validate and read.
|
|
3856
|
+
|
|
3857
|
+
`soup deploy autopilot --measure` caches results at `~/.soup/deploy_autopilot_cache.json` keyed on `(base, profile, eval-tasks)`. Repeat invocations short-circuit; pass `SOUP_DEPLOY_AUTOPILOT_CACHE=<path>` to redirect (constrained to home / cwd / tempdir). The recommended candidate uses soft-fallback: first `OK` by insertion order, else the candidate with the smallest delta (least drop relative to its own baseline).
|
|
3858
|
+
|
|
3735
3859
|
## Changelog
|
|
3736
3860
|
|
|
3737
3861
|
See [GitHub Releases](https://github.com/MakazhanAlpamys/Soup/releases) for version history.
|
|
@@ -43,15 +43,14 @@ soup train
|
|
|
43
43
|
|
|
44
44
|
Latest highlights only. Full history: [GitHub Releases](https://github.com/MakazhanAlpamys/Soup/releases).
|
|
45
45
|
|
|
46
|
-
**v0.53.
|
|
46
|
+
**v0.53.2 — Modality II live trainers**: Four v0.52.0 deferred stubs lifted into real, end-to-end-trainable wrappers — knowledge distillation, sequence classification, EBFT / GDPO loss kernels, and gpt-oss-style `reasoning_effort` system-prompt injection.
|
|
47
47
|
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
- **
|
|
51
|
-
- **
|
|
52
|
-
- **
|
|
53
|
-
- **
|
|
54
|
-
- **+157 net new tests** (7453 → 7610) across 154 tests in `test_v0530.py`. Five review agents (python / code / security / tdd / verification) ran in parallel; every CRITICAL / HIGH / MEDIUM / LOW finding fixed or documented: O(1) `_LOWER_INDEX` for GGUF lookup, ref-task set extended with GRPO + KTO, `_validate_v053_bool_fields` no longer silently coerces `None`, `requires_hopper` reads from spec metadata, `fp8_attention` validator order swapped so the `quantization_aware='fp8'` error fires first, `validate_calibration_data_path` / `validate_quant_config_path` docstrings name the exact controls v0.53.1 CLI dispatch must add.
|
|
48
|
+
- **`soup train` with `task: distill`.** New `DistillTrainerWrapper`: student + frozen teacher both load via `AutoModelForCausalLM` (separate `trust_remote_code` resolution for each), KL / forward_KL / reverse_KL / JS divergence kernels scaled by `temperature**2` per the Hinton paper. Device-bridge: teacher inputs auto-move to the teacher's device, teacher logits move back onto the student's device before the KL kernel — survives HF Trainer's auto-CUDA promotion on a CPU-tagged run. `DataCollatorForSeq2Seq(label_pad_token_id=-100)` handles variable-length pre-tokenised loss-masked rows correctly.
|
|
49
|
+
- **`soup train` with `task: classifier | reranker | cross_encoder`.** New `ClassifierTrainerWrapper`: `AutoModelForSequenceClassification` with `num_labels` and `label_names`, auto-routes `single_label_classification` / `multi_label_classification` from `tcfg.classifier_kind`. Multi-label string labels resolved via the `label_names` map with a 1024-entry cap + dedup. Training Setup Panel renders `Head: num_labels=N, kind=...` instead of LoRA r/alpha for the classifier family.
|
|
50
|
+
- **EBFT structured / strided + GDPO standard / length_normalized / margin loss kernels.** `apply_ebft_loss` and `apply_gdpo_loss` exit the v0.52.0 `NotImplementedError` stubs with finite-only-input guards and bool-rejected numeric params. `attach_ebft_compute_loss(trainer, tcfg)` (SFT) and `attach_gdpo_compute_loss(trainer, tcfg)` (DPO) wrap `Trainer.compute_loss` idempotently — re-attach is a no-op via a marker attribute on the wrapped method. Auto-attached when the corresponding `*_variant` field is set on `TrainingConfig`.
|
|
51
|
+
- **gpt-oss `reasoning_effort` + `train_on_eot`.** `apply_reasoning_effort_prefix(messages, level)` injects `<|reasoning_effort|>{low,medium,high}<|/reasoning_effort|>` into the system turn (creates one if absent), returning a new list (caller's messages immutable). `build_assistant_only_labels(train_on_eot=True)` keeps the EOT/EOS token unmasked at the assistant-turn boundary so the model learns when to stop. Both gated to the SFT-family at config-load.
|
|
52
|
+
- **+120 net new tests** (7722 → 7842) across `test_v0532.py`. Four review agents (python / code / security / tdd) ran; every CRITICAL / HIGH / MEDIUM / LOW finding fixed — separate `trust_remote_code` resolution for student vs teacher, idempotent attach hooks with regression tests, 1024-entry multi-label cap, `dpo_margin` defaults to `None` (not `0.0`) so missing values raise rather than silently zero, source-grep regression guards on the trainer-routing call sites use the full instantiation expression (no comment-only false-positives), Panel renders the classifier head instead of LoRA r/alpha.
|
|
53
|
+
- **Local end-to-end CPU smoke** confirms both new wrappers train 2 steps with finite loss on `hf-internal-testing/tiny-random-gpt2`. Two real bugs surfaced and were fixed during the smoke (collator label padding + teacher / student device mismatch) — both have source-level regression guards in the test suite. ONNX export QA: pipeline integrity proven on tiny-gpt2; TinyLlama-1.1B full export is host-RAM-bound (documented in `tests/qa/v053_qa.md`).
|
|
55
54
|
|
|
56
55
|
## Why Soup?
|
|
57
56
|
|
|
@@ -276,6 +275,97 @@ soup init --template pretrain
|
|
|
276
275
|
soup train
|
|
277
276
|
```
|
|
278
277
|
|
|
278
|
+
## Knowledge Distillation
|
|
279
|
+
|
|
280
|
+
Train a small student model to match a larger teacher's output distribution.
|
|
281
|
+
|
|
282
|
+
```yaml
|
|
283
|
+
base: HuggingFaceTB/SmolLM2-135M
|
|
284
|
+
task: distill
|
|
285
|
+
modality: text
|
|
286
|
+
backend: transformers
|
|
287
|
+
|
|
288
|
+
data:
|
|
289
|
+
train: ./data/chat.jsonl
|
|
290
|
+
max_length: 2048
|
|
291
|
+
chat_template: chatml
|
|
292
|
+
|
|
293
|
+
training:
|
|
294
|
+
teacher_model: meta-llama/Llama-3.1-8B
|
|
295
|
+
distill_divergence: forward_kl # kl | forward_kl | reverse_kl | js
|
|
296
|
+
distill_temperature: 2.0
|
|
297
|
+
epochs: 3
|
|
298
|
+
lr: 5e-5
|
|
299
|
+
quantization: 4bit # quantizes student only
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Loss = student CE + (T**2) × KL(teacher_logits / T || student_logits / T).
|
|
303
|
+
Teacher is loaded once, frozen via `requires_grad_(False)` + `.eval()`, and its
|
|
304
|
+
inputs / logits are auto-bridged across CPU / CUDA devices.
|
|
305
|
+
|
|
306
|
+
## Sequence Classification
|
|
307
|
+
|
|
308
|
+
Train a classifier head on top of any base model — supports single-label,
|
|
309
|
+
multi-label, and cross-encoder reranking.
|
|
310
|
+
|
|
311
|
+
```yaml
|
|
312
|
+
base: BAAI/bge-base-en-v1.5
|
|
313
|
+
task: classifier # or `reranker`, `cross_encoder`
|
|
314
|
+
modality: text
|
|
315
|
+
backend: transformers
|
|
316
|
+
|
|
317
|
+
data:
|
|
318
|
+
train: ./data/labelled.jsonl # rows: {"text": "...", "label": "spam"} or {"text": "...", "label": [0, 1, 0]}
|
|
319
|
+
max_length: 256
|
|
320
|
+
|
|
321
|
+
training:
|
|
322
|
+
num_labels: 3
|
|
323
|
+
classifier_kind: single_label # or `multi_label`
|
|
324
|
+
label_names: [ham, spam, promo] # required when labels are strings
|
|
325
|
+
epochs: 5
|
|
326
|
+
lr: 2e-5
|
|
327
|
+
batch_size: 32
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Routes `classifier` / `reranker` / `cross_encoder` through
|
|
331
|
+
`AutoModelForSequenceClassification`. Multi-label heads cap at 1024 entries per
|
|
332
|
+
row, dedup via set conversion, and reject null bytes in label strings.
|
|
333
|
+
|
|
334
|
+
## Reasoning Effort + EOT Control
|
|
335
|
+
|
|
336
|
+
gpt-oss-style reasoning-effort control for instruction tuning.
|
|
337
|
+
|
|
338
|
+
```yaml
|
|
339
|
+
training:
|
|
340
|
+
reasoning_effort: high # low | medium | high
|
|
341
|
+
train_on_eot: true # do NOT mask the EOT/EOS token in the loss
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
`reasoning_effort` injects `<|reasoning_effort|>high<|/reasoning_effort|>` into
|
|
345
|
+
the system turn (creating one if absent). `train_on_eot=True` makes the model
|
|
346
|
+
learn when to stop generating by training on the trailing EOS token instead of
|
|
347
|
+
masking it out. Both are gated to the SFT-family of tasks.
|
|
348
|
+
|
|
349
|
+
## EBFT / GDPO Loss Variants
|
|
350
|
+
|
|
351
|
+
Entropy-regularised SFT (`ebft_variant: structured | strided`) and generalised
|
|
352
|
+
DPO (`gdpo_variant: standard | length_normalized | margin`) — both attach
|
|
353
|
+
idempotently via `compute_loss` wrappers and auto-fire when the corresponding
|
|
354
|
+
variant field is set on `TrainingConfig`.
|
|
355
|
+
|
|
356
|
+
```yaml
|
|
357
|
+
# SFT with EBFT structured
|
|
358
|
+
training:
|
|
359
|
+
ebft_variant: structured
|
|
360
|
+
ebft_temperature: 1.0
|
|
361
|
+
|
|
362
|
+
# DPO with GDPO length_normalized
|
|
363
|
+
task: dpo
|
|
364
|
+
training:
|
|
365
|
+
gdpo_variant: length_normalized
|
|
366
|
+
dpo_beta: 0.1
|
|
367
|
+
```
|
|
368
|
+
|
|
279
369
|
## MoE Model Support
|
|
280
370
|
|
|
281
371
|
Fine-tune Mixture of Experts models (Mixtral, Qwen3-30B-A3B, DeepSeek V3) with ScatterMoE LoRA — applies LoRA to both attention layers and expert FFN layers:
|
|
@@ -3641,6 +3731,40 @@ Cross-validator ordering picks the most actionable error: `quantization_aware='f
|
|
|
3641
3731
|
|
|
3642
3732
|
`soup export --format torchao --quant-config <yaml>` is the planned PTQ export surface for `torchao.quantize_` + `save_pretrained`. Four schemes are allowlisted: `Int4WeightOnly`, `Int8DynActInt4`, `Float8DynActFloat8`, `NVFP4`. CASE-SENSITIVE — these are PyTorch class names and `torchao.quantize_` looks them up by exact name. Diverges from `--save-format` (lowercase-normalised) on purpose; documented at both validators.
|
|
3643
3733
|
|
|
3734
|
+
## Quant Menu II + Export Pipeline (v0.53.1)
|
|
3735
|
+
|
|
3736
|
+
v0.53.1 lifts the v0.53.0 schema-only stubs to live wiring:
|
|
3737
|
+
|
|
3738
|
+
```bash
|
|
3739
|
+
# Single-stage BNB-4bit merged checkpoint (no dequant/merge/requant)
|
|
3740
|
+
soup merge -a ./adapter -o ./merged_4bit --save-format 4bit
|
|
3741
|
+
|
|
3742
|
+
# TorchAO PTQ export — closed per-scheme kwarg allowlist
|
|
3743
|
+
cat > q.yaml <<EOF
|
|
3744
|
+
scheme: Int4WeightOnly
|
|
3745
|
+
group_size: 32
|
|
3746
|
+
EOF
|
|
3747
|
+
soup export --model ./merged --format torchao --quant-config ./q.yaml --output ./out
|
|
3748
|
+
|
|
3749
|
+
# Unsloth Dynamic 2.0 / IQ / Apple-ARM GGUF via llama.cpp imatrix
|
|
3750
|
+
soup export --model ./merged --format gguf-ud \
|
|
3751
|
+
--gguf-flavour UD-Q4_K_XL \
|
|
3752
|
+
--calibration-data ./calib.jsonl \
|
|
3753
|
+
--output ./out/model.UD-Q4_K_XL.gguf
|
|
3754
|
+
|
|
3755
|
+
# Deploy autopilot with live Quant-Lobotomy measurement
|
|
3756
|
+
soup deploy autopilot --target rtx-4090-24gb \
|
|
3757
|
+
--base meta-llama/Llama-3.2-1B \
|
|
3758
|
+
--measure --tasks ./eval_tasks.jsonl \
|
|
3759
|
+
--measure-candidates 4bit,gptq,awq
|
|
3760
|
+
```
|
|
3761
|
+
|
|
3762
|
+
Autopilot also detects pre-quantized bases automatically — `TheBloke/Llama-2-7B-Chat-GPTQ` is recommended `gptq` instead of stacking 4-bit on top. Detection runs against the base-model name regex AND any local `config.json`'s `quantization_config.quant_method`. Out-of-cwd model paths are silently skipped (soft-probe semantics).
|
|
3763
|
+
|
|
3764
|
+
The advanced GGUF pipeline uses POSIX `O_NOFOLLOW` to defeat the TOCTOU race between the dispatch-time symlink check and the actual open of the calibration data — a crafted environment cannot race-swap the calibration file between validate and read.
|
|
3765
|
+
|
|
3766
|
+
`soup deploy autopilot --measure` caches results at `~/.soup/deploy_autopilot_cache.json` keyed on `(base, profile, eval-tasks)`. Repeat invocations short-circuit; pass `SOUP_DEPLOY_AUTOPILOT_CACHE=<path>` to redirect (constrained to home / cwd / tempdir). The recommended candidate uses soft-fallback: first `OK` by insertion order, else the candidate with the smallest delta (least drop relative to its own baseline).
|
|
3767
|
+
|
|
3644
3768
|
## Changelog
|
|
3645
3769
|
|
|
3646
3770
|
See [GitHub Releases](https://github.com/MakazhanAlpamys/Soup/releases) for version history.
|
|
@@ -9,14 +9,15 @@ We provide security updates for the following versions:
|
|
|
9
9
|
- **Versions older than 3 minor versions:** No support
|
|
10
10
|
|
|
11
11
|
Example:
|
|
12
|
-
- v0.53.
|
|
12
|
+
- v0.53.2 -- Full support (latest)
|
|
13
|
+
- v0.53.1 -- Full support
|
|
14
|
+
- v0.53.0 -- Full support
|
|
13
15
|
- v0.52.0 -- Full support
|
|
14
16
|
- v0.51.0 -- Full support
|
|
15
17
|
- v0.50.0 -- Full support
|
|
16
|
-
- v0.49.0 --
|
|
18
|
+
- v0.49.0 -- Bug-fix support only
|
|
17
19
|
- v0.48.0 -- Bug-fix support only
|
|
18
|
-
- v0.47.
|
|
19
|
-
- v0.46.x and below -- No support
|
|
20
|
+
- v0.47.x and below -- No support
|
|
20
21
|
|
|
21
22
|
## Reporting a Vulnerability
|
|
22
23
|
|
|
@@ -147,6 +148,9 @@ No known critical vulnerabilities in current releases.
|
|
|
147
148
|
- **v0.32.0 — Training Stability & Auto-Tuning**: `--find-lr-output` containment via shared `utils/paths.is_under_cwd` (prevents writes outside cwd); `save_lr_finder_report` rejects NaN / Infinity floats in `lrs` / `losses` and serialises with `allow_nan=False` (keeps the report parser-safe); `compute_lr_schedule` rejects non-positive `start_lr`, inverted ranges, and `num_steps` outside `[2, 10_000]`; `pick_mixed_precision` rejects empty / null-byte / >200-char model names and resolves multi-version quirks (`qwen2.5` vs `qwen2`, `phi-3.5` vs `phi-3`) by longest-substring-first iteration so an added family can never accidentally make a more-specific entry dead code; `compute_warmup_steps` clamps to `[10, 1000]` with a `ratio==0.0` short-circuit matching HF Trainer's "no warmup" convention; `SpikeRecoveryStrategy` is `@dataclass(frozen=True)` (post-construction mutation cannot bypass validation), `max_attempts ∈ [1, 10]`, `lr_decay ∈ (0, 1)`, `min_lr > 0`; cross-validator `_validate_spike_recovery_requires_watchdog` rejects `loss_spike_recovery=true, loss_watchdog=false` at config-load (fails fast instead of never triggering); `convergence_window ∈ [5, 10_000]`, `convergence_rel_tol ∈ (0, 1]`, `recommend_action` reuses `detect_plateau` so plateau heuristic stays single-source-of-truth; `GradAccumMonitor.recommend()` caps doubled `accum` at `MAX_ACCUM=1024` so a runaway advisory loop cannot blow up DataLoader prefetch; `generate_config` validates BOTH the YAML output path AND the embedded `decisions["output"]` field via `is_under_cwd` (closes the gap where a crafted `decisions["output"]="../../etc"` would have silently propagated into the rendered YAML)
|
|
148
149
|
- **v0.34.0 — Observability & Dev UX**: `.crash` bundle generator (`utils/crash.py`) recursively redacts `hf_*` / `sk-*` / `Bearer …` token-shaped strings in any captured `config` and metric tail before serialisation, so a `.crash` file shared on a public GitHub issue cannot leak credentials; `output_dir` is reduced to `os.path.basename` so `$HOME` doesn't leak; `write_crash_bundle` uses `os.path.realpath + commonpath` for cwd containment (Windows-safe; raises `ValueError` not `PermissionError` so callers cannot silently swallow with `except OSError`); filename appends `secrets.token_hex(4)` so two crashes in the same UTC second don't collide; bundle truncated to `MAX_BUNDLE_BYTES=1_000_000`. `train.py` crash-write surfaces failures to the user (no silent missing-bundle). `profiling.py` `resolve_trace_path` rejects empty / `.` / `..` / `/` / `\\` / null-byte `run_id` (closes the `output_dir/profiles/../trace.json` escape) and uses `os.path.realpath + is_under_cwd`; profiles dir is created only on successful torch import (no stale empty dirs on torch-less CI). `tracker.get_run` LIKE-prefix match escapes `%` / `_` / `\\` and uses `ESCAPE '\\'` so a crafted `run_id` cannot widen the match (mirrors v0.26.0 registry policy). Lazy schema migration (`_ensure_schema`) tolerates the "duplicate column" race when two CLI processes start simultaneously on a fresh DB (fork-based multi-GPU training, TUI auto-refresh). `runs.py show/replay/clean` switched user `run_id` rendering to `markup_escape` and switched `clean` containment from broken `Path.resolve() + relative_to()` to project-standard `os.path.realpath + is_under_cwd`. `tui_app.py` lazy-imports `ExperimentTracker` and `markup_escape`s every DB-sourced string before passing into Textual widgets so a crafted base_model / experiment_name cannot inject `[bold red]…[/]` markup. `run_cost.estimate_run_cost_usd` rejects `bool` in `num_gpus` (bool is a subclass of int — same defence as v0.30.0 `Candidate.__post_init__`); duration clamped to `[0, 1 year]`; unknown GPU returns `None` so callers render `—` instead of fabricating `$0.00`. `log_level.parse_log_level` rejects non-string + null-byte input.
|
|
149
150
|
- **v0.33.0 — Live Wire**: RLVR `code_exec_reward` adds OS-level isolation (Linux best-effort `os.unshare(CLONE_NEWUSER|CLONE_NEWNET|CLONE_NEWPID)`, macOS `sandbox-exec` with default-deny `MACOS_SANDBOX_PROFILE` narrowed to a 3-name `mach-lookup` allowlist to prevent DNS / NSURLSession bypass of `(deny network*)`); `prune_checkpoints` switches to TOCTOU-safe `os.lstat + S_ISLNK` + `shutil.rmtree(onerror=_abort_on_symlink)` so a symlink encountered mid-walk aborts rather than escapes; `run_gate` wraps each task scorer in a typed `try/except` so backend failures produce `score=None, error=str(exc)` (never silent `score=1.0`); `_parse_judge_url` removes the bare `http://` catch-all (defence-in-depth after the Pydantic GateTask validator); `soup can run` requires `--yes` or explicit consent callback and raises `ValueError` (not `PermissionError`, which is an `OSError` subclass that broad `except` blocks would swallow); GGUF `rglob` result for ollama deploy is `realpath+commonpath` checked against extract_dir (prevents symlink escape from a crafted can); `DeployTarget.path` validator normalises mixed `\\`/`/` separators before splitting (closes a Windows `..` bypass); `CAN_FORMAT_VERSION` 1→2 (additive — v1 still loads); `soup can publish` validates `repo_id` via `utils/hf.validate_repo_id`, resolves token via `resolve_token`, sanitises commit messages (first-line, 200-char cap), uses HTTPS-only HfApi; `_write_spike_recovery_hint` adds `is_under_cwd` containment check on `args.output_dir` from raw HF `TrainingArguments`; `lookup_entry_by_output_dir` emits `ResourceWarning` when 1000-row scan limit is hit (no silent miss); `CrossDocCollator` no longer mutates input feature dicts (HF Dataset rows are cached and reused — mutation broke subsequent batches); `Candidate` rejects `bool` in `score`/`latency_ms` (was sneaking past `int` isinstance check); `evaluate_candidate` latency mean now divides by *completed* prompts (excludes crashed) so a broken candidate isn't artificially fast; `auto_quant.run_auto_quant_picker` soft-falls-back to highest-scored candidate when no candidate clears `min_score` (server still binds); `build_logits_processors` returns `[]` when neither `outlines` nor `lm-format-enforcer` is installed (server degrades to free-form rather than 500); MII server uses loopback-only CORS, max_tokens cap [1, 16384], stream rejection, generic 500 with no stack-trace leak; `os.execvp` auto-reexec uses list args (no shell), all forwarded flags pre-validated; `cleanup_extract_dir` uses `os.path.commonpath` (Windows-safe) instead of `startswith`; `_run_subprocess` catches `TimeoutExpired` and returns rc=124 (coreutils convention) instead of an unhandled traceback; new `eval_results` and `tensorrt` artifact kinds in `RegistryStore._VALID_KINDS`
|
|
151
|
+
- **v0.53.2 — Modality II live trainers**: lifts four v0.52.0 deferred stubs (#137, #135, #133, #132) into real trainer wrappers while keeping the project's hardening invariants. (#137 reasoning_effort + train_on_eot) `apply_reasoning_effort_prefix` follows v0.41.0 / v0.51.0 validator policy (bool-first, null-byte / empty / oversize / case-insensitive normalisation); messages list is treated as immutable (returns a new list — matches v0.33.0 #47 `CrossDocCollator` policy). `build_assistant_only_labels(train_on_eot=True)` reuses the existing v0.36.0 mask infrastructure — same null-byte / max_length / bool guards. (#135 EBFT / GDPO) `apply_ebft_loss` and `apply_gdpo_loss` enforce **finite-only inputs** (`torch.isfinite` guard on tensor inputs + `math.isfinite` on scalar params) — NaN / Inf would silently corrupt training otherwise. `dpo_margin` defaults to `None` (not `0.0`) per security-review M3 fix: silent zeroing in the `margin` variant when the operator forgot to set the margin would have looked like training success but produced a meaningless gradient. Both attach hooks (`attach_ebft_compute_loss`, `attach_gdpo_compute_loss`) are **idempotent** via a marker attribute on the wrapped method — re-attach is a no-op and a dedicated test class verifies the invariant (code-review M2 fix). (#133 DistillTrainerWrapper) **Separate trust_remote_code resolution for student and teacher** (security-review L2 fix): `model_requires_trust_remote_code(teacher)` runs independently of the student probe, otherwise a malicious teacher could piggy-back on the student's opt-in. Teacher is loaded with `device_map="cpu" if device == "cpu" else "auto"`, frozen via `requires_grad_(False)` + `.eval()` immediately after load — never participates in gradient computation. `_DistillTrainer.compute_loss` device-bridge: `teacher_device = next(teacher_ref.parameters()).device`, `teacher_inputs.to(teacher_device)` before teacher forward, `teacher_logits.to(student_logits.device)` before KL kernel — defends against HF Trainer's auto-CUDA promotion silently producing cross-device `index_select` crashes. **DataCollator correctness fix** (surfaced during Wave 3 CPU smoke): `DataCollatorForLanguageModeling` does NOT pad pre-tokenised `labels` — switched to `DataCollatorForSeq2Seq(label_pad_token_id=-100, padding=True)` so variable-length loss-masked rows batch correctly without runtime crash. (#132 ClassifierTrainerWrapper) `_normalise_label` caps multi-label entries at **1024 per row** (matches v0.52.0 schema cap; security-review HIGH fix — unbounded would allow OOM via crafted JSONL), dedups via set conversion, validates `label_names` map entries reject null bytes + empty strings. `problem_type` is set explicitly from `tcfg.classifier_kind` (not silently inferred from labels) so a multi-label-shaped row in a single-label config raises rather than mis-trains. Training Setup Panel renders `Head: num_labels=N, kind=...` for classifier-family tasks instead of meaningless LoRA r/alpha lines (code-review L3 cosmetic fix — Panel no longer mis-represents what the wrapper is doing). (Cross-cutting) `commands/train.py` task routing branches added for `distill` and `classifier` / `reranker` / `cross_encoder` — source-grep regression guards in the test suite use the **full instantiation expression** `DistillTrainerWrapper(cfg, **trainer_kwargs)` so comment-only mentions of the class name cannot satisfy the regression check (TDD-review hardening). Both new factories (`build_distill_trainer`, `build_classifier_trainer`) reject unknown kwargs via Python signature contract — dedicated `pytest.raises(TypeError)` tests cover the path (TDD-review L1 fix). Test surface: 1 new test file (`test_v0532.py`) carrying 120 new tests across 14 classes. Known limitations: (1) `#71` TinyLlama-1.1B-LoRA full ONNX export is host-RAM-bound (≥16 GB free RAM needed for the `onnx.load(load_external_data=True)` post-process step); tiny-gpt2 smoke proves pipeline integrity — recorded in `tests/qa/v053_qa.md`. (2) Distillation supports same-tokenizer pairs only — cross-tokenizer (Llama → Qwen) needs a projection or sequence-level loss, out of scope. (3) Classifier wrapper has no LoRA path — full head + base training; LoRA classifier finetuning is a follow-up. (4) EBFT / GDPO auto-attach only fires when the corresponding `*_variant` field is set; manual `attach_*` invocation from custom training loops is supported and idempotent. (5) `reasoning_effort` injection happens at data-prep time inside `build_format_row`; changing the level between runs requires re-rendering the dataset. (v0.53.2)
|
|
152
|
+
|
|
153
|
+
- **v0.53.1 — Quant Menu II + Export pipeline live**: lifts six v0.53.0 deferred stubs to live wiring while keeping the project's hardening invariants. New shared helper `soup_cli/utils/paths.enforce_under_cwd_and_no_symlink` consolidates the v0.33.0 #22 TOCTOU pattern (cwd containment via `os.path.realpath + os.path.commonpath` + `os.lstat + S_ISLNK` rejection) — used by `commands/merge.py`, `commands/export.py`, `utils/save_formats.py`, and `utils/gguf_quant.py` so the same boundary check fires at every CLI dispatch point. `merge_4bit` and `export_torchao` (`utils/save_formats.py`): cwd containment + symlink rejection on `merged_dir` / `model_dir` / `output_dir`; `load_quant_config` enforces `yaml.safe_load` only + 256 KB cap + extension allowlist (`.yaml`/`.yml`); **per-scheme closed kwarg allowlist** rejects dunder keys + unknown params before the splat into `torchao.<scheme>Config(**kwargs)` (security-review HIGH fix — `Int4WeightOnly` accepts `{group_size, inner_k_tiles}`, `NVFP4` accepts nothing extra). Corrected BNB-4bit skip-modules kwarg name from `llm_int8_skip_modules` to `bnb_4bit_skip_modules`. `export_advanced_gguf` (`utils/gguf_quant.py`): all three subprocess invocations (`convert_hf_to_gguf.py`, `llama-imatrix`, `llama-quantize`) use argv-list form with no shell, 30-min timeout, `sys.executable` for the convert script; `_run_convert_to_f16` realpath-verifies that `convert_hf_to_gguf.py` stays inside the `llama_cpp_dir` after resolution (security-review HIGH M5 fix — defends against a symlinked script escape). `_prepare_calibration_text` strips null bytes, collapses newlines to spaces, caps per-line at 8 KB + total at 50 MB (security-review M1), uses POSIX `O_NOFOLLOW` to refuse symlinks at the kernel level (security-review M3 — closes the TOCTOU window between the dispatch-time check and the actual `open()`); requires ≥ 1 usable row before invoking imatrix. `_safe_stderr` Rich-markup-escapes subprocess stderr before embedding in `RuntimeError` (security-review L4) so a crafted llama.cpp error cannot inject `[red]...[/]` into the operator-facing panel. UD-prefix stripped from flavour arg before passing to llama-quantize (`UD-Q4_K_XL` → `Q4_K_XL`). Calibration data path containment + symlink rejection fires at CLI dispatch in `commands/export.py::_export_gguf_advanced`. `detect_prequantized_format_from_path` (`autopilot/decisions.py`): cwd containment + `os.lstat + S_ISLNK` on `<model_dir>/config.json` (security-review HIGH H2 — out-of-cwd model paths silently return `None` to preserve soft-probe semantics so HF Hub repo IDs aren't rejected); null-byte rejection on `model_dir`. `commands/merge.py`: early `is_under_cwd(output)` check at CLI boundary (security-review M4) — consistent with the v0.20.0 / v0.40.2 containment-at-the-boundary policy. `deploy_measure.py`: cache file written atomically via `tempfile.mkstemp` + `os.replace` with `os.lstat + S_ISLNK` rejection on BOTH `load_cache` and `save_cache` (security-review M2 — was missing on the load side); env override `SOUP_DEPLOY_AUTOPILOT_CACHE` rejects null bytes + control chars before any path resolution and confines the override to home / cwd / tempdir; cache file gets best-effort 0o600 perms on POSIX (matches v0.26.0 registry.db policy); 1 MB cache-file cap. `_DEPLOY_MEASURE_BEFORE_GEN` / `_AFTER_FACTORY` module-level callables are documented as a non-public escape hatch (deferred until v0.46.1 live model-loader). Test surface: 4 new test files (`test_v0531_82.py` / `test_v0531_109.py` / `test_v0531_139.py` / `test_v0531_142.py`) carrying 112 new tests covering happy paths + failure modes + every security guard (POSIX symlink rejection, per-scheme kwarg allowlist, TOCTOU defences, `_MAX_CANDIDATES` cap, MINOR-verdict band, mxfp4 word boundary, BNB-alias detection, render-table markup escape). Known limitations: (1) `_DEPLOY_MEASURE_BEFORE_GEN` / `_AFTER_FACTORY` are a stop-gap until v0.46.1 ships first-party transformers / vLLM generator factories. (2) `#70` GGUF and `#72` AWQ/GPTQ manual QA smokes remain pending — require CUDA + llama.cpp build; recipes scripted in `tests/qa/v053_qa.md`. (3) BNB-4bit merge + TorchAO PTQ live happy-path is mock-covered only — CPU-only CI cannot execute the real BNB / torchao kernels. (4) `_prepare_calibration_text` accepts JSONL with `text` / `prompt` / `content` aliases + raw text fallback; other formats (parquet / markdown) are out of scope. (5) Cache key truncates `base_sha` to 16 hex chars at the call site (collision probability ≈ 1-in-2³² across ~4 billion entries). (6) Pre-quantized detection is heuristic — name regex + local `config.json` probe; HF Hub repo IDs without local download fall back to name-only matching. (7) `enforce_under_cwd_and_no_symlink` checks only the leaf path; deeper traversal relies on the per-file leaf check at each site. (v0.53.1)
|
|
150
154
|
- **v0.53.0 — Quant Menu II (UD GGUFs + KV cache + NVFP4 + LF parity + save formats)**: 6 schema-only Parts; live wiring deferred to v0.53.1. Every new validator follows the project's established hardening policy: closed allowlists (`UD_GGUF_FORMATS`, `IQ_GGUF_FORMATS`, `APPLE_ARM_GGUF_FORMATS`, `KV_CACHE_TYPES`, `MERGE_SAVE_FORMATS`, `TORCHAO_PTQ_SCHEMES`) as `frozenset` so registries cannot be mutated; `_GGUF_METADATA` / `_KV_CACHE_METADATA` / `_MERGE_METADATA` / `_TORCHAO_METADATA` wrapped in `MappingProxyType`; `_LOWER_INDEX` for GGUF lookup is also `MappingProxyType`-wrapped (replaces O(N) walk with O(1) lookup — code-review MEDIUM fix). All string validators reject non-string / bool / empty / null-byte / oversize with case-insensitive normalisation (matches v0.41.0 `validate_optimizer_name` / v0.51.0 `validate_hub_name` policy); `validate_torchao_scheme` is INTENTIONALLY case-sensitive (PyTorch class names — `torchao.quantize_` looks them up by exact name) with the asymmetry documented at both validators (security-review LOW fix). `validate_calibration_data_path` + `validate_quant_config_path` are shape-only at this release; their docstrings name the exact controls a v0.53.1 CLI dispatch contributor MUST add (`os.path.realpath` + `os.path.commonpath` cwd containment, `os.lstat` + `stat.S_ISLNK` symlink rejection before `open()`, existence check, `yaml.safe_load`-only for quant configs) — closes the security-review MEDIUM "documentation gap at trust boundary" finding. SoupConfig cross-validators: `_validate_fp8_attention_compat` (requires `quantization_aware='fp8'` BEFORE the MLX gate so the more actionable error fires first — code-review MEDIUM fix); `_validate_nvfp4_compat` (non-MLX + `modality='text'`; Blackwell SM ≥ 12.0 runtime check fires at trainer construction); `_validate_unsloth_bnb_4bit_compat` (requires `backend='unsloth'` + `quantization='4bit'`); `_validate_bnb_4bit_double_quant` (requires `quantization='4bit'` — rejects `none`/`8bit`/Quant-Menu); `_validate_llm_int8_alias` (asserts `quantization='8bit'`, deliberately disjoint from v0.41.0 `load_in_8bit` aliasing); `_validate_quantize_ref_reward` (extended ref-task allowlist `{dpo, ipo, simpo, orpo, bco, kto, preference, grpo, ppo}` per code-review HIGH fix — first-cut omitted grpo + kto + ppo which all have reference policies); `_validate_kv_cache_type_supported` (only `fp8` gated to non-MLX in v0.53.0; q8_0/bf16/f16 pass-through documented at validator site so v0.53.1 contributor sees the gate immediately). `requires_hopper` reads from `_KV_CACHE_METADATA` spec — single source of truth so adding a Hopper-only type means flipping the spec field only (code-review MEDIUM fix). All 7 new bool fields share `_validate_v053_bool_fields` `field_validator(mode='before')` that rejects bool-as-int with explicit `TypeError("v0.53.0 flag must be bool")` and passes `None` through to Pydantic's `default=False` rather than silently coercing it (python-review MEDIUM fix — `fp8_attention: null` in YAML now surfaces as a "valid boolean" ValidationError instead of masquerading as `False`). Known limitations: (1) Every live wiring is deferred to v0.53.1 — `export_advanced_gguf`, `apply_kv_cache_type`, `apply_fp8_attention`, `apply_nvfp4`, `merge_4bit`, `export_torchao` all raise `NotImplementedError` with explicit `v0.53.1` markers. (2) `validate_calibration_data_path` + `validate_quant_config_path` are shape-only this release; CLI dispatch in v0.53.1 MUST add cwd-containment + TOCTOU symlink rejection. (3) `kv_cache_type` MLX permissive policy: only `fp8` is rejected, the other three pass-through; v0.53.1 may narrow further. (4) Hopper SM-capability check is runtime-only — schema accepts `kv_cache_type='fp8'` + `fp8_attention=true` without GPU probe. (5) NVFP4 + Blackwell (SM ≥ 12.0) check is runtime-only. (6) `bnb_4bit_use_double_quant` only gated against `quantization`, not against `quantization_aware` — the latter combination is already rejected by v0.28.0 Quant-Menu + QAT cross-validator. (7) `llm_int8` is an assertion not an aliaser — diverges from v0.41.0 `load_in_8bit` design on purpose. (v0.53.0)
|
|
151
155
|
- **v0.52.0 — Modality II (TTS + Distillation + BitNet + EBFT-GDPO + MoE quant + reasoning_effort)**: 7 schema-only Parts; live trainer / loss / export wiring deferred to v0.52.1. Every new validator follows the project's established hardening policy: closed allowlist (`SUPPORTED_TTS_FAMILIES`, `CLASSIFIER_TASKS`, `DIVERGENCES`, `BITNET_QUANT_FORMATS`, `BITNET_EXPORT_FORMATS`, `EBFT_VARIANTS`, `GDPO_VARIANTS`, `MOE_EXPERT_QUANT_FORMATS`, `REASONING_EFFORT_LEVELS`, per-family `_FAMILY_EMOTIONS`) wrapped in `frozenset` / `MappingProxyType` so registries cannot be mutated at runtime; `validate_*` helpers reject non-string / bool / empty / null-byte / oversize / unknown inputs with case-insensitive normalisation (matches v0.41.0 `validate_optimizer_name` / v0.50.0 `grpo_variant` / v0.51.0 `hub` policy); float validators (`validate_distill_temperature`, `validate_ebft_temperature`) gate on `math.isfinite` to reject NaN AND `±inf` (matches v0.32.0 `save_lr_finder_report` policy). `field_validator(mode="before")` on `num_labels` (security-review HIGH fix) rejects `bool` before Pydantic's `ge=1` coercion silently treats `True` as `1`. Field validator on `reasoning_effort` routes through the shared `validate_reasoning_effort` helper so the schema and runtime validator agree on what's accepted (security-review MEDIUM fix). SoupConfig cross-validators: `_validate_tts_compat` (requires `task='tts'` + `modality='audio_out'` + non-MLX backend; per-family emotion allowlist via `_FAMILY_EMOTIONS`), `_validate_classifier_compat` (with lazy-import early-return — code-review HIGH fix — so SFT hot path doesn't pay import cost; requires `num_labels` on classifier tasks; rejects classifier-only fields outside the task family with named offenders), `_validate_distill_compat` (requires `teacher_model` when `task='distill'`; rejects distill-only fields outside the task), `_validate_bitnet_compat` (gates to non-MLX + text-modality + task ∈ {sft, pretrain, dpo}), `_validate_ebft_compat` + `_validate_gdpo_compat` (task-family gates), `_validate_moe_expert_quant_compat` (requires `moe_lora=true` to prevent silent no-op), `_validate_reasoning_effort_task_gate` (code-review HIGH fix — rejects `reasoning_effort` + `train_on_eot` outside the SFT-family task set with named offenders; mirrors v0.50.0 GRPO stability task-gate policy). Public `DIVERGENCES` frozenset is derived from `_DIVERGENCE_ALIASES` so adding a new alias updates both the accepted-input set and the error message in lockstep (review fix LOW). `validate_bitnet_export` enforces a closed-allowlist canonical form for `soup export --format <bitnet|tq1_0>`, both of which are CLI-registered with a yellow advisory panel + `Exit(0)` stub (no artifact written until v0.52.1 — the format flag is accepted so existing scripts pinned to v0.52.0 will not break). 6 new YAML recipes appended (5 TTS + Falcon-E BitNet) — every entry is exercised by `tests/test_v0520.py` for `load_config_from_string` round-trip + `_no_null_or_whitespace` model-id check (mirrors v0.51.0 review-fix LOW). Known limitations: (1) 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_quant` all raise `NotImplementedError` with explicit `v0.52.1` markers; schema accepts every new task / quant / variant + the CLI stub for `soup export --format bitnet/tq1_0` prints a deferred-advisory panel and exits 0. (2) `modality='audio_out'` accepted on non-TTS tasks — design choice this release so future audio-output tasks (ASR / V2A) can reuse it; today's runtime trainer dispatch must check `task == 'tts'` to avoid silent routing into the deferred TTS path. (3) Oute emotion allowlist is a tight 6-entry subset (neutral / happy / sad / angry / calm / excited); operators wanting custom emotions will need a v0.52.1 patch to extend `OUTE_EMOTIONS`. (4) `is_bitnet_model` is best-effort heuristic over name prefixes (`bitnet`, `falcon-e`, `1bitllm`, `onebit`); a BitNet checkpoint published under an org without any of those prefixes returns False. This is detection, not gating — the trainer wrapper (v0.52.1) loads the model regardless of the heuristic. (5) `quantization='bitnet_1.58'` gated to task ∈ {sft, pretrain, dpo} — extending to GRPO / PPO / RewardModel requires upstream onebitllms RL kernels not yet shipped. (v0.52.0)
|
|
152
156
|
- **v0.51.0 — Model Catalog Expansion + Alternative Model Hubs**: 5 release Parts. New `soup_cli/utils/hubs.py` ships closed allowlist `SUPPORTED_HUBS = frozenset({hf, modelscope, modelers})` + three `MappingProxyType`-wrapped registries (`_HUB_DEFAULT_ENDPOINTS` / `_HUB_ENDPOINT_ENV` / `_HUB_PACKAGE`) so the registry cannot be mutated at runtime (matches v0.36.0 `_REGISTRY` policy). `validate_hub_name` rejects non-string / bool / empty / null-byte / >32-char / unknown with case-insensitive normalisation (matches v0.41.0 `validate_optimizer_name` policy). `validate_hub_endpoint` is the SSRF kernel — full parity with v0.29.0 `utils/hf.resolve_endpoint`: scheme allowlist (`http`/`https` only), null-byte rejection, **control-character / CRLF rejection** added in v0.51.0 as a defence-in-depth review fix (defends against URL-as-HTTP-header injection if the URL ever flows into a raw HTTP client), `0.0.0.0` explicitly rejected, plain HTTP only for loopback `{localhost, 127.0.0.1, ::1}`, RFC1918 / link-local / cloud-metadata IPs (169.254.x) rejected via `ipaddress.ip_address` for plain HTTP. `resolve_endpoint(hub, *, env=None)` looks up the per-hub env var (`HF_ENDPOINT` / `MODELSCOPE_ENDPOINT` / `MODELERS_ENDPOINT`) and runs the override through `validate_hub_endpoint`; default endpoints are baked-in HTTPS URLs. `is_hf` rejects `bool` explicitly (review fix HIGH — bool is a subclass of int and would have silently fallen through `hub.lower() == "hf"` → `False`, which happens to be correct by accident but violates the contract; matches v0.30.0 `Candidate` / v0.34.0 `estimate_run_cost_usd` policy). `TrainingConfig.hub: Literal["hf","modelscope","modelers"]` field gets a `field_validator(mode="before")` `_normalize_hub` that delegates to `validate_hub_name` so `hub: HF` in YAML normalises to `"hf"` (review fix HIGH — first-cut had Pydantic Literal exact-match while `validate_hub_name` was case-insensitive, breaking the v0.41.0 `validate_optimizer_name` / v0.50.0 `grpo_variant` / `rollout_backend` policy of agreement between schema and shared validator). SoupConfig `_validate_hub_supported` cross-validator rejects `hub != 'hf'` on `backend == 'mlx'` with a distinct error message (review fix HIGH — `mlx-lm` only downloads from HF Hub; without this gate a `backend: mlx` + `hub: modelscope` config would silently pass schema load and fail at runtime with a confusing `mlx-lm` error). 26 new YAML recipes appended to `soup_cli/recipes/catalog.py` — every entry is exercised by `tests/test_v0510.py` via `load_config_from_string` round-trip + `yaml.safe_load` (no Python tags / no template injection / no credential leak in the YAML strings) + a `_no_null_or_whitespace` model-id check that rejects empty path components (review fix LOW — first-cut allowed `"/name"` leading-slash IDs to pass). Two non-`<N>B` `size` strings (`"image"` / `"ocr"` / `"moe"` / `"medium"`) were normalised to `"N/A"` (review fix MEDIUM — `search_recipes(size=…)` would silently miss those entries, and the autopilot VRAM estimator could not parse them). Known limitations: (1) Live downloader / uploader / push integration deferred to v0.51.1 — `TrainingConfig.hub` schema lock-in ships now (Literal accept + MLX cross-validator + case-normalisation), but `soup data download --hub modelscope` and `soup push --hub modelers` still route through the existing HF Hub code path; the actual `modelscope-sdk` / `openmind-hub` adapters are the v0.51.1 deliverable. Same stub-then-live pattern as v0.27.0 MII / v0.37.0 multipack / v0.50.0 GRPO Plus. (2) Speculative / aspirational `base` model IDs in some Part A/C recipes — the catalog ships entries for `openai/gpt-oss-{20,120}b`, `THUDM/glm-5`, `Qwen/Qwen-Image`, `deepseek-ai/DeepSeek-OCR`, `PaddlePaddle/PaddleOCR-VL`, `google/embeddinggemma-300m` so users have ready-made recipes the moment those repos go live (matches the plan's "match Unsloth's day-zero coverage" directive). Recipes for not-yet-published repos will surface a clear HF Hub 404 when the user runs `soup train --recipe <name>`. (3) DNS-resolved private hostnames not blocked — `validate_hub_endpoint` only rejects literal RFC1918 / link-local IP addresses; a hostname like `corp-proxy.internal` that DNS-resolves to a private IP is accepted at validation time (mirrors the v0.29.0 `HF_ENDPOINT` policy — DNS resolution is intentionally not performed in this local-tool threat model). (v0.51.0)
|
|
@@ -17,6 +17,8 @@ from soup_cli.autopilot.decisions import (
|
|
|
17
17
|
decide_performance_flags,
|
|
18
18
|
decide_quantization,
|
|
19
19
|
decide_task,
|
|
20
|
+
detect_prequantized_format,
|
|
21
|
+
detect_prequantized_format_from_path,
|
|
20
22
|
parse_gpu_budget,
|
|
21
23
|
)
|
|
22
24
|
from soup_cli.autopilot.generate_config import build_soup_config, write_yaml
|
|
@@ -37,6 +39,8 @@ __all__ = [
|
|
|
37
39
|
"decide_performance_flags",
|
|
38
40
|
"decide_quantization",
|
|
39
41
|
"decide_task",
|
|
42
|
+
"detect_prequantized_format",
|
|
43
|
+
"detect_prequantized_format_from_path",
|
|
40
44
|
"parse_gpu_budget",
|
|
41
45
|
"write_yaml",
|
|
42
46
|
]
|