Tutorials
Chat response distillation and SFT
Run a complete offline chat workflow, then understand the boundary for provider teachers and production recipes.
This tutorial freezes one canonical conversation, produces explicitly fake teacher output, trains the CPU fixture, resumes it, evaluates it, and verifies its export. It makes no network request, model download, GPU call, or upload.
1. Inspect and freeze the input
examples/chat-offline/records.jsonl contains one versioned conversation with provenance and a stable record ID. Freeze it before generation so later stages can bind to an immutable hash.
npm run build
node dist/cli/index.js dataset freeze \
examples/chat-offline/records.jsonl \
--out tmp/chat-offline/frozen \
--force \
--json
Expect recordCount: 1. The frozen manifest is the input authority; changing a record creates a different hash rather than silently reusing prior work.
2. Initialize, plan, and generate offline
node dist/cli/index.js distill init \
--root tmp/chat-offline/distill \
--config examples/chat-offline/distillation.json \
--input examples/chat-offline/records.jsonl \
--force \
--json
node dist/cli/index.js distill plan \
--root tmp/chat-offline/distill \
--json
node dist/cli/index.js distill responses \
--root tmp/chat-offline/distill \
--offline-fake \
--json
The fake candidate is labeled custom/offline-fake; it is test data, not evidence about a real teacher. A provider-backed plan instead requires an explicit provider/model, credential environment-variable name, --allow-network, and separate positive generation and judging budgets. Idempotency and the resume ledger prevent a successful paid sample from being purchased twice.
3. Freeze distilled output
node dist/cli/index.js distill freeze \
--root tmp/chat-offline/distill \
--out tmp/chat-offline/distilled \
--force \
--json
Inspect rejected and retained candidates before freezing. Policy decisions annotate candidates; they do not erase lineage. Keep validation/test groups locked and never send held-out answers to a teacher.
4. Train, resume, evaluate, and export
node dist/cli/index.js training run \
--spec examples/chat-offline/training.json \
--python python3 --python-root python --json
node dist/cli/index.js training resume \
--spec examples/chat-offline/training.json \
--checkpoint ../tmp/chat-offline/train/checkpoint-1.json \
--python python3 --python-root python --json
node dist/cli/index.js training evaluate \
--spec examples/chat-offline/training.json \
--python python3 --python-root python --json
node dist/cli/index.js training export \
--spec examples/chat-offline/training.json \
--python python3 --python-root python --json
Each command returns exitCode: 0. Verify every path and SHA-256 in tmp/chat-offline/train/artifact-manifest.json. A complete checkpoint permits full resume; weights-only output is a labeled warm start.
Recovery and production transition
On interruption, rerun status and resume from the newest atomic, compatible checkpoint. Never adopt a checkpoint with a different data hash, recipe identity, image, or spec. The Qwen 9B recipe and all production chat recipes are experimental; execution remains gated until pinned license, GPU smoke, clean reload, and evaluation gates pass.
Next: choose a distillation target or interpret evaluation and artifacts.