§ 6.2 · Section

模型 · Model

Model · The Brain Waiting to Be Trained

数据是教材,那学生本人呢?模型就是那个等着被训练的"大脑"——它长什么样、有多少神经元、初始状态如何、以什么节奏学习,全部要在动手训练之前定下来。这些选择合起来,就是一个模型的"先天条件"。

先把术语翻译成人话

这一篇满屏都是 B、层数、隐藏维度、MoE,听着玄。说白了整节就在讲一件事:开一家店之前,你得先定厨房多大、灶几个、师傅几位、菜单多宽。先摆一张对照表。

术语换成大白话生活里对应什么
模型(Model)那个等着被训练的"脑子"本身刚盘下来还没开火的一间餐厅
参数量(70B 之类)这个脑子能记多少东西厨房面积——越大能同时开的锅越多
参数(Parameter / 权重)脑子里一根根连线的粗细柜子里备了多少种调料
架构(Architecture)脑子按什么图纸搭厨房的动线图纸:灶、水槽、案板怎么摆
层数 / 隐藏维度层数=工序多少道;维度=每道工序摆得多宽流水线有几个工位、每个工位多长
注意力头数(Heads)同时从几个角度看同一句话几个厨师各盯一件事:火候、咸淡、摆盘
词表(Vocabulary)模型认得多少个"字块"菜单上一共写了多少道菜
MoE 混合专家请一屋子专科师傅,每道菜只叫两三个上手餐厅后厨分红案白案凉菜,各管一摊
初始化(Initialization)开工前所有旋钮拧到哪个位置新店开业前把灶火、冰箱温度先调到标准档
超参数(Hyperparameter)不属于脑子本身,但决定怎么训的那些设定员工作息表:几点开工、一次备多少料
学习率(Learning Rate)每次改进步子迈多大调咸淡时一次加半勺还是一勺
量化(Quantization)把参数存得糙一点,省地方把散装货压成真空包,塞得进小冰箱
生活场景
🧬 挑一个"要培养的孩子"

假设你是育儿专家,一次要培养一个天才少年,摆在你面前的选择有:
脑容量——8B 参数?70B?还是 405B?大脑越大越聪明,但也越贵、越挑食;
大脑结构——是标准的 Transformer 骨架,还是 MoE 稀疏专家,还是 Mamba 状态空间?
初始状态——出生时神经连接是随机杂乱,还是遵循某种"黄金比例"?
学习节奏——每天学多少小时?学多快?多久换一批新题?
这些决定合起来,就叫"选架构 + 调超参"。

一、参数量:模型的"脑容量"

参数是神经网络里的可训练权重——每一根神经元之间的连接强度。参数量越大,理论上模型能表达的函数越复杂、能记住的知识越多。看看这几年的军备竞赛:

模型参数量发布时间备注
GPT-215 亿 (1.5B)2019当时惊为天人
GPT-31750 亿 (175B)2020第一次涌现
GPT-4据传 1.8T (MoE)2023官方从未公布
Llama 38B / 70B / 405B2024开源天花板
DeepSeek-V3671B (MoE, 37B 激活)2024中国开源标杆
Claude / Gemini未公布-推测数百 B 到 T 级

参数量决定了模型的"知识容量上限"。但请注意:参数量不是越大越好,而是要跟数据量匹配——DeepMind 提出的 Chinchilla 缩放定律指出,最优的参数/数据比例大约是 1 : 20:8B 参数最好搭配 160B token 训练;175B 参数最好用 3.5T token;否则要么"营养过剩"要么"营养不良"。

但"参数量"这三个字要落到地上,最有用的换算是它要占多少显存。这是所有本地部署、成本估算、选卡决策的起点。规则很简单:每个参数占多少字节,取决于你用什么精度存它

精度格式每参数字节数1B 参数需要70B 参数需要典型用途
FP32(单精度)4 字节4 GB280 GB早期训练、小模型
FP16 / BF16(半精度)2 字节2 GB140 GB现代训练与推理的默认
FP81 字节1 GB70 GBH100 起支持,DeepSeek-V3 用于训练
INT8 量化1 字节1 GB70 GB推理部署,质量损失很小
INT4 量化0.5 字节0.5 GB35 GB消费级显卡跑大模型的关键

记住这一条心算口诀就够用了:半精度下,显存 GB 数 ≈ 参数 B 数 × 2。一个 7B 模型要 14 GB,塞不进 12 GB 的 RTX 3060,但量化到 4 位只需 3.5 GB,连笔记本都能跑。一个 70B 模型要 140 GB,需要两张 80 GB 的 A100/H100 并联,量化到 4 位则 35-40 GB,一张 48 GB 的 A6000 勉强够。

"140 GB"这个数换个感觉:相当于把 30 部高清电影同时塞进显存并且一刻不能挪走。而"量化到 4 位"这件事说白了就是把散装货压成真空包——同样的东西,占的地方小了四倍,口感掉一点点,但终于塞得进家用冰箱了。

但这只是推理的账。训练的显存开销要大得多,因为除了权重本身,你还得存三样东西:

# 训练一个 N 参数模型的显存账(以混合精度 + AdamW 为例)
权重(BF16)              : 2N 字节
梯度(BF16)              : 2N 字节
AdamW 一阶动量(FP32)    : 4N 字节
AdamW 二阶动量(FP32)    : 4N 字节
FP32 主权重副本           : 4N 字节
                          ───────────
优化器状态小计            : 约 16N 字节

以 7B 模型为例:
    16 × 7e9 = 112 GB   ← 光是状态就超过一张 H100(80GB)
再加上激活值(随批大小和序列长度增长),实际常常翻倍

结论: 训练所需显存 ≈ 推理的 8 到 10 倍
      这就是为什么"能跑"和"能训"是两个完全不同的门槛

这笔账解释了两件事。第一,为什么微调技术(LoRA、QLoRA)这么重要——它们只训练一小部分新增参数,把 16N 的优化器状态压到几乎可以忽略,于是单张消费级显卡也能微调 7B 模型。第二,为什么 ZeRO 这类"把优化器状态切分到多卡上"的技术是训练超大模型的必需品,而不是可选优化。

二、架构选型:Transformer 一统江湖

模型的"骨架"叫架构(architecture)。从 2017 年 Transformer 论文之后,几乎所有主流大模型都是 Transformer 变体:

为什么架构选型这么重要?因为不同架构对同样的数据,学到的东西完全不同。就像让同一个孩子分别用"死记硬背"和"理解推导"两种方法学数学,最终的能力差别巨大。Transformer 之所以赢,就是因为它的"注意力机制"特别适合语言这种长距离依赖的数据——这个我们下一章会详细讲。

把主流模型的真实规格摊开看,你会发现"架构"其实是一组具体数字。下面这张表值得对着读三遍,因为它是理解"模型配置"最直观的入口:

模型参数量层数隐藏维度注意力头数词表大小上下文
GPT-2 small1.24 亿1276812502571024
GPT-2 XL15 亿48160025502571024
GPT-31750 亿961228896502572048
Llama 3 8B80 亿32409632(8 个 KV 头)1282568K→128K
Llama 3 70B700 亿80819264(8 个 KV 头)1282568K→128K
Llama 3 405B4050 亿12616384128(8 个 KV 头)1282568K→128K
DeepSeek-V36710 亿(激活 370 亿)617168128129280128K

这些数字不是随便填的,它们之间有硬性的相互制约。四条最重要的规则:

三、稠密 vs MoE:两条放大路线

缩写先摊开:MoE(Mixture of Experts,混合专家——请一屋子专科师傅,每道菜只叫其中两三个上手)换成大白话,稠密模型是"每道菜全店师傅都得过一遍手",MoE 是"红案的菜只找红案师傅"。前者稳但费人,后者省人但得有个靠谱的派活儿的人(路由器)。

上面那些模型里,DeepSeek-V3 那一行有点特殊:6710 亿参数,但每次只激活 370 亿。这就是 MoE(Mixture of Experts,混合专家)架构,它是过去两年最重要的架构分歧点。

原理并不复杂。传统"稠密"模型每生成一个 token,都要让数据流过全部参数。MoE 把每层的 FFN 拆成很多个小 FFN(叫"专家"),前面加一个路由器(router)——一个小小的线性层,负责给每个 token 打分,决定送给哪几个专家处理。

# MoE 层的核心逻辑(简化)
def moe_layer(x, experts, router, top_k=2):
    scores = softmax(router(x))            # 对 N 个专家打分
    idx = topk_indices(scores, k=top_k)    # 只选前 k 个
    out = 0
    for i in idx:
        out += scores[i] * experts[i](x)   # 加权求和
    return out
    # 假设有 256 个专家,只激活 8 个
    # → 总参数 = 256 份,实际计算 = 8 份 → 省 32 倍算力

# DeepSeek-V3 的实际配置
专家数     : 每层 256 个路由专家 + 1 个共享专家
激活数     : 每 token 选 8 个
总参数     : 671B
激活参数   : 37B     ← 推理开销只相当于一个 37B 稠密模型
训练成本   : 278.8 万 GPU 小时(约 557 万美元)

MoE 的诱惑在于它解耦了"知识容量"和"计算成本"。稠密模型这两者是绑死的:想装更多知识,就必须付更多算力。MoE 让你可以只花 37B 的推理成本,享受 671B 的知识储备。DeepSeek-V3 用 557 万美元的训练成本做出接近 GPT-4o 的效果,MoE 是最关键的一块拼图。

维度稠密(Dense)MoE 稀疏
推理算力与参数量成正比只和激活参数相关,便宜得多
显存占用= 参数量= 总参数量(全部要装载),这是它的硬伤
训练稳定性成熟、可预测路由容易失衡,需要负载均衡损失
微调难度标准流程较难,路由容易被小数据集破坏
适合场景本地部署、小尺寸模型云端大规模服务、追求性价比
代表Llama 3、Qwen 稠密版Mixtral 8×7B、DeepSeek-V3、GPT-4(推测)

MoE 最麻烦的工程问题叫负载不均衡:路由器如果学"偷懒",可能把 90% 的 token 都送给同几个专家,剩下的专家从没被训练过,等于白占参数。解法是在损失函数里加一项负载均衡惩罚,逼路由器把流量摊开。DeepSeek-V3 更进一步用了"无辅助损失的负载均衡"——通过动态调整每个专家的偏置项来平衡流量,避免辅助损失干扰主任务。这类细节说明 MoE 不是"稠密模型加个开关",它是一套需要单独调教的体系。

"负载不均衡"这四个字翻译成人话就是:派活儿的人偷懒,天天只找那两三个熟手,其他师傅在后厨闲站着领工资。结果是你按 256 个人的编制付了钱,实际干活的一直是那 8 个——好比车间里明明八条流水线,工单全压给一条,那条累死,另外七条空转。负载均衡惩罚干的活儿就是给派活儿的人立个规矩:必须把单子摊开发。

Analogy · 模型架构 = 楼房结构

如果说训练数据是砖头,那模型架构就是建筑蓝图。同样一堆砖,你按四合院图纸盖,就是四合院;按摩天大楼图纸盖,就是 100 层高楼。Transformer 就是当代 AI 世界里"最靠谱的摩天大楼蓝图"——扎实、可扩展、几乎所有名楼都照它盖。

Analogy · 模型大小 = 厨房面积,参数 = 调料种类

想象一下你要开一家餐厅参数量好比厨房面积:8B 是个能炒两个菜的家用厨房,70B 是能同时开八个灶的酒店后厨,405B 是那种能给婚宴出五百桌的中央车间参数本身好比柜子里的调料种类——只有盐和酱油,你做不出复杂的菜;备齐三百种调料,能做的菜系一下就宽了。

顺着这个场景,本节几个数字全都能落地:
层数 vs 宽度——层数相当于流水线上有几道工序(洗、切、腌、炒、摆盘),宽度相当于每道工序摆几个案板工序太少做不出复杂的菜,工序太多、每道又太窄,前面等后面,整条线全在排队。这就是"深还是宽"要权衡的原因。
MoE——相当于后厨请了 256 位专科师傅(红案、白案、凉菜、面点……),但每道菜只叫其中 8 位上手。工资得给 256 个人发(显存要装全部参数),可每道菜的人力只花 8 份(算力只按激活参数算)——这就是 DeepSeek-V3 用 671B 的本事、只付 37B 的账的全部秘密。
量化——好比把散装食材压成真空包,同样的货塞进小得多的冰箱。压得狠了口感会掉一点,但能让原本要两台工业冰柜的货塞进家用冰箱
初始化——相当于开业前把每个灶的火力、每台冰箱的温度都先拧到标准档。全都拧到零,这店根本开不了火;随手乱拧,第一天就得炸厨房。

说白了:这一整节讲的都不是"怎么做菜",而是"开店之前该把店盘成什么样"。菜怎么做是下一篇的事(训练),这一篇只管先天条件。

四、权重初始化:出生时的"起点"

模型架构定了,参数量定了——但每一个参数的初始值该设成多少?全设成 0 行不行?答案是:绝对不行。如果所有参数都是 0,那所有神经元的输出都相同,反向传播的梯度也都相同——网络永远学不出任何有意义的东西,这叫"对称性问题"。

那随机初始化行不行?可以,但也有讲究:如果初始值太大,激活函数会饱和(sigmoid、tanh),梯度消失;如果太小,信号一层层传下去就淹没了。所以业界发明了几种精心设计的初始化方法:

本质上,好的初始化就是给模型一个"不偏不倚的起点"——像跑步比赛前所有选手站在同一条起跑线,谁也不比谁多占一步。

Xavier 和 He 这两个名字背后的推导直觉值得讲清楚,因为它出人意料地简单。核心目标只有一句话:让信号在逐层传播时,方差既不放大也不缩小

假设某一层有 n_in 个输入,输出是 y = Σ w_i · x_i。如果各项独立,那么 Var(y) = n_in · Var(w) · Var(x)。要让 Var(y) = Var(x),就必须让 Var(w) = 1 / n_in。这就是 Xavier 初始化的全部推导——Glorot 和 Bengio 在 2010 年同时考虑前向和反向,取了输入输出的平均,得到 Var(w) = 2 / (n_in + n_out)

He 初始化(何恺明等,2015)多了一步观察:如果激活函数是 ReLU,它会把一半的输入直接砍成 0,等于让方差减半。要补回来,就得把权重方差加倍:Var(w) = 2 / n_in。就这一个"×2",让上百层的深度网络第一次能稳定训练起来。

# 三种初始化的实际差别(以 n_in=1024, n_out=1024 为例)
全零初始化      : std = 0        → 所有神经元完全对称,永远学不动
朴素高斯 N(0,1) : std = 1.0      → 逐层放大 32 倍,第 5 层就数值爆炸
Xavier          : std = √(2/2048) ≈ 0.031   ← 适合 tanh / sigmoid
He (Kaiming)    : std = √(2/1024) ≈ 0.044   ← 适合 ReLU / GELU

# 大模型的额外一招:按深度缩放残差分支
# GPT-2 论文:把残差分支的输出权重再乘 1/√(2 × 层数)
# 目的:防止 N 层残差累加后方差线性增长
std_residual = 0.02 / math.sqrt(2 * n_layers)

最后那个细节在大模型上尤其关键。Transformer 是残差结构,每层的输出都加回主干上,N 层叠加会让方差涨 N 倍。GPT-2 的做法是把残差分支的输出投影权重按 1/√(2N) 缩小;Llama 系列则依赖 RMSNorm 和精心调过的标准差(常用 0.02)来控制。初始化在小模型上是"调优",在百层大模型上是"能不能训起来"的生死问题——一个 405B 模型跑崩一次,损失就是几十万美元的算力。

五、超参数:训练前的"作息表"

"超参数"这名字最容易让人望而生畏,其实就是开工前定下的那张作息表和工作规矩:一次备多少料(批大小)、调味一次加多少(学习率)、开工前先热几分钟锅(warmup)。它们不属于模型这个"脑子",但决定这个脑子被怎么带。

还有一堆参数不属于模型本身,但决定训练的过程,叫超参数(hyperparameters)

超参数含义典型值
学习率 Learning Rate每步权重更新的步长1e-5 ~ 1e-3
批大小 Batch Size每次训练用多少条样本32 ~ 4096(大模型上百万)
训练轮数 Epochs整个数据集过几遍大模型通常只过 1-3 遍
层数 LayersTransformer 的深度12 (GPT-2) ~ 126 (Llama 405B)
隐藏维度 Hidden Size每层的"宽度"768 ~ 16384
注意力头数 Heads并行的注意力子空间数12 ~ 128
Dropout训练时随机丢弃的比例0 ~ 0.1
Warmup Steps学习率从 0 慢慢升起的步数数百到数千

超参数为什么重要?举一个真实故事:同一个模型架构,同一份数据,学习率从 3e-4 改到 3e-5,最终效果可能相差 5 个 MMLU 百分点。这就是为什么大模型团队要花几百万美元跑"超参搜索"——每一次实验都是烧钱,但值得。

更麻烦的是:大模型无法做超参搜索。你不可能把 405B 模型训 50 遍来试学习率。所以业界的做法是在小模型上搜,再按缩放规律外推到大模型。有几条已经被反复验证的经验定律:

下面这张表把主流模型公开的真实超参放在一起,比任何教科书上的"典型值"都有说服力:

模型峰值学习率批大小(token)warmup权重衰减梯度裁剪
GPT-3 175B0.6e-4320 万3.75 亿 token0.11.0
Llama 2 70B1.5e-4400 万2000 步0.11.0
Llama 3 405B8e-5400 万 → 1600 万8000 步0.11.0
DeepSeek-V32.2e-4逐步升至 6273 万2000 步0.11.0

六、Chinchilla 最优配比:算力该怎么花

现在把参数量和数据量放在一起考虑。假设老板给你 1000 万美元算力预算,你该训一个"大模型少数据"还是"小模型多数据"?2022 年 DeepMind 的 Chinchilla 论文给出了第一个可计算的答案。

他们训了 400 多个不同规模的模型,拟合出的结论是:在固定算力预算下,参数量 N 和 token 数 D 应该同比例增长,最优比约为 D ≈ 20N。同时给出了那条著名的算力公式:C ≈ 6ND(训练所需 FLOPs 约等于 6 倍的参数量乘 token 数)。

# Chinchilla 三件套:给定算力,反推最优配置
C = 6 · N · D          # 总算力(FLOPs)
D = 20 · N             # 最优数据量
→ C = 120 · N²  →  N = √(C / 120)

# 例:手上有 1e24 FLOPs 的预算
N = √(1e24 / 120) ≈ 9.1e10  →  约 91B 参数
D = 20 × 9.1e10  ≈ 1.8e12   →  约 1.8T token

# 验算 GPT-3(实际 175B 参数、300B token)
按 Chinchilla,175B 参数应配 3.5T token
它只用了 300B → 只有应有量的 8.6%  →  严重欠训
DeepMind 用 70B + 1.4T 训出的 Chinchilla 打败了 GPT-3
同样算力,参数减 60%、数据增 4.7 倍 → 效果反超

但这条定律有一个被广泛误读的地方,必须说清:Chinchilla 最优的是"训练算力",不是"总体成本"。一个模型训完之后要服务几亿次请求,推理成本会远超训练成本。所以从商业角度,你宁愿多花训练算力去"过训"一个小模型——推理时每一次调用都省钱。

这就是为什么 2023 年之后所有模型都远远超过 Chinchilla 建议值:Llama 3 8B 用了 15 万亿 token,是建议值(1600 亿)的 94 倍。它在训练算力上"浪费"了,但换来一个能在单张显卡上跑、推理便宜 50 倍的模型。Chinchilla 回答的是"怎么用最少算力达到某个损失",而工业界真正关心的是"怎么用最低总成本服务用户"——这是两个不同的优化目标。

七、层数 vs 宽度:深还是宽

一个有趣的问题:给定同样的参数预算(比如 10B),是把网络堆得更深(100 层每层 1000 维),还是更宽(20 层每层 5000 维)?经验规律是:先增宽、再增深——太深会梯度消失、训练不稳定;太宽会计算不高效。Llama 3 8B 是 32 层 × 4096 维;70B 是 80 层 × 8192 维——你能看出比例上的讲究。

这个"讲究"是有量化规律的。Kaplan 等人 2020 年的缩放定律论文发现了一个重要事实:在参数量固定的情况下,模型的损失对"深宽比"非常不敏感——只要宽高比落在一个很宽的合理区间内,效果差不多。也就是说,形状不太重要,总参数才重要。这在当时是个解放性的结论,意味着你可以按工程便利去选形状。

但工程上的偏好非常明确,两个理由都跟硬件有关:

反过来,深度也有它不可替代的价值:推理的"步数"上限。直观地说,模型每一层可以看作一次"信息变换",需要多步组合的推理任务(比如"A 的父亲的老师的国籍是什么")就需要足够的层数来串联。有研究显示,在同参数量下,更深的模型在多步推理任务上略有优势,而更宽的模型在知识记忆类任务上略强。深度换推理,宽度换记忆——这是一个粗糙但好用的直觉。

模型层数 : 宽度宽深比观察
GPT-2 small12 : 76864小模型偏窄
GPT-3 175B96 : 12288128放大时宽度涨得更快
Llama 3 8B32 : 4096128与 GPT-3 同比例
Llama 3 70B80 : 8192102略偏深
Llama 3 405B126 : 16384130回到约 128 这条线

看最后一列的规律:宽深比长期稳定在 100 到 130 之间。这不是巧合,而是几百次实验之后收敛出来的工程共识。你要设计一个新模型,从这条线出发几乎不会错。

八、模型并行:一个模型怎么塞进上万张卡

四种切法用车间就能讲明白:数据并行=开八条一样的流水线,各干一批货;张量并行=一道工序太重,四个人围着同一个案板一起干;流水线并行=按工序拆开,前十道在这个车间、后十道在那个车间ZeRO=别每个工位都备一整套工具,共用一个仓库,用的时候去取。

一个 405B 模型光权重就要 810 GB,训练状态要 6 TB 以上——它物理上不可能装进任何一张卡。所以"配置一个大模型"必然包含一个问题:怎么把它切开分到几千张卡上?这里有四种正交的切法,实际训练中要组合使用。

并行方式切什么通信量通信发生在主要作用
数据并行 DP切数据批次,每卡一份完整模型每步同步全部梯度集群内任意位置皆可提高吞吐,不省显存
张量并行 TP切单层内的矩阵(按行/列)极高,每层两次 all-reduce必须在同一节点内(NVLink)省显存,降低单卡负担
流水线并行 PP按层切,前 20 层在卡 A,后 20 层在卡 B低,只传层间激活可跨节点(InfiniBand)省显存,但有气泡
ZeRO / FSDP切优化器状态、梯度、参数中等,用时再收集跨节点大幅省显存,改动最小
专家并行 EP把 MoE 的不同专家放不同卡中等,all-to-all 路由跨节点MoE 模型专用
上下文并行 CP按序列长度切中等节点内优先训练超长上下文用

ZeRO(微软 DeepSpeed 提出,PyTorch 里对应 FSDP)是最值得单独理解的一个,因为它的思路特别漂亮。回到前面算过的那笔账:训练显存的大头是 16N 的优化器状态。ZeRO 的洞察是——这些状态在数据并行的每张卡上都是完全一样的副本,纯属浪费。那就把它们切开,每张卡只存 1/N 份,需要时再临时收集。

# ZeRO 的三个阶段,省显存力度递增
ZeRO-1: 只切优化器状态         → 省 4 倍,通信不增加
ZeRO-2: 再切梯度               → 省 8 倍,通信不增加
ZeRO-3: 连参数也切(= FSDP)   → 省 N 倍(N=卡数),通信增加约 50%

# 以 64 张卡训练 7B 模型为例(单卡显存需求)
不用 ZeRO : 权重14 + 梯度14 + 优化器84  = 112 GB  ← 装不下
ZeRO-1    : 14 + 14 + 84/64  ≈  29 GB
ZeRO-2    : 14 + 14/64 + 84/64 ≈ 16 GB
ZeRO-3    : (14+14+84)/64      ≈ 1.8 GB  ← 一张消费卡都够

# Llama 3 405B 的实际组合(16384 张 H100)
张量并行 TP=8     (节点内 8 卡,走 NVLink 高速互联)
流水线并行 PP=16  (跨 16 个节点分层)
上下文并行 CP=?   (长上下文阶段启用)
数据并行 DP=128   (最外层,配 FSDP 切状态)
→ 8 × 16 × 128 = 16384 张卡

为什么要这么复杂地组合?因为每种并行都有它的通信代价与拓扑约束。张量并行每层要做两次 all-reduce,通信量极大,只有节点内 NVLink 的 900 GB/s 带宽扛得住,跨节点走 InfiniBand(约 400 Gb/s)会直接把训练拖垮——所以 TP 的规模几乎永远等于单节点的卡数(通常是 8)。流水线并行通信量小,适合跨节点,但会产生"气泡":第一张卡算完第 1 层要等最后一张卡回传梯度,中间大量空转,需要用 micro-batch 交错来填。

这些并行策略最终决定了一个关键指标:MFU(Model FLOPs Utilization,模型算力利用率)——你实际用上了 GPU 峰值算力的百分之几。Llama 3 405B 训练时报告的 BF16 MFU 约为 38%-43%。听起来不高,但这已经是世界级水平:超过一半的理论算力,都消耗在了搬数据、等同步、填气泡上——分布式训练的真正对手不是计算,是通信。

"MFU 40%" 相当于一条流水线上,工人真正动手干活的时间只占四成,另外六成在等上一道工序、等物料从仓库运到、等旁边工位对齐进度。说白了:这上万张卡里有一大半时间在排队,而不是在算。好比雇了一万个厨师,其中六千个随时都在等叫号。

九、"配置一个模型"的完整清单

把上面这些放在一起,训练一个大模型前,工程师要在一张 yaml 配置里定义大概这些东西:

这张配置表,就是这个"待培养的天才少年"的完整先天档案。

为了让它变成可触摸的东西,下面是一份接近真实的 7B 模型训练配置。你会发现前面讲的每一个概念,都在这里对应一行:

# config.yaml — 一个 7B 稠密模型的完整先天档案
model:
  architecture: llama          # Decoder-only Transformer
  n_layers: 32                 # 深度
  hidden_size: 4096            # 宽度  →  12 × 32 × 4096² ≈ 6.4B
  n_heads: 32                  # 4096 / 32 = 128 维每头
  n_kv_heads: 8                # GQA:KV 头只有 8 个,省 4 倍 KV Cache
  ffn_hidden: 14336            # SwiGLU,约 3.5 倍扩展
  vocab_size: 128256           # 嵌入层就占 5.25 亿参数
  max_seq_len: 8192
  norm: rmsnorm                # 比 LayerNorm 少算均值,快约 10%
  pos_encoding: rope           # 旋转位置编码,支持外推
  rope_theta: 500000           # 加大 theta 是为了后续扩长上下文
  tie_word_embeddings: false    # 大模型不共享输入输出嵌入

init:
  method: normal
  std: 0.02
  scale_residual_by_depth: true   # 残差分支 × 1/√(2×32)

optim:
  optimizer: adamw
  lr: 3.0e-4                   # 7B 规模的典型峰值
  betas: [0.9, 0.95]           # 注意 beta2 是 0.95 不是默认的 0.999
  eps: 1.0e-8
  weight_decay: 0.1            # 排除 norm 与 bias
  grad_clip: 1.0               # 全局梯度范数裁剪
  scheduler: cosine
  warmup_steps: 2000
  min_lr_ratio: 0.1            # 衰减到峰值的 10% 而非 0

train:
  precision: bf16              # 主流选择,动态范围比 fp16 大
  global_batch_tokens: 4194304 # 400 万 token / step
  micro_batch_size: 4
  grad_accum: auto
  total_tokens: 2.0e12         # 2 万亿 token
  seed: 42

parallel:
  tensor_parallel: 2
  pipeline_parallel: 1
  zero_stage: 3                # = FSDP,切一切
  activation_checkpointing: true  # 用重算换显存,慢约 30%

checkpoint:
  save_every_steps: 500        # 万卡集群必须频繁存盘
  keep_last: 5

注意几个容易被忽略的细节。betas: [0.9, 0.95]——大模型几乎都把 AdamW 的第二个动量系数从默认 0.999 调到 0.95,因为大批量训练时梯度统计已经足够稳,用更短的记忆窗口反应更快。min_lr_ratio: 0.1——学习率不衰减到 0 而是留 10%,为的是保留一点继续训练的余地。activation_checkpointing: true——不保存中间激活值,反向传播时重新算一遍,用 30% 的速度换掉大部分激活显存,这是训练长序列的标准操作。

最后提醒一句现实:这份配置的每一个数字,都可能因为一个小错误让几百万美元的算力打水漂。这就是为什么真正的大模型团队会先用 1B 规模跑几十次"缩放实验"验证配置,确认损失曲线符合预期,才敢按下大规模训练的开始按钮。

Recap · 收束

模型是训练开始之前,就要决定的一切"先天"——多少参数、什么架构、如何初始化、怎么调节奏。这些配置里的每一个数字,都可能让最终效果相差几个百分点。好的模型 = 合适的架构 × 匹配的参数量 × 合理的初始化 × 精调的超参数。做完这些,你才拥有了一个"值得砸算力去训练"的胚子。

九条要点收束这一节:(1) 参数量最实用的换算是显存——半精度下 GB 数 ≈ B 数 × 2,7B 要 14 GB,70B 要 140 GB;(2) 但训练要 16N 字节的优化器状态,是推理的 8-10 倍,这就是"能跑"和"能训"的鸿沟;(3) 架构是一组互相制约的数字,记住 参数量 ≈ 12 × 层数 × 维度²每头维度固定在 128 这两条,你能反推任何模型的配置;(4) MoE 解耦了知识容量与计算成本——DeepSeek-V3 用 671B 的知识、37B 的算力、557 万美元训出来,但显存仍要装全部参数;(5) 初始化的全部直觉是"让方差逐层守恒",Xavier 是 2/(n_in+n_out),He 因为 ReLU 砍掉一半而取 2/n_in(6) 超参有铁律:模型越大学习率越小、批大小随进程增长、权重衰减固定 0.1、beta2 用 0.95(7) Chinchilla 的 20:1 优化的是训练算力,而工业界要优化总成本,所以 Llama 3 8B 故意"过训"了 94 倍;(8) 宽深比长期稳定在 100 到 130,深度换推理、宽度换记忆;(9) 上万张卡靠 TP × PP × DP × ZeRO 四维切分组合,而 MFU 只有 38%-43% 说明了一切——大模型训练真正的对手不是计算,是通信。

☰ 主页
Xue Hai Wu Ya · § 6.2 · Model