mirror of
https://github.com/hanzoai/gym.git
synced 2026-09-30 22:37:59 +00:00
Rollouts go through a KV cache (prompt prefilled once per group, one decode step per token); cached logits match the full forward to 1e-4. GRPO runs end to end on Metal — a mixed group at step 5 gives reward 0.75, loss −0.032, gradient norm 1.19 — after the clipping reduction stopped going through f64, which Metal does not have. gym synth ports Data Designer's core: sampler, expression and LLM columns (text, structured, judge) generated per row in dependency order against any OpenAI-compatible endpoint, validators that drop or regenerate, jsonl or parquet out. gym trainjob is the Kubeflow TrainJob entry for the hosted fine-tuning API: the broker's env contract becomes a Config; METHOD=lora is served, qlora and full are refused by name. Dockerfile.cuda and image.yml build ghcr.io/hanzoai/gym on the forge runners. 84 tests. Co-authored-by: Hanzo Dev <[email protected]>
3.6 KiB
3.6 KiB
hanzo-gym
Rust trainer on hanzo-ml (candle fork, crates.io hanzo-ml / hanzo-nn).
Binary gym, lib gym. Standalone Cargo workspace ([workspace] in Cargo.toml
keeps it out of ~/work/hanzo's root workspace).
Shape
src/lib.rs— the contracts every module is written against:CausalLm(forward → logits,trainable_vars,save_adapter),Example,Batch(labels unshifted,IGNORE_INDEX= -100 at padding),Prompt(GRPO).src/config.rs— Axolotl-shaped YAML,deny_unknown_fields: a key this crate does not implement fails at load rather than being ignored.src/hub.rs— model files: local dir or Hugging Face repo via hf-hub.src/model/— LoRA (lora.rs), one trainable transformer for Qwen3 and Llama built from differentiable primitives only, PEFT adapter save/load/merge.src/data/— dataset sources (jsonl, json, parquet, HF datasets; HF split grammar), strategieschat_template/alpaca/completionwith Axolotl's label semantics,collate,load_promptsfor GRPO.src/train/— SFT loop: chunked masked CE, schedules, accumulation, clipping, AdamW, checkpoints;runpicks device/dtype and dispatches to GRPO.src/grpo/— port of hanzo-ml'shanzo-training/src/grpomath with a realLmPolicyoverCausalLm: rollouts throughforward_cached(prompt prefilled once per group, one decode step per token), differentiable scoring throughforward; verifiers (exact_match,numeric_match,format:<re>,length:<n>,http:<url>).src/synth/—gym synth: Data Designer-style dataset synthesis. Columns are samplers, Jinja expressions or LLM calls (text, structured, judge) run per row in dependency order against any OpenAI-compatible endpoint; validators drop or regenerate; rows stream to jsonl/parquet.src/trainjob.rs—gym trainjob: the Kubeflow TrainJob container entry. Reads the env contract from hanzoai/aicluster/finetune.go(BASE_MODEL, METHOD, TASK, DATASET_DIR, …) into aConfig; METHOD=lora only.Dockerfile.cuda+.hanzo/workflows/image.ymlbuildghcr.io/hanzoai/gym:<tag>on the forge runners.
Facts that shaped it
- hanzo-nn's fused
rms_norm,ropeand attention kernels have no backward; the model usesrms_norm_slow,rope_slow,softmax_last_dimand matmul. Cache/forward_cachedis the decode path; rows in a cached batch must have equal length (no padding mask there).- Metal has no f64: reduce norms and scalars through f32 tensors, never
to_dtype(F64). No QLoRA, full fine-tune, multi-GPU, DPO family, sample packing — rejected at config load. - KL in GRPO is against the pre-update policy of the step (adapter cannot be
disabled through
CausalLm), not the frozen base. - Hosted
/v1/ai/finetune/jobs(hanzoai/ai) submits a TrainJob against thehanzo-ft-{lora,qlora,full}ClusterTrainingRuntimes in~/work/hanzo-ml/trainer/manifests/base/runtimes/hanzo_finetune.yaml(imageghcr.io/hanzoai/finetune-runtime, Python). Pointinghanzo-ft-loraatghcr.io/hanzoai/gym:<tag>withCMD trainjobis the switch, once the forge has built the image (the repo needs a git.hanzo.ai mirror first). - Engine loads PEFT adapters at startup only (merged into weights);
/v1/models/unload+/reloadre-reads the same adapter path; it serveslogprobs. Engine-served rollouts would be adapter-to-path + reload per step.
Build / test
cargo test (CPU), --features metal or --features cuda for GPU. CI in
.hanzo/workflows/ci.yml (fmt, clippy -D warnings, tests; metal leg on
hanzo-build-macos-arm64). Publish: cargo publish as hanzo-gym.