File size: 15,025 Bytes
dfb775d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | # YAML schema reference
mindxtrain takes one YAML per training run, validated against
`mindxtrain.config.schema.XTrainConfig` (Pydantic v2). The canonical hero
config lives at [`examples/demo_qwen3_8b_sft.yaml`](../examples/demo_qwen3_8b_sft.yaml).
Every recipe under `mindxtrain/train/recipes/` round-trips through this schema
(proven by `tests/test_config_schema.py::test_all_recipes_validate`).
Source of truth: [`mindxtrain/config/schema.py`](../mindxtrain/config/schema.py).
When the schema changes, update this doc.
> **YAML recipes vs JSON defaults.** The 12 YAML recipes in
> `mindxtrain/train/recipes/` are full `XTrainConfig` instances for a specific
> training run (they're what `mindxtrain init --template <name>` writes).
> Separately, `mindxtrain/config/{train_default,eval_default,deploy_default}.json`
> provide ml-intern-style runtime defaults with `${ENV}` interpolation — these
> are runtime defaults for `train`/`eval`/`serve` orchestration, not training-job
> recipes.
Top-level shape:
```yaml
meta: { project, run_name, seed, license, description }
hardware: { name, gfx_arch, gpus, expected_hbm_gb }
autotune: { enabled, plan_path, budget_seconds, policy }
model: { name, revision, attn_implementation, torch_dtype, trust_remote_code }
data: { source, hf_id, split, streaming, max_samples, seq_len, packing, dedupe, shard }
train: { backend, method, optimizer, schedule, batch, precision,
gradient_checkpointing, flash_attention, fsdp, env }
eval: { harness, regression }
quantize: { enabled, scheme, ptpc }
serve: { backend, reasoning_parser, tool_call_parser, tensor_parallel,
max_model_len, port }
publish: { enabled, hf, lighthouse, mindx, agenticplace, bankon, billing }
receipt: { output, include }
```
`extra: forbid` is set on every model — unknown fields raise `ValidationError`. `frozen: true` is set on every model — configs are immutable once loaded.
## `meta`
| Field | Type | Default | Notes |
|---------------|------|--------------|----------------------------------------------|
| `project` | str | _required_ | Logical group, e.g. `mindxtrain_demo`. |
| `run_name` | str | _required_ | Slug for the run, e.g. `qwen3_8b_sft_lora`. |
| `seed` | int | `2048` | RNG seed; cypherpunk2048 reference. |
| `license` | str | `apache-2.0` | SPDX-style license string. |
| `description` | str | `""` | Free-form. |
## `hardware`
| Field | Type | Default | Notes |
|-------------------|------------------------------|-----------|----------------------------------------------------------------------------------------|
| `name` | `mi300x \| mi325x \| mi350x \| mi355x` | `mi300x` | Cloud SKU. |
| `gfx_arch` | `gfx942 \| gfx950` | `gfx942` | Must match `name`. AOTriton compiles per arch. |
| `gpus` | `Literal[1, 8]` | `1` | **Hard constraint** — 2/4-GPU FSDP groups hit MI300X xGMI bandwidth asymmetry. |
| `expected_hbm_gb` | int | `192` | Used by autotune to size FSDP shards. |
## `autotune`
| Field | Type | Default | Notes |
|-------------------|---------------------|---------------------------------------|---------------------------------------------|
| `enabled` | bool | `true` | Skip with `--dry-run` on CPU. |
| `plan_path` | Path | `./out/mindxtrain.tuned.yaml` | AOT plan output location. |
| `budget_seconds` | int (10-600) | `60` | MoE recipes use 90-120 s. |
| `policy` | `Literal[aot_only]` | `aot_only` | **JIT autotune is forbidden in production.** |
## `model`
| Field | Type | Default | Notes |
|------------------------|---------------------------------------|----------------------|----------------------------------------------------|
| `name` | str | _required_ | HF Hub model ID. |
| `revision` | str \| null | `null` | git revision pin; `null` means default branch. |
| `attn_implementation` | `flash_attention_2 \| sdpa \| eager` | `flash_attention_2` | autotune may override. |
| `torch_dtype` | `bfloat16 \| float16 \| float32 \| fp8_e4m3 \| mxfp4` | `bfloat16` | BF16 is the safe default on MI300X. |
| `trust_remote_code` | bool | `false` | Reject untrusted custom code paths. |
## `data`
| Field | Type | Default | Notes |
|---------------|-------------------------------|------------------|------------------------------------------------------|
| `source` | `hf \| local \| lighthouse` | `hf` | |
| `hf_id` | str | _required_ | Dataset ID, e.g. `HuggingFaceH4/ultrachat_200k`. |
| `split` | str | `train` | |
| `streaming` | bool | `true` | Avoid storing 100 GB+ corpora locally. |
| `max_samples` | int \| null | `null` | Truncate for fast demos. |
| `seq_len` | int (64 .. 1 048 576) | `4096` | |
| `packing` | bool | `true` | Pack-to-cutoff Qwen3-style. |
| `dedupe` | `DedupeCfg` | `{}` | Optional `minhash` and `semdedup` sub-configs. |
| `shard` | `ShardCfg` | `{ num_shards: 1 }` | |
`DedupeCfg.minhash`: `{ threshold: 0.0..1.0 }`.
`DedupeCfg.semdedup`: `{ threshold, model: <ST model id> }`.
## `train`
| Field | Type | Default | Notes |
|--------------------------|-----------------------------------------|------------------------|--------------------------------------------------------------------|
| `backend` | `axolotl \| unsloth \| torchtune \| primus` | `axolotl` | Only `axolotl` is real in week 1. |
| `method` | discriminated union (see below) | `lora` defaults | Tag with `kind:`. |
| `optimizer` | `OptimizerCfg` | adamw_torch_fused 1e-4 | `name`, `lr`, `betas`, `weight_decay`, `grad_clip`. |
| `schedule` | `ScheduleCfg` | cosine, warmup 0.03 | `type`, `warmup_ratio`, `epochs`. |
| `batch` | `BatchCfg` | per_device 8, ga 4 | `per_device`, `grad_accum`. |
| `precision` | `DType` | `bfloat16` | training-time precision; quantize step changes serving precision. |
| `gradient_checkpointing` | bool | `true` | |
| `flash_attention` | `FlashAttentionCfg` | `{ backend: ck }` | autotune may flip to `triton`. |
| `fsdp` | `FsdpCfg` | `{ enabled: false }` | |
| `env` | `dict[str, str]` | seven MI300X knobs | Set in subprocess before training-backend launch. |
The default `train.env` carries the non-negotiable MI300X knobs:
```yaml
env:
HSA_NO_SCRATCH_RECLAIM: "1"
NVTE_CK_USES_BWD_V3: "1"
NVTE_CK_IS_V3_ATOMIC_FP32: "1"
PRIMUS_TURBO_ATTN_V3_ATOMIC_FP32: "1"
NCCL_MIN_NCHANNELS: "112"
HIP_FORCE_DEV_KERNARG: "1"
PYTORCH_ROCM_ARCH: "gfx942"
```
### `train.method` (discriminated union)
| `kind` | Required fields | Notes |
|----------|---------------------------------------------------|---------------------------------------------|
| `full` | _none_ | Full-parameter SFT. |
| `lora` | `r`, `alpha`, `dropout`, `target_modules` | Default LoRA recipe. |
| `qlora` | `r`, `alpha`, `dropout`, `quant_bits` (4 or 8), `target_modules` | bitsandbytes opt-in only. |
| `dpo` | `beta` | Direct Preference Optimization. |
| `orpo` | `beta` | Odds Ratio Preference Optimization. |
| `grpo` | `num_generations`, `kl_coef` | Group Relative Policy Optimization. |
| `gspo` | `num_generations` | Qwen team's preferred RL on hybrid + MoE. |
| `kto` | `beta` | Kahneman-Tversky Optimization. |
| `cpt` | _none_ | Continued Pretraining. |
Unknown `kind` raises `ValidationError` (tested in `tests/test_config_schema.py::test_method_discriminator_rejects_unknown_kind`).
## `eval`
| Field | Type | Default | Notes |
|--------------|---------------------|----------------------------------------------------|------------------------------------------------|
| `harness` | `EvalHarnessCfg` | `{ tasks: [mmlu, gsm8k, ifeval, humaneval], fewshot: 5 }` | Wraps `lm-evaluation-harness`. |
| `regression` | `EvalRegressionCfg` | `{ baseline: "", threshold_pct: -1.0 }` | Fail run if any task drops > 1 pct vs baseline. |
## `quantize`
| Field | Type | Default | Notes |
|------------|--------------------------------------------|---------------|--------------------------------------------------------|
| `enabled` | bool | `true` | |
| `scheme` | `quark_fp8 \| quark_mxfp4 \| gptq_rocm \| none` | `quark_fp8` | AMD Quark FP8 (E4M3) is the default. |
| `ptpc` | bool | `true` | Per-tensor-per-channel — 15-30 % faster than BlockScale on MI300X. |
## `serve`
| Field | Type | Default | Notes |
|------------------------|-------------------------------|---------------|--------------------------------------------------|
| `backend` | `vllm-rocm \| sglang` | `vllm-rocm` | |
| `reasoning_parser` | `deepseek_r1 \| qwen3 \| none`| `qwen3` | Use `qwen3` for Qwen3 / 3.5 / 3.6. |
| `tool_call_parser` | `hermes \| qwen3_coder \| none` | `hermes` | Use `qwen3_coder` for Qwen3-Coder family. |
| `tensor_parallel` | int (≥1) | `1` | tp size for multi-GPU serving. |
| `max_model_len` | int (≥512) | `8192` | KV cache cap. |
| `port` | int (1024..65535) | `8000` | |
## `publish`
| Field | Type | Notes |
|---------------|----------------------------|------------------------------------------------------------------|
| `enabled` | bool, default `true` | |
| `hf` | `HfPublishCfg \| null` | `{ repo, private }`. `null` skips HF push. |
| `lighthouse` | `LighthousePublishCfg` | `{ api_key_env }`. Defaults to env var `LIGHTHOUSE_API_KEY`. |
| `mindx` | `MindxPublishCfg` | `{ api_url, register_as_capability }`. |
| `agenticplace`| `AgenticPlacePublishCfg` | `{ api_url, chain_map_url }`. |
| `bankon` | `BankonPublishCfg` | `{ ens_parent, subname }`. |
| `billing` | `BillingPublishCfg` | `{ x402: { network, asset, receiver_via, price_per_1k_tokens } }`.|
`publish.billing.x402.network` is `algorand | base | base-sepolia`. The defaults are `algorand` + `USDC` ASA `203977300`.
## `receipt`
| Field | Type | Default | Notes |
|----------|-----------------------|-------------------------------------|------------------------------------------------------|
| `output` | Path | `./out/receipt.json` | Manifest output. |
| `include`| `list[ReceiptIncludeKey]` | all 8 keys (see schema.py) | Which provenance fields to capture. |
`ReceiptIncludeKey` is one of: `rocm_version`, `gfx_arch`, `container_digest`, `all_git_shas`, `yaml_hash`, `dataset_cids`, `eval_report`, `energy_kwh`.
## How the schema is enforced
```bash
uv run pytest tests/test_config_schema.py -v
```
12 tests cover the full surface: every recipe round-trips, the demo example validates, the `hardware.gpus: 1|8` constraint rejects 2 and 4, the discriminator rejects unknown method kinds, and `extra: forbid` rejects unknown keys at every level.
|