Commit Graph

5 Commits

Author SHA1 Message Date
Alpamys a1463bf716 feat(v0.71.6): live build runner + Magpie generator + 2PL/3PL IRT + augment fix
Lift the v0.69.0 deferred stubs to live + extend IRT + fix a real bug:

- #231 soup build materialises (5 built-in transforms, table/view/incremental
  with SQLite-tracked config-fingerprint cache key, atomic JSONL, --output-dir)
- #232 soup data gen-magpie live (ollama/vllm raw-completion harvest; anthropic
  rejected; optional --quality-filter; dedup-before-response)
- #167 tokenizer-aware memorization probe (sub-word/BPE overlap, library-only)
- #213 soup eval irt-subset --model 2pl|3pl (joint coordinate-ascent MLE)
- #75 fix soup data augment --provider ollama|vllm ImportError + QA log

Security: validate_ollama_url/validate_vllm_url reject 0.0.0.0; augment output
containment+symlink reject; magpie response-body cap.

Tests 12581 -> 12703 (+122 in tests/test_v0716.py). Full suite green, ruff clean.
2026-06-02 22:06:12 +05:00
Alpamys 514761c89a feat(env,lock,serve,eval): v0.71.1 — quick wins + wiring (7 closures)
Closes #195 #210 #214 #224 #230 #233 #209.

- soup env fix: print-only install-plan renderer from soup-env.lock
  (uv-pip / requirements; non-pip entries surfaced as comments). (#209)
- soup lock write --env-lock: auto-derive --env-hash from soup-env.lock
  via new compute_env_hash (excludes created_at). (#224)
- soup serve --record-thumbs <db>: capture thumbs-up/down into the
  local-RL SQLite + POST /v1/thumbs (transformers backend). (#230)
- Judge-calibration persistence: JudgeCalibrationReport.to_dict +
  write/load_judge_calibration + judge_calibration registry kind; load
  re-validates the frozen dataclass with cwd/symlink containment. (#214)
- soup completions: introspect a base model's real LoRA target modules
  (config-only AutoConfig, local_files_only, never networks/raises). (#210)
- Bundled MUSE + WMDP unlearning eval fixtures; WMDP forget rows ship
  REDACTED (Soup never bundles verbatim hazardous content). (#195)
- build_dag.validate_build_source: cwd-containment + symlink rejection. (#233)

Review-fix hardening (consolidated python+code+security+tdd, 0 CRIT/0 HIGH):
load_judge_calibration containment + friendly missing-field ValueError;
serve thumbs success-print escape; env_fix --output Optional[str];
empty --env-hash auto-derives; render_install_plan PEP 440 docstring note.

Tests: 12071 -> 12134 (12044 passed, 90 skipped, 2 deselected).
2026-06-01 14:12:30 +05:00
Alpamys 06d8ea7cc5 chore: migrate to src-layout
Move soup_cli/ -> src/soup_cli/ (history preserved via git mv). src-layout
forces the test suite to import the installed package instead of the
repo-root source tree, surfacing packaging bugs that flat-layout masks —
e.g. the v0.53.8 double-shipped-fixtures regression, invisible because
`pytest tests/` imports ./soup_cli directly and never from the wheel.

- pyproject: packages = ["src/soup_cli"]; artifacts globs -> src/soup_cli/...
  The import name is unchanged, so the `soup` entry point, --cov=soup_cli,
  and report_to/module-path strings stay `soup_cli`.
- CI / ownership: ruff lint path (ci.yml), recipe-validation `paths:` filters,
  CODEOWNERS patterns, and the PR-template checklist all repointed to
  src/soup_cli/.
- tests: source-grep regression tests that read package files by repo-relative
  path repointed to src/soup_cli/ (64 files; 170 path literals). Lines pushed
  over 100 chars by the prefix were wrapped to keep ruff E501 clean. Module
  references (`import soup_cli`, `-m soup_cli`, mock.patch("soup_cli.x")) and
  the `--cov=soup_cli` coverage target are deliberately unchanged.
- docs: AGENTS.md + CONTRIBUTING.md structure tree and lint commands.

Verified locally: ruff clean (src/soup_cli + tests); `import soup_cli`
resolves to src/soup_cli/__init__.py; built wheel ships
soup_cli/data/_fixtures/*.jsonl (10 files, no duplicates, no src/ prefix);
3174 tests across every touched test file pass. Packaging-only — no version bump.
2026-05-31 12:40:06 +05:00
Alpamys 74edac95d1 feat(v0.70.0): Loop Hardening — reward-hacking + ULD + MiniLLM + RL ckpt + iterative DPO + echo-trap
Six-part schema-only release shipping the axis-3 + axis-13 training-loop
hardening. Every live trainer-callback / math kernel is deferred to v0.70.1
per the project's established stub-then-live cadence
(matches v0.50.0 / v0.62.0 / v0.69.0).

Part A — Reward-hacking detector (soup_cli/utils/reward_hacking.py):
  InfoRM Cluster-Separation Index (Wang et al. 2024 arXiv:2402.09345) +
  RM-ensemble pairwise variance + OK/WARN/HACK taxonomy at 0.10/0.30
  thresholds. TrainingConfig.reward_hack_detector / reward_hack_halt;
  SoupConfig task-gate (grpo/ppo only, mlx rejected, halt requires detector).

Part B — Cross-tokenizer ULD (soup_cli/utils/uld.py):
  Universal Logit Distillation (Boizard et al. 2024 arXiv:2402.12030).
  wasserstein + topk_align allowlist; ULDConfig frozen with topk/strategy
  cross-validators; vocab-size cap 262144. Schema-gated to task='distill'.

Part C — MiniLLM reverse-KL on-policy distillation (soup_cli/utils/minillm.py):
  Gu et al. 2024 (arXiv:2306.08543) — bundles teacher-mixed sampling +
  length-norm + pretrain-loss anchor stability tricks. Anchor weight↔path
  mutual-requirement cross-validators reject silent no-op combos.

Part D — Mid-epoch RL checkpoint (soup_cli/utils/rl_checkpoint.py):
  Optimizer-state serialization TorchTune explicitly punts. RLCheckpointConfig
  + RLCheckpointState frozen + JSON-serialisable manifest. RL-task gate.

Part E — Iterative DPO loop driver (soup_cli/utils/iterative_dpo.py +
  commands/iterative_dpo.py): sample → RM-score → re-pair → retrain over
  N rounds. IterativeDPOPlan with consecutive-round_index invariant.
  New `soup iterative-dpo` CLI; --plan-only live, runner deferred.

Part F — RAGEN echo-trap detector (soup_cli/utils/echo_trap.py):
  Zhu et al. 2025 (arXiv:2504.14437) — n-gram trajectory-repetition kernels
  with DoS caps (max 32 ngram_n, 1M tokens, 100k trajectories). OK/WARN/TRAP
  at 0.30/0.60. Composes with v0.53.11 #127 GRPOStabilityCallback.

Cross-cutting hardening:
- 6 new util modules + 1 new top-level CLI + 11 new TrainingConfig fields
  + 6 new SoupConfig cross-validators + 3 new field validators
- Closed allowlists (frozenset) + MappingProxyType registries everywhere
- Frozen dataclasses with post-init validation on every public record
- Bool-as-int rejection on every numeric (matches v0.30.0 / v0.41.0 policy)
- math.isfinite NaN/Inf rejection on every float
- Null-byte rejection + per-field length caps on every string
- No top-level torch imports (4 source-grep regression tests)
- Deferred-live stubs validate inputs FIRST then raise NotImplementedError
  with explicit v0.70.1 marker
- CLI exit codes split: 2 = validation rejection, 3 = deferred-live

Test count: 11487 → 11824 (+337 net). 12-invariant self-review against
the full project checklist (closed allowlists, frozen dataclasses,
MappingProxyType, bool-as-int rejection, finite check, null-byte, length
caps, no top-level torch, TypeError/ValueError split, deferred-live,
tuples-not-lists, CLI exit codes) all green across all 6 Parts.

Manual CPU smokes (Step 6): every CLI happy + failure path exercised —
`soup iterative-dpo --plan-only` 3-round plan rendered end-to-end with
per-round artifacts; 5 happy-path YAML loads + 5 failure-mode rejections
across reward_hack / uld / minillm / rl_checkpoint / echo_trap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 17:17:03 +05:00
Alpamys 49943a5af6 feat(v0.69.0): Data Engineering Pro — soup build + expect + gen-magpie + persona-mix + brain-rot
5 parts shipping axis-2 (dbt-for-SFT) + axis-13 (data ops):

- soup build — dbt-for-SFT DAG with refs / incremental materialization /
  content-hash row-diff kernel (run_build live runner deferred → v0.69.1)
- soup expect <data> <suite> — LIVE expectations suite: PII / token-length /
  refusal / chosen-vs-rejected judge; exit 3 on suite failure
- soup data gen-magpie — Magpie synthetic generator plan (live → v0.69.1)
- soup data persona-mix — Persona-Hub × style sampler with bundled 12×5 set,
  atomic JSONL write (LIVE)
- soup data brain-rot — arXiv 2510.13928 detector with --strict CI gate,
  worst-signal composite (LIVE)

Centralised TOCTOU defence behind utils/paths.enforce_under_cwd_and_no_symlink
in build_dag / expectations / expect.py (code-review CRIT — replaces 3
duplicate os.lstat + S_ISLNK + realpath + is_under_cwd blocks). DoS caps on
every new JSONL loader (brain-rot 1 GiB + 1M rows; persona-mix 100 MiB + 100k
entries). persona-mix --output TOCTOU symlink rejection. magpie quality_filter
validator + expectations._dispatch_expectation raw-args pass-through (no
int/float coercion bypass). BuildModel seed/derived cross-validator rejects
ambiguous shapes at schema load.

Review-fix coverage across 4 waves (security + code + python + TDD):
1 CRITICAL + 4 HIGH + 5 MEDIUM + 4 LOW.

Test count: 11225 → 11487 (+262 net across 5 new files).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 16:00:15 +05:00