Skip to content

v2-i1: Qwen3-0.6B controlled comparison + DeepSeek judge (ADR 0050) - #4

Merged
marzoukbaig14 merged 10 commits into
mainfrom
v2-i1/qwen3-0p6b
Jul 1, 2026
Merged

v2-i1: Qwen3-0.6B controlled comparison + DeepSeek judge (ADR 0050)#4
marzoukbaig14 merged 10 commits into
mainfrom
v2-i1/qwen3-0p6b

Conversation

@marzoukbaig14

Copy link
Copy Markdown
Owner

What

v2 iteration 1 (ADR 0049): re-run the v1 fine-tune + eval pipeline with exactly one variable changed — base model 1.7B → 0.6B. Recipe, dataset, grammar, prompt, 442-row strata sample, harness, and composite all frozen.

  • configs/qwen3-0.6b-lora-r16.yaml — copy of the 1.7B config, only the three model-identity fields changed (base id, hub_model_id, run_name); recipe byte-identical. scripts/train.slurm parameterized (default 0.6B).
  • GGUF pipelinemerge_adapter.py repointed to 0.6B; merge_convert_quantize.py (was a non-functional stub) implemented into a real merge→convert→quantize pipeline. Produced committed-gguf-0.6b (Q4_K_M).
  • train.py — checkpoint resume made config-driven (default off) after the first run crashed trying to resume 1.7B checkpoints into the 0.6B model.

Judge switch — ADR 0050

Gemini's prepaid credits depleted mid-eval, so the judge was switched to DeepSeek (deepseek-chat, OpenAI-compatible, pay-as-you-go). New backend judge_deepseek.py reuses the frozen rubric unchanged; run_eval.py gains an additive --backend deepseek. To stay consistent under one judge, all four arms were re-judged on DeepSeek (0.6B + the v1 1.7B candidate files); the old Gemini numbers are a superseded reference. Full findings in docs/eval/FINDINGS_v2_i1.md, raw evidence in analysis/results/ (ADR 0046).

Headline result

The fine-tune rescues 0.6B feat-collapse decisively (type-correctness 0.296 → 0.726; prefix accuracy 0.154 → 0.601, above the 0.489 floor; feat-share of generations 86.7% → 9.7%). The 0.6B fine-tune lands within ~4–5 pts of the 1.7B fine-tune on type/faithfulness/completeness/prefix and near-identical graded mean (2.094 vs 2.139); the capacity gap concentrates in specificity (0.545 vs 0.667). DeepSeek judge vs human (n=50): agreement ≥ Gemini on every axis. Total judge cost ~$1.2 est.

🤖 Generated with Claude Code


Generated by Claude Code

claude added 10 commits June 27, 2026 20:10
Add configs/qwen3-0.6b-lora-r16.yaml as a copy of the 1.7B config with only
the three model-identity fields changed: base model id (Qwen/Qwen3-0.6B),
hub_model_id (committed-qwen3-0.6b-lora), and run_name. The recipe (LoRA
rank/alpha, lr, sequence length, epochs, batch size, grad-accum) is left
byte-identical so the v1->v2-i1 comparison is attributable to base-model
capacity alone, per ADR 0049.

Parameterize scripts/train.slurm to take the config path as its first arg,
defaulting to the 0.6B config, so the same script reproduces either run.

Gate 0 verified: Qwen3-0.6B and Qwen3-1.7B tokenizers are identical
(vocab_equal and ids_equal both True), so committed-train is reused unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyxW8LpuJuQRCzdnfYp8Xo
The first 0.6B run crashed because train.py hardcoded
resume_from_checkpoint=True while the 0.6B config's output_dir still pointed at
outputs/qwen3-1.7b-lora-r16, so the trainer tried to resume 1.7B checkpoints
into the 0.6B model.

- configs/qwen3-0.6b-lora-r16.yaml: output_dir -> outputs/qwen3-0.6b-lora-r16,
  and add io.resume_from_checkpoint (default false).
- train.py: read io.resume_from_checkpoint (default False via .get, so the
  frozen 1.7B config is unaffected and also starts clean). A fresh run now
  starts from scratch; an interrupted run can resume by setting the flag true.

W&B project is unchanged: train.py still pins WANDB_PROJECT=committed before
the wandb integration loads, matching the slurm export.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyxW8LpuJuQRCzdnfYp8Xo
Phase 3 prep. merge_adapter.py: base -> Qwen/Qwen3-0.6B, adapter ->
committed-qwen3-0.6b-lora, output under gitignored models/.

merge_convert_quantize.py was a non-functional scaffold (every stage raised
NotImplementedError). Implemented it as a runnable merge -> convert -> quantize
pipeline that shells out to a llama.cpp checkout (convert_hf_to_gguf.py +
llama-quantize), defaulting to the 0.6B adapter and Q4_K_M. A --no-adapter mode
converts the bare base model for the eval baseline arm.

Produced and pushed (private) marzoukbaig14/committed-gguf-0.6b:
committed-0.6b-{finetuned,baseline}-Q4_K_M.gguf. Sanity generation through the
frozen engine + GBNF grammar yields valid Conventional Commits from both.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyxW8LpuJuQRCzdnfYp8Xo
…tial)

Generation (both arms, 442 each over the frozen strata ids) complete. Gemini
judge: fine-tune arm fully judged (442/442, $0.8182), report written. Baseline
arm reached only 35/442 before Gemini's daily request quota was exhausted; the
harness stopped gracefully and the log is resumable. Committing completed
evidence now (ephemeral sandbox); the baseline judge resumes once quota resets.

Eval generation reproduced v1's no-guard path (the looks_like_diff guard added
later to engine.generate() rejects 1 of the 442 real rows, id 350); bypassed in
the eval driver only, engine.py unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyxW8LpuJuQRCzdnfYp8Xo
Mirror the v1 .gitignore allowlist convention (ADR 0046) for the 0.6B
candidates and judge logs. Fine-tune judge log is complete (442); baseline
judge log is the resumable partial (35/442, pending Gemini daily-quota reset).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyxW8LpuJuQRCzdnfYp8Xo
Gemini judge credits depleted mid-eval (prepaid balance, not a rate cap) and the
account has a $10 minimum top-up. Switch the v2-i1 judge to DeepSeek
(pay-as-you-go, ~10-50x cheaper, OpenAI-compatible).

- src/committed/eval/judge_deepseek.py: new backend, model deepseek-chat, mirrors
  judge_gemini.py exactly (same JudgeResult schema, same JSONL log contract, same
  resumable/graceful-stop behavior; BalanceExhausted is the 402 analogue of
  DailyQuotaExceeded). Rubric (judge_prompt.py) imported UNCHANGED; a JSON-format
  envelope is added in-backend for DeepSeek's schemaless json_object mode, with
  validation + retry.
- run_eval.py: additive --backend deepseek (choices/import/rpm); metrics,
  composite, sample, prompt, grammar all untouched.
- ADR 0050: records the switch, the comparability cost (v1 Gemini numbers become a
  superseded reference; all four arms re-judged on DeepSeek for one-judge
  consistency), and the human-validation re-check plan. Regenerated DECISION_LOG.md
  + decision-tree.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyxW8LpuJuQRCzdnfYp8Xo
First arm of the DeepSeek re-judge (ADR 0050) complete: 0.6B baseline, 442/442,
$0.32. type_correctness pass 0.296, conjunctive (deploy) 0.101 — the feat-collapse
confirmed by the judge. Remaining arms (0.6B fine-tune, 1.7B baseline+fine-tune)
still judging in the background; their evidence lands as each completes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyxW8LpuJuQRCzdnfYp8Xo
0.6B fine-tune re-judged on DeepSeek (442/442, $0.31). DeepSeek-judged 0.6B lift
baseline->fine-tune: type-correct pass 0.296->0.726, prefix acc 0.154->0.601
(above the 0.489 floor), graded 0.777->2.094 — the feat-collapse rescue,
judge-confirmed.

judge_deepseek.py robustness: at temperature=0 a malformed-JSON generation
repeated identically on every retry and one bad example crashed a whole arm
(hit on the 1.7B baseline). Fix: escalate temperature on JSON-parse retries so a
resample can differ, strip stray code fences, and skip a persistently-bad
example (logged) instead of aborting the batch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyxW8LpuJuQRCzdnfYp8Xo
All four arms now DeepSeek-judged (442 each, 0 skipped). Adds the 1.7B baseline
(+ human validation) and 1.7B fine-tune evidence, and the comparison report
docs/eval/FINDINGS_v2_i1.md.

Headline: the fine-tune rescues 0.6B feat-collapse decisively (type_correctness
0.296->0.726; prefix acc 0.154->0.601, above the 0.489 floor; feat-share of
generations 86.7%->9.7%). The 0.6B fine-tune lands within ~4-5 pts of the 1.7B
fine-tune on type/faithfulness/completeness/prefix and near-identical graded mean
(2.094 vs 2.139); the capacity gap is concentrated in specificity (0.545 vs
0.667) and the conjunctive all-pass it caps.

DeepSeek judge vs human (n=50): agreement >= Gemini on every axis
(type/faith/compl kappa 0.56-0.61; specificity weakest at 0.34). Total judge
cost ~$1.2 est.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyxW8LpuJuQRCzdnfYp8Xo
… var)

Drop the unused `openai.APIError` import (F401) and the unused binding in
`except (RateLimitError, APIConnectionError) as e` (F841). No behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyxW8LpuJuQRCzdnfYp8Xo
@marzoukbaig14
marzoukbaig14 merged commit 023f0ab into main Jul 1, 2026
1 check passed
@marzoukbaig14
marzoukbaig14 deleted the v2-i1/qwen3-0p6b branch July 1, 2026 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants