You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
CONVERT (E6-4): fuse --dequantize (28GB bf16) -> convert_hf_to_gguf f16 (30GB)
-> llama-quantize Q5_K_M (11GB candidate). E6-14: dequantize required (4bit
fused model can't GGUF-convert directly). GATE (E6-3): candidate served on
side-port :18102 (/health 200), run_benchmark makes real calls (1428 server
call lines, non-zero — passes the no-zero-call discipline). All four pipeline
stages (export->curate->train->convert->gate) now validated end-to-end with
real production data. Remaining: wire the proven commands into the controller.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| E6-1 |`execPythonStage` uses `FT_LOOP_PYTHON_BIN` default `python3` (system) — the training toolchain (`mlx_lm`) lives in `neural/.venv`; a real run needs the venv interpreter. |`ftloop/controller.go`|**[FIXED]**`resolvePython()` prefers `neural/.venv/bin/python`. **Live-validated:** curate ran the module (error was its usage message). |
14
14
| E6-2 | One `RepoDir` for all stages, but `python -m training.X` needs cwd `neural/` while `python -m neural.benchmarks.X` needs the repo root. |`ftloop/controller.go::execPythonStage`|**[FIXED]**`stageDir()` per-stage cwd. **Live-validated** (module resolved from `neural/`). |
15
-
| E6-3 | Stage arg-sets are placeholders. Real: curate needs `--spec/--input-dir/--output-dir/--version`; train needs `--tier/--mode/--base-model/--expected-sha256/--dataset/--adapter-path/--rank/--alpha/--n-epochs`; gate needs `--config/--out/--model`. **Live-confirmed:** curate failed exit-2 on the missing required args (the FAIL path). |`ftloop/controller.go`|**[curate + train VALIDATED]** convert/gate + controller wiring [6b-continuation]|
16
-
| E6-4 | No MLX→GGUF conversion stage between train and gate (the run_record rule: candidate evals always use the GGUF form). | controller pipeline |[6b-followup] add a convert stage|
15
+
| E6-3 | Stage arg-sets are placeholders. Real: curate needs `--spec/--input-dir/--output-dir/--version`; train needs `--tier/--mode/--base-model/--expected-sha256/--dataset/--adapter-path/--rank/--alpha/--n-epochs`; gate needs `--config/--out/--model`. **Live-confirmed:** curate failed exit-2 on the missing required args (the FAIL path). |`ftloop/controller.go`|**[curate + train + convert + gate ALL VALIDATED]** controller wiring [6b-continuation]|
16
+
| E6-4 | No MLX→GGUF conversion stage between train and gate (the run_record rule: candidate evals always use the GGUF form). | controller pipeline |**[VALIDATED]** fuse --dequantize→convert_hf_to_gguf→llama-quantize Q5_K_M produces the 11GB candidate; gate serves it on a side-port + run_benchmark makes real calls|
17
17
| E6-5 | Curate `--input-dir` (exported JSONL) has no producer in the loop — the controller must run `mdemg data export` (or read TSDB) to materialize the curate input. | controller pipeline |**[SOLVED]**`mdemg data export --tables llm_interactions[,…] --since … --output <tar>` → extract `llm_interactions.jsonl` into `<input-dir>/`. The export schema matches `quality_filter`'s `TEXT_FIELDS` exactly. |
18
18
19
19
| E6-8 |**Train base-model SHA pin is STALE (drift-guard rot).**`train_ft.SPRINT_C_CONFIG_SHA = cdc167566e…` but upstream `mlx-community/Qwen3-14B-4bit``config.json` is now `a54ec18f…` (re-published since the pin). A real retrain **drift-aborts**. Verified: the current upstream config is **byte-identical** to the local production model's config (`qwen3-14b-mdemg-v1`), so the base is functionally the production base; the pin just rotted. Same class as the run_record's "configs rot at cutovers" — now for the base-model pin. |`neural/training/train_ft.py:83`; `expert_selection.py:10`|**[decision]** update the pin to `a54ec18f…` (safe — identical to production) **or** pin to a specific HF revision. A deliberate provenance call (the pin is a drift-guard) — surfaced, not silently bypassed. |
arg-sets + the train→convert→gate artifact chain) — the focused 6b continuation.
63
63
64
64
| E6-13 |**Training on the dev box is very slow + degrades the live server.** With the mdemg server + neo4j running, mlx_lm.lora hit **~52 s/iter** (It/sec 0.019), peak 23.6 GB, and starved llama-server `:8102` → HIGH `jiminy.evaluate_llm` timeouts. A full 1-epoch run on 4660 rows (1165 iters) would be ~17 h at this rate; even a 50-iter subset is ~43 min. The controller's `Quiesce` pauses RSIC LLM fan-out but the server+neo4j load remains. | live (M5 Max) |**[viability]** a real retrain wants the box mostly idle (or dedicated/off-peak); consider the loop scheduling retrains during quiet windows, and/or a smaller per-cycle row budget. Pipeline-mechanics validation uses a tiny subset (quality irrelevant for convert/gate). |
65
+
66
+
| E6-14 |**Convert must dequantize first.**`convert_hf_to_gguf.py` on a 4bit-fused MLX model fails (`Can not map tensor 'model.embed_tokens.biases'` — MLX 4bit quant tensors). The convert stage MUST `mlx_lm.fuse --dequantize` → bf16 HF safetensors → `convert_hf_to_gguf --outtype f16` → `llama-quantize Q5_K_M` (the CLAUDE.md path; ~85GB transient). | convert stage |[6b-continuation] wire the 3-step dequantize→gguf→quantize convert; confirmed required |
0 commit comments