docs: T17 process-per-GPU results — measured throughput-neutral
Records the key empirical finding: process-per-GPU is statistically identical to thread-per-GPU at this scale (thread 5.27x vs proc 5.31x @8, <1% noise; all 8 GPUs 95-99% util). The residual ~5.3x@8 non-linearity is the NCCL/PCIe communication wall, NOT single-CUDA-context launch/cuBLAS serialization as the old KI-5/T11 note speculated — measurement falsifies that hypothesis (same methodology as T11 falsifying "bucket the all-reduce"). Correctness all green: proc==thread loss 1.5e-7, cross-rank 1.2e-7, full regression + xserv md5 b04fc9f9 identical. Closes the process-per-GPU backlog item (measured no-op); default training path unchanged. evolution.md Infra row + README T17 row + known-issues entry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
13
README.md
13
README.md
@@ -26,7 +26,7 @@ borrows, the rest hand-written CUDA + Rust:
|
||||
| `xtrain-model` | tiny **Qwen3-style** transformer (RoPE + RMSNorm + QK-norm + SwiGLU), batched forward |
|
||||
| `xtrain-optim` | hand-written **AdamW** (host + GPU kernels) |
|
||||
| `xtrain-train` | training loop, LR schedule, grad clip, checkpoint, BPE corpus + cache, samplers, safetensors export |
|
||||
| `xtrain-distributed` | **NCCL DDP** (thread-per-GPU, all-reduce) |
|
||||
| `xtrain-distributed` | **NCCL DDP** (thread-per-GPU + torchrun-style process-per-GPU, all-reduce) |
|
||||
|
||||
Every op's backward is verified against **finite differences** and against **PyTorch**
|
||||
(forward + per-parameter grads, batch > 1). Trained weights export to HF-safetensors and
|
||||
@@ -53,6 +53,7 @@ Each phase: design doc + implementation + tests + a scoped commit (see [`docs/`]
|
||||
| **T14** | **fused flash-attention** kernel (online softmax, no materialized N×N; opt-in `--flash`) | peak mem −16%@1k / −23%@2k seq; flash==composed (grads/PyTorch) |
|
||||
| **T15** | **grouped-query attention** (`num_kv_heads<num_heads`; `repeat_kv` broadcast feeds both SDPA paths; backward sums each kv head's group; `--kv-heads`) | repeat_kv grad-check + **group=1 bit-identical to MHA**; GQA flash==composed; PyTorch GQA B>1; **xserv closed loop with real `num_key_value_heads`** token-identical |
|
||||
| **T16** | **gradient accumulation** (`--accum-steps`; DDP all-reduces only at the boundary) | equiv to N× big batch (grad 3.8e-5); same effective-64 batch 27.7GB→7.2GB (−74%) |
|
||||
| **T17** | **process-per-GPU** DDP (torchrun-style: 1 worker process / CUDA context per GPU; launcher mints `ncclUniqueId` → hex env injection; `train_rank` reused unchanged; thread-per-GPU path kept) | proc==thread loss 1.5e-7, cross-rank 1.2e-7, xserv md5 identical · **measured no-op on throughput**: thread 5.27× vs proc 5.31×@8 (8 GPUs 95–99% util) → residual non-linearity is NCCL/PCIe, *not* CUDA-context serialization (falsifies the old KI-5 hypothesis) |
|
||||
| **T18** | **dropout** (hand counter-based device RNG + mask, inverted scaling, train/eval switch) | fixed-seed grad-check; **p=0 bit-identical**; recompute-safe |
|
||||
|
||||
The four performance fixes (T10–T13) each removed a real bottleneck — see
|
||||
@@ -64,8 +65,14 @@ num_heads` via a `repeat_kv` broadcast op whose backward sums each kv head's que
|
||||
group — feeding both SDPA paths unchanged, default MHA bit-identical);
|
||||
T16 = micro-batch gradient accumulation ([`docs/15-grad-accum.md`](docs/15-grad-accum.md)),
|
||||
which decouples the effective batch from activation memory (memory tracks the micro-batch,
|
||||
not N×); T18 = dropout ([`docs/17-dropout.md`](docs/17-dropout.md), hand counter-based
|
||||
device RNG + mask, inverted scaling, train/eval switch).
|
||||
not N×); T17 = torchrun-style process-per-GPU DDP
|
||||
([`docs/16-process-per-gpu.md`](docs/16-process-per-gpu.md), one process + CUDA context per
|
||||
GPU, launcher-minted `ncclUniqueId` via env injection, reusing the T8 training step
|
||||
unchanged) — which **measured** that, at this scale, separate contexts give no throughput
|
||||
gain over thread-per-GPU (the residual ~5.3×@8 is the NCCL/PCIe communication wall, not
|
||||
single-context serialization as the old KI-5 note speculated); T18 = dropout
|
||||
([`docs/17-dropout.md`](docs/17-dropout.md), hand counter-based device RNG + mask, inverted
|
||||
scaling, train/eval switch).
|
||||
|
||||
## The scaling study — v0 → v8
|
||||
|
||||
|
||||
Reference in New Issue
Block a user