diff --git a/docs/evolution.md b/docs/evolution.md new file mode 100644 index 0000000..f02c8f2 --- /dev/null +++ b/docs/evolution.md @@ -0,0 +1,58 @@ +# xtrain 演进总览 — 按维度记录每次变化 + +每个里程碑(**T# 基建 phase** 或 **v# 训练 run**)在四个维度上分别改了什么、结果如何。 +这是活文档:**每次新 run 收尾时追加一行/一段**。细节见各 `docs/runs/0N-*.md`、各 phase 设计文档、`docs/known-issues.md`。 + +四个维度:**算法**(autograd/优化器/精度/反向数学)· **模型架构**(dim/层/头/算子)· **Infra**(构建/显存/并行/吞吐)· **数据集**(语料/token/epoch/tokenizer)。 + +--- + +## 一、基建 phase(T1–T12)—— 主要动「算法」与「Infra」 + +| Phase | 维度 | 变化 | 结果 / 验证 | +|---|---|---|---| +| T1 | Infra | Rust↔CUDA FFI 构建链(build.rs+nvcc, `no_cuda` cfg),gitea↔dash5 流 | vector-add 跑通 | +| T2 | Infra | Tensor 抽象(dtype/shape/Storage, H↔D 拷贝)+ elementwise kernel | roundtrip 保真 | +| T3 | 算法 | 手写 tiled GEMM fwd/bwd + finite-diff 梯度检查 harness | fwd vs cuBLAS 1e-7;bwd vs finite-diff | +| T4 | 算法 | tape autograd 引擎 + 11 算子 backward(含梯度扇出累加);attention 由 matmul+softmax 组合 | 每算子 finite-diff ≤2e-2 | +| T5 | 模型架构 | 组装 tiny decoder(RoPE+RMSNorm+SwiGLU)+ embedding/reshape/transpose 算子 | overfit 27/27 + PyTorch 对拍 B>1 | +| T6 | 算法 + 数据集 | 手写 AdamW + 训练 loop + LR sched + grad clip + checkpoint;gpt2 BPE + TinyStories | 真训出连贯英文 | +| T7 | Infra | cuBLAS matmul + GPU 端 AdamW/grad-norm + 去 per-op sync | **~3×**:2.7K→8.5K tok/s,零回归 | +| T8 | Infra | NCCL DDP(单进程 thread-per-GPU)+ 梯度 all-reduce | 多卡(当时弱扩展 ~1.4×) | +| T9 | 算法/模型架构 + Infra | **加 per-head QK-norm**(Qwen3 兼容);safetensors 导出 | xserv 闭环:贪心**逐 token 一致** | +| T10 | 算法/Infra | **batched 多序列 forward**(linears flatten `[B·S,dim]` + fused batched SDPA + 每序列 RoPE) | **单卡 15–24×**;MFU 0.4%→14%(修 KI-1) | +| T11 | Infra | **device caching/pool allocator**(复用 op 输出显存,消 per-step cudaMalloc) | 单卡 2.3×;**8卡 461K tok/s** 近线性(修 KI-5) | +| T12 | 算法/Infra | **bf16 混合精度**(fp32 master,cuBLAS GemmEx,norm/softmax/CE 保 fp32) | dim768 OOM 解除,−29% 显存/+13% tok/s(修 KI-2) | + +--- + +## 二、Scaling runs(v0–v6)—— 主要动「模型架构」与「数据集」 + +架构始终是 **Qwen3-style**(RoPE + RMSNorm + QK-norm + SwiGLU,gpt2 50257 词表),只放大 dim/层;其余维度逐版变化如下: + +| ver | 模型架构(dim/层/头·hd · 核心/总参) | 数据集(语料 · 实训 token · epoch) | 算法/精度 | Infra(GPU · 吞吐) | 结果(val · 备注) | +|---|---|---|---|---|---| +| v0 | dim32/4L/2h · 41K/3.26M | TinyStories 3MB 切片 · ~0.72M · — | fp32 单序列 | 1 GPU | val 3.80(toy,不可用) | +| v1 | dim256/8L/8h · 8.4M/34M | TinyStories 全量 · 5.1M · 0.01ep | fp32 单序列 | 1 GPU · 3.3K | val 2.58 | +| v2 | dim384/12L/12h · 28M/67M | TinyStories · 37M · 0.08ep | fp32 单序列 | 4 GPU DDP · 3.6K | val 1.71(暴露 KI-1/弱扩展) | +| v3 | dim512/16L/16h · 67M/119M | TinyStories · 246M · 0.53ep | fp32 **batched(T10)** | 1 GPU · 26K | val 1.30 | +| v4 | dim768/18L/24h · 127M/205M | TinyStories · 721M · 1.54ep | fp32 batched | **8 GPU(T11)** · 145K | val 1.17(仍欠拟合) | +| v5 | dim768/18L(**同 v4**) | TinyStories · 2.49B · **5.33ep** | **bf16(T12)** | 8 GPU · 217K | val **1.11**:⚠️**TinyStories 饱和**(3.5×数据仅↓5%) | +| v6 | dim768/18L(同 v4/v5) | **FineWeb-edu** 真实网页 · 2.29B · 1.02ep | bf16 | 8 GPU · 204K | 训练中(FineWeb val 与上**不可比**) | + +> 实训 token = steps×batch×seq(非数据集大小)。val 同一 1M-token TinyStories 留出集(v0–v5 可比;v6 起换 FineWeb-edu 留出集,分布不同、不可比)。 + +--- + +## 三、各维度的累积演进(轴向看一条线怎么走的) + +- **算法**:手写 autograd(tape)+扇出累加 → AdamW/LR-sched/grad-clip → +QK-norm(Qwen3) → batched forward → bf16 混合精度(fp32 master)。 +- **模型架构**:固定 Qwen3-style;dim **32→256→384→512→768**;核心参数 **41K→127M**(总 3.26M→205M)。 +- **Infra**:单卡 fp32 → cuBLAS/GPU-optim(T7) → NCCL DDP(T8) → batched forward(T10) → caching allocator(T11) → bf16(T12)。吞吐 **3.3K→217K tok/s**,MFU **0.4%→17%**(每次提升都对应一块 perf 基建,详见 known-issues + MFU 分析)。 +- **数据集**:TinyStories 3MB 切片 → 全量 TinyStories(epoch 0.01→5.33,至饱和)→ **FineWeb-edu** 真实网页。tokenizer 全程 gpt2 BPE(复用 xserv-tokenizer)。 + +## 四、perf 杠杆台账(详见 [known-issues.md](known-issues.md)) + +- **已修**:KI-1 单序列 launch-bound(T10)· KI-5 per-op cudaMalloc 串行(T11)· KI-2 bf16/OOM(T12)。 +- **待办**:KI-3 激活重计算(放大到 dim1024+ 时)· KI-4 大词表小 vocab · process-per-GPU(要更高多卡线性时)。 +- 两次「先 profile 再动手」证伪了错误的拟修复(KI-1「加大batch」、KI-5「分桶all-reduce」),避免了无效大改——profile-first。