从0训练LLM · 现代大模型体系 阅读 + 实验 ≈ 25 分钟 页内实验 ×1
C1 文字怎么变成数字 第 7 课

Embedding 维度越大越好吗?

维度是一笔预算
维度 d 决定每个 token 能装多少信息,也决定每层参数按 d² 增长。它是靠实验和算力预算选出来的超参数,没有公式能算出「最优的 5,120」。

本课一问:Embedding 维度越大越好吗?

这一课先不碰:宽度、深度、数据量怎么一起定(C6 规模)、模型变宽之后学习率怎么跟着调(C8)。只回答 d 这一个数的取舍。

② 从已有出发

d 不只是 embedding 的长度

累计数据流 · 从文字到下一个 token 的概率 已学本课新增还没学
解码层

点任一已学环节,看这一步的输入 → 输出形状、参数量,以及它解决了什么问题(数字取自 Qwen/Qwen3.8-27B 真实 config)。

贯穿例句「小明把苹果给了小王」查表后是 [5 × 5120]:5 是 token 数,5120 就是本课要问的 d。点开流水线里的每一格看形状:Qwen3.8 从 Embedding 查表出来是 [T × 5120],之后每一层注意力、FFN 的输入输出都是 [T × 5120],一直到 lm_head。d 是贯穿整个模型的宽度(hidden size),embedding 的每一行只是它第一次出现。所以「embedding 维度」一改,整个模型都跟着变宽或变窄。

③ 先自己设计

朴素的想法:维度越大,表示能力越强

对话样本(L581–L601)说得对:维度越高,能装的信息越多。那就开大一点?按我们项目模型的结构,算算每一档宽度的参数:

  1. ① 朴素方案
  2. ② 它在哪失败
  3. ③ 改进方案
朴素方案维度越大越好
④ 改进到现代做法

真实模型的宽度是怎么定的

本课在演进图里的位置:

文字 → 数字的演进:每一步都被上一步的某个真数字逼出来 · 高亮 = 本课
  1. 起点 每个字符直接用 Unicode 码点当编号 最容易想到的做法
    解决了不用训练,任何文字都能编号。
    卡在码点从 0 排到 1,114,111,embedding 表得开 1,114,112 行,是 Qwen3.8 实际 248,320 行的 4.5 倍;而且一个字一个 ID,序列一点不缩短。
  2. 朴素 ① 按字切(字符级词表) 只收语料里出现过的字
    解决了字符集封闭,词表小。
    卡在序列最长:209 字的段落按字切要做 43,681 次注意力打分,是 Qwen3.8 子词切分(106 个 token)的 3.9 倍。
  3. 朴素 ② 按词切 + 固定词表 早期神经机器翻译的做法(Sennrich 2015 的对照组)
    解决了一个词一块,序列短。
    卡在词是开放集合:我们的语料按空白和标点切出 70,310 种块,94.8% 只出现过一次;验证集里连训练集没见过的字都有 83 种——含它们的词只能记成 UNK。
  4. 第一代 子词 BPE(以字符为初始单元) Gage 1994 压缩算法 → Sennrich 2015 用于切词
    解决了按频次反复合并相邻对:常见的整块、罕见的拆碎,词表大小由合并次数控制。
    卡在初始单元是字符:要覆盖全部 Unicode,基础词表就超过 13 万(GPT-2 论文 §2.2);只收见过的字,我们的验证集照样缺 83 种字。
  5. 第二代 字节级 BPE(256 个字节兜底) GPT-2 2019
    解决了初始词表就是 256 个字节,任何文字都能编码,永远不出 UNK。
    卡在词表没学过的语言会被切碎:同义的中文段落,GPT-2 切 461 个 token,Qwen3.8 切 106 个,差 4.3 倍;同义英文段落两者一样多。
  6. 第三代 为多语言训练的大词表 2024–2026
    解决了中文常用字串整块进词表:「我喜欢机器学习」只要 2 个 token(GPT-2 要 17 个)。各家词表:DeepSeek-V3 129,280 · Qwen3 151,936 · GLM-5.3 154,880 · Kimi K3 163,840 · Qwen3.8 248,320。
    卡在两头各一张 V × d 的表:2 × 248,320 × 5,120 = 2,542,796,800 个参数,占 Qwen3.8 的 9.2%;同样的词表搬到我们 d = 256 的小模型上,embedding 占 95.3%。
  7. 表示 ① ID → Embedding 查表 神经语言模型的标准做法
    解决了ID 只是行号,取出一行 5,120 维向量;one-hot 乘矩阵与查表等价,但查表只拷现成的数。
    卡在表里的 1,271,398,400 个数(输入端一张表)从哪来?人填不完,也不知道每一维该是什么意思。
  8. 表示 ② 随机初始化、和整个模型一起训练的 Embedding Bengio 等 2003 → 今天的 LLM
    解决了用「预测下一个 token」的 loss 端到端训练,用法相近的 token 被推到相近的位置。
    卡在只在出现时才被推:我们的项目里一个 batch 8,192 个位置,平均只出现 1,453 个不同 token;罕见 token 学得少——MiniMax 的「嘉祺」在后训练里被推偏,输出层那一行与原来的余弦只剩 0.329。
  9. 表示 ③ 向量该多宽(hidden size d) 各家自选:GPT-2 768 · Qwen3-8B 4,096 · Qwen3.8-2.4T 8,192 · Qwen3.8-27B 5,120 本课
    解决了维度越高,每个 token 能装的信息越多。
    卡在参数按 d² 涨:我们的模型 d 从 128 到 256,总参数 1,066,112 → 3,688,704,val loss 4.776 → 4.641(d = 256 这一档是参照 run ref_baseline,与项目基线同配置同种子;基线记录的 4.626 与它之差是重跑波动,见 C14);没有公式能给出「最优的 d」。
数字口径:码点总数按 Unicode 标准(U+0000–U+10FFFF);词表与宽度取各模型官方 config.json(anchor-model.json、frontier-models.json);token 数取真 Qwen3.8 / GPT-2 分词器的离线切分(c1-tokenize.json);语料统计、batch 覆盖、宽度扫描取项目实测(c1-tokens.json);「13 万以上」出自 GPT-2 论文 §2.2;「嘉祺」的余弦 0.329 出自 MiniMax 官方博客 2026-05-25(官方自报)。

先读我们自己的三档:d 从 64 到 128,总参数 ×3.2,val loss 从 5.073 降到 4.776(降 0.297);从 128 到 256,总参数再 ×3.5,val loss 只再降 0.136。在这个规模上变宽仍然有用,但每一份参数换来的下降在变小——值不值,要和算力、显存、数据量一起看。

上面列出的前沿模型 hidden size——768、2,560、4,096、5,120、6,144、7,168、8,192——有两个共同点:

  1. 全是 256 的整数倍。 这是工程习惯:矩阵的每一维按整块对齐到硬件上算得更快(第 4 课词表补齐是同一个道理),不是从「最优维度」推出来的。
  2. 跟着模型总规模走。 宽度通常和层数、总参数一起按算力预算定;Kaplan 等 2020 的实验发现,在总参数固定时,loss 对「宽还是深」并不敏感——层数与宽度之比变化 40 倍,效果差得不多(例如 6 层、宽 4,288 的模型与 48 层、宽 1,600 的模型,loss 相差在 3% 以内)。真正决定性能的是总规模。
⚠

常见误解:「4,096、5,120 这些数是算出来的最优值」。 没有定理能给出最优的 d。这些数来自「在给定预算下试出来、又对齐了硬件」的工程选择;同一家公司不同规模的模型用不同的 d(Qwen3-8B 是 4,096,Qwen3.8-27B 是 5,120,Qwen3.8-2.4T-A95B 是 8,192)。

🔍 Qwen3.8 的注意力比 d 还宽

Qwen3.8 的 d = 5,120,但它的注意力有 24 个头、每头 256 维,24 × 256 = 6,144,比 d 还大——Q 投影是「升维」的。这说明 d 只是残差流的宽度,每个子层内部可以更宽或更窄(FFN 中间维是 17,408,即 3.4 × 5,120)。C3 第 1 课在 Q、K、V 的形状里标出这一点,第 7 课说明头数 × 每头维数不必等于 d。

⑤ 极小真数字,算一次

参数为什么按 d² 涨:一层拆开数

用我们项目模型的一层来数(结构见 minillm/model.py:多头注意力、SwiGLU FFN、两个 RMSNorm,无 bias):

项目模型一层的参数(d = 256)
+ + =
👆 公式里带下划线的每一项都可以点——点哪项,讲哪项。
d 翻倍时,4d² 与 3·d·h 都约变成 4 倍,所以非 embedding 参数约 ×4;embedding 只是 V × d,线性增长。Qwen3.8 同理:一层 FFN 是 3 × 5,120 × 17,408 = 267,386,880 个参数,64 层 FFN 合计占全模型的 61.6%。
👀

试三件事: ① 在朴素方案里看 d = 64 到 2,048 每翻一倍,非 embedding 参数乘了多少;② 展开改进方案,比较三档 d 的最终 val loss 差了多少、参数差了多少倍——值不值?③ 看前沿模型那一排:每个宽度除以 256 的商是不是都是整数?再想想为什么没有一个模型用 5,000 这样的整数。

⑦ 证据三问

维度怎么选才有依据

⑧ ⑨ ⑩ 带走与下一步

一句话、下一个缺口、你的提问

📌

一句话: 维度 d 决定每个 token 能装多少信息,也决定每层参数按 d² 增长;它是靠实验和算力预算选出来的超参数,没有公式能算出最优值。

下一个缺口:本章结束,下一章开始

到这里,一句话已经变成了一个 [T × 5120] 的矩阵,C1 的主线走完了。但有个漏洞:第 5 课说过,每个 token 的向量只由它的 ID 决定。「小明打了小王」和「小王打了小明」切出的 3 个 token 完全相同,查表得到的是同一组向量,意思却完全相反——这些向量不知道自己在第几个位置。C2:位置——模型怎么知道顺序

你的提问

C1 还没有真实提问记录。你可能会问: