Files
xtrain/docs/runs/08-v8-fineweb-edu-dim1024.md
Gahow Wang 511f35d40c docs: run v8 — dim1024 capacity helps (val 2.98)
v8 = capacity-axis A/B: freeze the v6/v7 2.255B FineWeb-edu subset, scale
dim768→dim1024 (core 127M→226M, +78%) via bf16 + T13 activation recompute.
8-GPU DDP, 2.36B tok (1.05 ep), ~129K tok/s (recompute tax), ~5h.

Result (same FineWeb val, v6/v7/v8 comparable): v6 3.0652 / v7 3.0149 /
v8 2.9801. Capacity helps — v8 (1.05ep) beats v6 at the same ~1ep by 0.085
AND beats v7 (smaller model, 1.45ep more old data) by 0.035 ⇒ v6/v7 were
partly capacity-limited, scaling capacity > repeating old data. But the gain
is only ~3% (same magnitude as the data-axis single-step lever), and v8's
val was still descending at the end (not saturated).

Meta-finding: every single-axis lever (data-volume v5/v7, breadth v6,
capacity v8) is now ~3%/lever ⇒ broad diminishing returns; to progress,
scale capacity AND data together (Chinchilla, reproduced at toy scale).

- docs/runs/08-v8-fineweb-edu-dim1024.md: full capacity experiment + v7-vs-v8 samples
- docs/runs/README.md: +v8 row, v9 proposal
- docs/evolution.md: +T13 infra row, +v8 scaling row, capacity-axis & diminishing-returns notes

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 15:12:01 +08:00

14 KiB
Raw Permalink Blame History

Scaling Run v8: 容量轴 — dim1024/18L(core 226M, +78% 容量) + 同 v6/v7 的 FineWeb-edu 2.255B 子集 + bf16 + 激活重计算(T13) + 8 卡 DDP — Design Document

Goal

v6/v7 把数据轴测到了头:同一 2.255B FineWeb-edu 子集,从 1.02 epochv6 3.0652)喂到 1.45 epoch v7 3.0149FineWeb val 仅 ↓0.05 且走平 = 同子集多 epoch 在 dim768 上近天花板。v7 末尾把下一步的 首选定为「新 FineWeb shards」真·更多数据并把「更大模型」列为待测的容量轴——但留了一个明确的 未解问题:dim768core 127M在这本语料上到底是数据见够了还是模型容量不够(即是否 capacity-limited

v8 就是去净测这条容量轴数据完全冻结 = v6/v7 的同一个 2.255B 子集,唯一变量 = 把模型从 dim768 放大到 dim1024core 127M → 226M+78% 容量)。

  1. 数据子集完全冻结 = v6/v7:同一个 2,254,904,418-token FineWeb-edu 子集(sample/10BT 3 个 parquet 分片),同一 1M held-out val与 v6/v7 同一把尺子,可直接比)。不补任何新数据——这是干净的 dim768-vs-dim1024 A/B。
  2. 唯一变量 = 模型容量dim 768 → 102432 heads × 32 head_dimffn 2048 → 2730(≈ 8/3·dim 的 SwiGLU 惯例18 层不变 → core 226.5M+78%/ 总 329.4M
  3. 为装下 dim1024 而启用 T13 激活重计算dim1024 batch32 激活显存超 32GB → 用 KI-3 的 per-block gradient checkpointingno-tape 前向 + 反向时重算)压到 16.6GB/卡,恰好装得下。这是 v8 能成立的前置基建

⚠️ 方法论说明(同 v6/v7

v8 的 valFineWeb-edu 2.9801)与 v63.0652、v73.0149同一把尺子、同一个 1M 留出集,三版可以 直接比;但都不能和 v0v5 的 TinyStories val~1.1)比大小——真实网页文本熵高,~3.0 是预期值不是回退。

数据v8 与 v6/v7 的唯一差别 = 模型容量,数据一字不差)

v6/v7 v8
来源 FineWeb-edu sample/10BT(真实教育类网页) 同(一字不差的同一子集,非新数据)
语料规模 2,254,904,418 tokens3 parquet 分片) 2,254,904,418 tokens同子集
训练消费 token v6 ~2.29B(1.02ep) / v7 ~3.28B(1.45ep) ~2.359B36000 步 × global 256 × seq 256
epoch 占比 v6 ~1.02 / v7 ~1.45 ~1.05(刻意取最接近 v6 的 ~1 epochA/B 同 epoch 对照)
tokenizer gpt2 BPEvocab 50257
缓存 data/fineweb-edu.txt.u16.bin4.51GB u16 同一缓存
held-out val FineWeb-edu 末尾 1M token 同(与 v6/v7 可比)

v8 的 epoch 取 1.05(不是 v7 的 1.45)是刻意的:这样 v8 与 v61.02ep)几乎同 epoch,是最干净的 「同数据量、纯放大容量」A/B同时与 v71.45ep,更多 epoch 的小模型)对照,能回答「容量 vs 更多老数据 谁更值」。

架构v8 唯一变化点 = 容量)

v8 = 把 v4v7 的 tiny Qwen3RoPE + RMSNorm + per-head QK-norm + SwiGLU + 独立 lm_headMHA按容量轴放大

v4v7 (dim768) v8 (dim1024)
dim 768 1024
heads × head_dim 24 × 32 32 × 32
layers 18 18不变
SwiGLU ffn 2048 2730
core 参数 127,432,704 226,495,488+78%
embed + lm_head 77.19M 102.93M
总参数 204.63M 329.42M
导出 tensors 201 201(层数同,张量数同)

head_dim 保持 32与全系一致RoPE/QK-norm 维度不变靠加头数24→32把 dim 撑到 1024ffn 2730 ≈ (8/3)·1024 取整到偶数,沿用 SwiGLU 的 2/3·4·dim 经验比例。

训练器8 卡 DDP bf16 + 激活重计算v8 新启 T13

复用 v5/v6/v7 的训练栈fp32 master + AdamW/clip/DDP 全 fp32linears 走 cublasGemmEx 16BF/fp32 accum、 激活存 bf16norm/softmax/rope/CE 仍 fp328 卡 thread-per-GPU all-reduce 取均值后各 rank 本地 GpuAdamW step跨 rank bit-identical新增一项

  • 激活重计算 ONT13 / KI-3per-block gradient checkpointing——前向不建 tape、反向时按块重算激活。 对非重计算版梯度逐位一致0.00 rel err。这是 dim1024 batch32 能装进 32GB 卡的关键16.6GB/卡)。
  • 代价dim1024 下重算税更重,稳态吞吐 ~129,000 tok/svs dim768 bf16 的 ~218K——多一遍块前向 + 更大的矩阵。util 97100%、16.3GB/卡。wall-clock ~5h 训完 2.359B token36000 步)。

超参

备注
optimizer 手写 AdamWGPU 端 step wd=0.1,β/eps 用 xtrain-optim 默认(同全系)
LR schedule 线性 warmup → cosine decay max_lr 6e-4 → min_lr 6e-5(同 v1v7
warmup ~1800 步 lr 峰值 6e-4cosine 衰减到末步 6e-5
grad clip global-norm 1.0 平稳 gnorm ~0.21
steps 36000 ~5h @ 8 卡(重算税)
global batch 256per-rank 32 × world 8 bf16 + 重计算后 dim1024 的甜点区
seq_len 256 同 v2v7
tokens/step 256×256 = 65536 总训练 token ≈ 2.359B~1.05 epoch
world size 8RTX 5090sm_120
精度 bf16 混合精度fp32 master T12/KI-2导出 xserv 同样 BF16
激活重计算 ONper-blockT13/KI-3 v8 新启,解锁 dim1024

结果

  • train lossstart 11.1018 → end 3.0586(全程平滑下降)
  • best val loss 2.9801step 35999final val loss 2.9801同一步即末步FineWeb-edu held-out 1M
  • FineWeb val 曲线(抽样):
step 499 999 3999 7999 11999 15999 19999 25999 29999 31999 33999 34999 35999
val 5.5736 4.6699 3.6454 3.4184 3.2956 3.2153 3.1506 3.0593 3.0201 2.9999 2.9862 2.9828 2.9801

⚠️ 末步即 best、且仍在降:从 33999(2.9862) → 34999(2.9828) → 35499(2.9820) → 35999(2.9801),每 500 步 仍稳定 ↓~0.002到训练结束没有走平——与 v7 末段(~step44000 后走平、末步还反弹)形成对比。v8 还没吃饱

核心 A/B 结论:容量有用(部分 capacity-limited但增益 ~3% 边际

三版同一 FineWeb val 尺子,直接可比:

v6 v7 v8
模型 dim768 (core 127M) dim768 (core 127M) dim1024 (core 226M, +78%)
epoch 1.02 1.45 1.05
训练 token 2.29B 3.28B 2.36B
best valFineWeb可比 3.0652 3.0149 2.9801

两个干净的对照:

  1. 同 ~1 epoch、纯放大容量v6 vs v81.02ep → 1.05ep 几乎同数据量dim768 → dim1024 val 3.0652 → 2.9801↓0.085。→ 同样的数据,更大的模型榨出更多v6/v7 在 dim768 上吃不动的, 不全是「数据见够了」,有一部分是模型容量不够capacity-limited
  2. 容量 vs「更多老数据的小模型」v7 vs v8v8dim1024才 1.05ep2.9801 < v7dim7681.45ep 更多数据3.0149,低 0.035。→ 放大容量比「给小模型多喂 0.4 epoch 老数据」更值——这正面回答了 v7 留下的问题:在这本语料上,下一步的杠杆容量 > 重复老数据

⚠️ 但要诚实:增益是 ~3% 的边际,不是质变

v8 的 0.085vs v6 同 epoch2.8% 的 val 改善。这和「数据轴单步杠杆」量级一样薄

  • v5同子集 ×3.5 数据TinyStories val ↓5%
  • v7同子集 ×1.4 epochFineWeb val ↓0.05~1.6%
  • v8容量 +78%dim768→dim1024FineWeb val ↓~3%

元结论:到 v8无论拨数据轴还是容量轴单轴单步的杠杆都收敛到 ~3%/lever = 全面进入边际递减。 这正是 Chinchilla 的教训在小尺度上的复现:容量与数据要匹配地一起 scale,单独猛拨一根轴, 另一根很快成为新瓶颈v8 容量 +78% 但只配同样的 2.36B token所以容量没吃满 → val 末步仍在降 = 数据 这边又成了限制)。

采样对比 —— v7(dim768) vs v8(dim1024)(同 xserv、同贪心、同 prompt

唯一差别是 v8 容量 +78%。喂同样的通用/说明文提示词greedymax 60 token

prompt v7dim768, 1.45ep v8dim1024, 1.05ep
The history of the city of New York is a story of many different people. The first inhabitants… were the Native Americans… the Dutch… the United States is a history of the United States as a nation… a nation of immigrants. (随后陷入 "a nation of immigrants" 重复)
In science, the term "science" is used to describe the study of the natural world… biology, chemistry, physics, and mathematics… the term "biological" refers to the organisms that are alive and have been alive for a long time…随后重复该定义句
The most important thing to remember is that you can't just buy a new car and expect to pay for it… understand the basics of insurance… thing to remember is that the best way to prevent a heart attack is to eat a heart-healthy diet.(随后重复该句)
Water is a natural substance that is found in the earth's crust… a very important element in the Earth's ecosystem… a good thing. It's a good thing to have…随后漂进对话腔 "I'm not sure if you're going to be able to do that"

质量观察(诚实读法):两版都写同一语域的连贯说明文英文没有可感知的质的跃迁——这正是 val 仅 ↓3% 在采样上的体现。更细看:

  • v7 在这组 greedy prompt 上反而信息更具体、更耐读(具体地名/学科列表/事实),尽管也有事实瑕疵;
  • v8 在 greedy 下更快掉进重复循环"a nation of immigrants" ×6、"heart-healthy diet" ×3且 "Water is" 漂出说明文语域进了对话——这更像是**采样路径greedy + 小模型 + 才 1 epoch**的表现,而非容量带来的退步;
  • 两版的小模型重复倾向、轻微事实瑕疵都在。

一句话:val 上 v8 确实更低(容量有用),但在贪心采样的肉眼质量上看不出 v8 明显更好——这与 ~3% 的边际 val 提升完全一致。要把容量优势兑现成可感知的文本质量,多半还需要配套更多数据v8 才 1.05 epoch、val 未饱和)。

xserv 验证

导出 HF Qwen3 safetensors命名映射 + 2D 权重转置 [in,out]→[out,in] + BF16见 T9 docs/08201 tensors config.json hidden_size 1024 / heads 32 / head_dim 32 / intermediate 2730 / layers 18)存入 registryxserv-cli 加载并贪心生成:

$ xserv-cli ~/projects/tiny-models/v8-fineweb-edu-dim1024 --max-tokens 60
Model: qwen3, layers=18, hidden=1024, heads=32/32 kv, vocab=50257
Loaded 201 tensors
Ready (KV cache, dtype=bf16).
xserv> The history of the United States is a history of the United States as a nation. The United States is a
       nation of immigrants…
xserv> In science, the term "biological" refers to the organisms that are alive and have been alive for a long time…
xserv> The most important thing to remember is that the best way to prevent a heart attack is to eat a
       heart-healthy diet…

token-matchxtrain f32 贪心 on ckpt vs xserv BF16 贪心 on 导出权重,同 prompt

  • Once upon a time / The little逐 token 完全一致30/30 byte-identical
  • One day → 前 ~6 token 一致后在一个 BF16 近似平局处分叉xtrain f32 "home from school" / xserv BF16 "along the road in the village of Kambala")——这是 v4v7 一贯报告的 BF16-vs-f32 贪心在近平局处翻拍 的 预期漂移点,非 bug。v8 训练即 bf16fp32 master权重本就在 bf16 数值域收敛,导出 BF16 给 xserv 后两侧 数值路径一致——同全系闭环成立。

xserv 加载 qwen3 layers=18 hidden=1024 201 tensors、KV-cache、贪心生成连贯说明文英文闭环成立。

相比 v6/v7 与 v9 提案

v8 兑现了 v7 提案里的容量轴,并给出一个清晰结论:容量有用v6/v7 在 dim768 上有一部分是 capacity-limited不全是数据见够——但和数据轴一样,单步杠杆只有 ~3%。叠加 v5/v6/v7

  • 数据轴(同子集多 epoch饱和~1.65% / 步。
  • 数据广度换语料v6 唯一的质变(小故事 → 真实说明文),但那是一次性换分布的红利。
  • 容量轴v8有用但 ~3% 边际
  • 所有单轴都已进入 ~3%/lever 的边际递减区

Chinchilla 教训(小尺度复现)v8 容量 +78% 但只配 2.36B token1.05epval 末步仍在降 = 数据这边 立刻成了新瓶颈。要继续进步,容量与数据必须匹配地一起 scale而不是单独猛拨一根轴。v9 选项按此重排:

  1. 双轴一起 scale最符合 Chinchilla真 scale更大模型dim1024+ 或更深)+ 新 FineWeb shards (更多样、不重复 token配上去把 dim1024 喂饱)。⚠️ 投入最大(下载 + 长训 + 磁盘紧需 /dashscope-tmp 暂存)。
  2. dim1024 多喂数据(最便宜,先验证容量能不能吃满)v8 才 1.05 epoch、val 未饱和——直接给 dim1024 续训 到 23 epoch或加新 shards看 val 还能降多少。这是验证「v8 的容量是否被数据卡住」的最低成本实验。
  3. 自然收尾(漂亮里程碑):项目已 8 版 + 从零全栈autograd/backward/AdamW/DDP/bf16/重计算/export+ 完整的数据轴 + 容量轴 + Chinchilla 边际分析——作为一条学习线已经讲完了一个完整的故事。

我的判断:作为工程/学习项目v8 是一个天然的收尾点——8 版把「数据量 / 数据广度 / 容量」三根轴都 测过,并落到「单轴 ~3%、要双轴一起 scale」这个有分量的元结论上全栈基建闭环。若要再做一版首选 2 dim1024 多喂数据):它最便宜、且直接回答 v8 留下的唯一悬念容量被数据卡住的程度——v8 val 未饱和说明 这一版很可能立刻见效;真要追求规模再上 1双轴。详见对比表与 evolution.md 的「容量轴」与「边际递减」两条。