v4 scaling run finished: dim768/18L, core 127.43M (total 204.63M), trained 720.9M tokens (~1.54 epoch) on 8x RTX 5090 DDP fp32, ~145K tok/s, ~84 min, best val 1.1690. Checkpoint archived to registry (~/projects/tiny-models/v4-tinystories-dim768/) and exported to xserv HF Qwen3 safetensors (201 tensors, BF16); xserv serves it and matches xtrain greedy token-for-token on all 3 fixed prompts (40 tok). Add `greedy_sample` bin: load a trained ckpt with its arch flags and print xtrain's own greedy continuations for the fixed run prompts, so they can be diffed against xserv's greedy on the exported weights (the per-run token-match check). Same model/config/init scheme as bin/train.rs + bin/export_safetensors.rs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
xtrain
A from-scratch Rust + CUDA LLM training engine — the sibling of xserv (the inference side). GPU-first.
The goal is to learn the full training-systems stack by hand: autograd / backward passes / optimizers (AdamW) / the training loop / distributed logic. Heavy lifting is borrowed where it makes sense (GEMM → cuBLAS after a hand-written version, multi-GPU comms → NCCL, tokenizer → reused from xserv), but the core is written from scratch. The target architecture is a tiny modern transformer (RoPE + RMSNorm + SwiGLU, ~1–30M params) whose forward aligns with xserv's Qwen3, so the backward passes map one-to-one onto xserv's existing forward kernels and trained weights can flow back into xserv.
Status
Bootstrapping (P0). This repo currently contains only the project skeleton and a working Rust↔CUDA build chain, verified by a trivial vector-add CUDA kernel.
Layout
xtrain/
├── Cargo.toml # workspace
├── csrc/ # CUDA sources (.cu)
│ └── test/vecadd.cu # trivial element-wise vector-add (smoke test)
└── crates/
└── xtrain-cuda/ # CUDA Runtime FFI + build.rs (nvcc → sm_120)
├── build.rs # compiles csrc/*.cu via the `cc` crate, links cudart
├── src/ # ffi / error / device / memory
└── tests/ # vecadd smoke test
The build mirrors xserv's approach: build.rs invokes nvcc (via the cc crate)
to compile csrc/*.cu targeting sm_120 (RTX 5090) and links them into the Rust
crate over hand-written extern "C" FFI.
Building & testing
CUDA compilation and execution happen on a GPU box (dash5, 8× RTX 5090, sm_120):
export PATH=/usr/local/cuda/bin:$HOME/.cargo/bin:$PATH
cargo build
cargo test -p xtrain-cuda -- --nocapture # runs the vecadd smoke test
On a machine without nvcc/GPU, build.rs detects the missing toolchain, skips
CUDA compilation, and sets a no_cuda cfg — so host-side cargo check still
works (the GPU smoke test is compiled out).