Build models — TRAIN / STEP / ARTIFACT
How Spark programs training in SPARK_BC and what lands on disk. Train runs on CPU (default) or a consumer GPU. CPU fixtures only.
Full factory: SPARK_BC Builder. Language verbs: MODEL_TRAINING.md · LANGUAGE.md.
Opcodes in the binary
| Byte | Mnemonic | LANGUAGE | Disk / stdout |
|---|---|---|---|
0x26 |
TRAIN |
model train / model build |
dry job JSON; writes ARTIFACT under out/train/<job>/; trained=false until STEP |
0x28 |
STEP |
model step |
multi-pass CPU SGD → weights.safetensors + checkpoint.json; trained=true / not_sgd=false when grads apply |
0x27 |
TRAIN_STATUS |
model status |
dry status JSON |
Dry fixture SoT: bootstrap/dry_train.c. Emitting TRAIN ≠ trained
weights.
End-to-end (proof program)
Source: examples/spark_train_step.spark → published
docs/examples/spark-train-step.sparkbc.
./spark-bootstrap --compile examples/spark_train_step.spark \
-o /tmp/spark-train-step.sparkbc
./spark-bootstrap --run-bc /tmp/spark-train-step.sparkbc
# → out/train/job-dry-001/ARTIFACT (+ weights after STEP)
Helper (same SGD as STEP path):
PYTHONPATH=python python3 tools/spark-bc-dump/apply_step.py \
--sparkbc docs/examples/spark-train-step.sparkbc \
--weights /tmp/weights.safetensors \
--checkpoint /tmp/checkpoint.json \
--dataset examples/fixtures/train/dataset.jsonl \
--outer 4 --inner 8 --step 1
Implementation: python/sparklang/model_lab/ (apply_sgd_step).
Not a second training SoT in docs — link the code.
ARTIFACT / checkpoint status
ARTIFACT— job marker text; after successful STEP lists weights + checkpoint paths andnot_sgd=false.weights.safetensors— Spark tensors; metatrainedmust match reality (falsefor init-only,trueafter SGD).checkpoint.json— includesloss_curve,loss_before/loss_after,claim: false,device(CPU).
Gates fail loud if loss does not drop.
Init vs STEP weights
| Artifact | Meaning |
|---|---|
Init safetensors from dump.py --weights |
Derived from SPARK_BC bytes; Xavier; not trained |
| STEP weights | Multi-pass CE on lm_head (+ optional embed); tiny fixture |
Init tensor layout (including unused attn Q/K/V/O slots):
python/sparklang/model_lab/weights.py. Serve path today uses
the MLP only — Attention / forward.
Makefile targets
make test-sparkbc # includes dump + SGD loss-drop asserts
make sparkbc-e2e # TRAIN→STEP→ARTIFACT (+ GAS --run-bc)
make spark-sgd-proof # SGD then measurement-only spark-eval
make spark-eval # frozen probes; exit 0 ≠ marketing win
make spark-eval WEIGHTS=out/train/sgd-proof/weights.safetensors
Details: SPARKBC_MAKE.md.
HTTP companion (live jobs)
./spark-train-http remains the live HTTP job path
(MODEL_TRAINING.md). backend on train lines
is parsed and skipped in SPARK_BC (not an operand).