前言

在前面的几篇文章中,我们已经补完了 LLaMA 的两个重要基础:

第一篇补了 Tokenizer、BPE、SentencePiece,解决了“大模型如何读文字”的问题。
第二篇拆了 LLaMA Transformer Block,理解了 RMSNorm、Attention、RoPE、FFN、SwiGLU、Residual Connection 这些结构。

但是只懂结构还不够。

因为 LLaMA 这篇论文最值得学习的地方,并不是它发明了一个全新的 Transformer,而是它告诉我们:

一个强大的基础语言模型,不一定靠疯狂堆参数,而是靠合理的数据规模、模型规模、训练配方和工程实现共同堆出来。

LLaMA 的核心特点可以概括成一句话:

小模型,充分训练,公开数据,高效推理。

这篇文章要解决的问题是:

  1. 为什么 LLaMA 13B 可以在多数 benchmark 上超过 GPT-3 175B?
  2. Chinchilla Scaling Law 到底告诉了我们什么?
  3. 为什么大模型训练不能只堆参数,还要看 token 数?
  4. AdamW 到底比 Adam 多做了什么?
  5. Weight Decay 和 L2 正则到底有什么区别?
  6. Cosine Learning Rate Schedule 为什么适合大模型训练?
  7. Activation Recomputation、Model Parallelism、Sequence Parallelism 这些工程手段在解决什么问题?
  8. LLaMA 的实验 benchmark 到底在测什么能力?
  9. LLaMA 的实验结果应该怎么看,而不是只背分数?

这篇文章会比较长,因为它把 训练方法实验评价 放在一起讲。
原因也很简单:

训练配方决定模型能力,实验评价证明这些能力。

如果只讲训练,不看实验,就不知道这些训练策略到底有没有效果。
如果只看实验,不懂训练,又会误以为模型强只是因为“参数大”。


一、LLaMA 的核心问题:为什么不是越大越好?

在 GPT-3 之后,很多人对大模型形成了一个直觉:

模型越大,效果越好。

这个直觉不是完全错,但不完整。

GPT-3 有 175B 参数,展示出了很强的 few-shot 能力。
但是后来研究者发现,很多大模型虽然参数巨大,却没有被充分训练。

这是什么意思?

假设你有一个非常大的模型,它有很强的记忆容量和表达能力。
但是你只给它看很少的数据,它就像一个很聪明的学生,只刷了一点题。

结果可能是:

模型很大,但训练不充分;
参数很多,但很多能力没有被真正激发;
推理很贵,但性能提升并不划算。

LLaMA 的思路不是继续盲目扩大参数,而是问了一个更实际的问题:

如果我训练一个更小的模型,但喂给它更多 token,它能不能比更大的模型更强?

LLaMA 的答案是:可以。

这也是为什么 LLaMA-13B 只有 GPT-3 175B 的十几分之一大小,却能在多数 benchmark 上超过 GPT-3。


二、Scaling Law:参数量、数据量和计算量之间的关系

2.1 什么是 Scaling Law?

Scaling Law,中文可以叫 缩放规律

它研究的是:

当模型参数量、训练数据量、训练计算量发生变化时,模型性能会如何变化。

在大模型训练中,最常见的三个变量是:

N:模型参数量
D:训练 token 数
C:训练计算量

其中:

  • (N):Number of Parameters,模型有多少参数;
  • (D):Dataset Size,用 token 数表示训练数据规模;
  • ©:Compute,训练消耗的计算量。

直观来说:

参数量 N 决定模型容量;
数据量 D 决定模型能学习多少信息;
计算量 C 决定模型能训练到什么程度。

早期的 scaling law 研究发现,模型越大、数据越多、计算越多,loss 通常会下降。

可以粗略写成:

L(N,D)≈AN−α+BD−β L(N,D) \approx A N^{-\alpha} + B D^{-\beta} L(N,D)ANα+BDβ

这个公式逐项解释:

  • (L(N,D)L(N,D)L(N,D)):模型在参数量为 (N)、数据量为 (D) 时的 loss;
  • (NNN):模型参数量;
  • (DDD):训练 token 数;
  • (A,BA, BA,B):经验常数;
  • (α,β\alpha, \betaα,β):经验指数;
  • (N−αN^{-\alpha}Nα):参数量增加时,loss 会下降;
  • (D−βD^{-\beta}Dβ):数据量增加时,loss 也会下降;
  • (≈\approx):这是经验近似,不是数学上的绝对定理。

这个公式想表达的是:

模型变大有用,数据变多也有用,但二者都有边际收益递减。

也就是说,不能无限堆一个变量,而不管另一个变量。


2.2 Chinchilla 是什么?

讲 LLaMA,就必须讲 Chinchilla

Chinchilla 是 DeepMind 在 2022 年提出的一个 70B 参数语言模型。它最重要的贡献不是模型名字本身,而是提出了一个影响很大的训练结论:

在固定计算预算下,很多过去的大模型参数太多、训练数据太少,属于 undertrained,也就是欠训练。

这句话非常重要。

什么叫欠训练?

可以这样理解:

模型容量很大,
但是训练 token 不够,
模型还没有充分吸收数据规律,
训练就结束了。

GPT-3 有 175B 参数,但训练 token 数大约是 300B 级别。
从后来的 Chinchilla 观点看,这种配置更偏向“参数很多,但数据相对不足”。

Chinchilla 的核心思想是:

参数量和训练 token 数应该一起增长,而不是只增长参数量。


2.3 Chinchilla Scaling Law:多少参数需要多少 token?

Chinchilla 给出了一个非常好记的经验比例:

D≈20N D \approx 20N D20N

这个公式很重要,我们慢慢解释。

  • (D):训练 token 数;
  • (N):模型参数量;
  • (20):经验比例,表示大约每 1 个参数需要 20 个训练 token;
  • (≈\approx):大约等于,说明这是经验规律,不是严格定理。

举例来说:

如果模型有 1B 参数,那么建议训练 token 数大约是:

D≈20×1B=20B D \approx 20 \times 1B = 20B D20×1B=20B

如果模型有 7B 参数,那么建议训练 token 数大约是:

D≈20×7B=140B D \approx 20 \times 7B = 140B D20×7B=140B

如果模型有 70B 参数,那么建议训练 token 数大约是:

D≈20×70B=1400B=1.4T D \approx 20 \times 70B = 1400B = 1.4T D20×70B=1400B=1.4T

这里的 (T) 是 trillion,也就是万亿。

所以可以得到一张直观表:

模型参数量 Chinchilla 经验建议训练 token 数
1B 20B tokens
7B 140B tokens
13B 260B tokens
33B 660B tokens
65B 1.3T tokens
70B 1.4T tokens
175B 3.5T tokens

这个表能帮助我们理解 LLaMA 的训练策略。


2.4 LLaMA 如何利用 Scaling Law?

LLaMA 论文中的几个模型规模是:

模型 参数量 训练 token 数
LLaMA-7B 6.7B 1.0T
LLaMA-13B 13.0B 1.0T
LLaMA-33B 32.5B 1.4T
LLaMA-65B 65.2B 1.4T

注意这里最关键的是:

LLaMA 的小模型训练 token 数远远超过 Chinchilla 的 20 tokens/parameter 经验比例。

例如 LLaMA-7B:

按照 Chinchilla 粗略经验:

D≈20N=20×7B=140B D \approx 20N = 20 \times 7B = 140B D20N=20×7B=140B

但 LLaMA-7B 实际训练了约 1T tokens。

也就是说:

LLaMA-7B 被训练得非常充分。

LLaMA-13B 也是一样。

按照经验比例:

D≈20N=20×13B=260B D \approx 20N = 20 \times 13B = 260B D20N=20×13B=260B

但 LLaMA-13B 实际训练了约 1T tokens。

这就解释了为什么 LLaMA-13B 能挑战 GPT-3 175B。

它不是靠参数量赢,而是靠:

更充分的训练 token;
更好的数据配比;
更高效的结构细节;
更稳定的训练配方。

三、LLaMA 的数据策略:公开数据也能训练强模型

LLaMA 论文另一个重要特点是:

它只使用公开可获得的数据训练。

这和很多闭源模型不同。
很多大模型的数据细节并不完全公开,而 LLaMA 强调自己的数据来源公开、可复现程度更高。

LLaMA 的训练数据主要包括:

数据源 作用
CommonCrawl 大规模网页文本,提供通用语言能力
C4 清洗后的网页数据,提高质量
GitHub 代码数据,提高代码和结构化文本能力
Wikipedia 百科知识和多语言知识
Books 长文本、叙事、逻辑表达
ArXiv 科学论文、公式、学术语言
StackExchange 问答、技术讨论、解释型文本

这套数据组合非常有代表性。

CommonCrawl 提供规模。
Wikipedia 和 Books 提供知识和语言质量。
GitHub 提供代码能力。
ArXiv 提供学术表达和数学符号。
StackExchange 提供问答和解释风格。

所以 LLaMA 的能力不是凭空出现的,它来自训练数据的覆盖面。


四、训练目标:LLaMA 到底在学什么?

LLaMA 是一个 Decoder-only autoregressive language model

它的训练目标是:

给定前面的 token,预测下一个 token。

这个目标可以写成语言模型 loss:

LLM=−∑t=1Tlog⁡pθ(xt∣x<t) \mathcal{L}_{LM}= -\sum_{t=1}^{T}\log p_\theta(x_t \mid x_{<t}) LLM=t=1Tlogpθ(xtx<t)

逐项解释:

  • (LLM\mathcal{L}_{LM}LLM):语言模型损失函数;
  • (TTT):当前训练序列的长度;
  • (ttt):当前位置;
  • (xtx_txt):第 (t) 个真实 token;
  • (x<tx_{<t}x<t):第 (t) 个 token 前面的所有 token;
  • (pθ(xt∣x<t)p_\theta(x_t \mid x_{<t})pθ(xtx<t)):模型在看到前文后,预测真实 token (x_t) 的概率;
  • (θ\thetaθ):模型参数;
  • (log⁡\loglog):对概率取对数;
  • 负号 (-):因为训练时要最小化 loss,而我们希望真实 token 的概率越大越好。

这个公式的直觉是:

如果模型给真实 token 很高概率,loss 就小;
如果模型给真实 token 很低概率,loss 就大。

例如句子:

The capital of France is Paris.

模型在看到:

The capital of France is

之后,应该给 Paris 较高概率。

训练过程就是不断重复这个任务:

看前文 → 猜下一个 token → 算错多少 → 更新参数

这就是大语言模型的基本训练方式。


五、AdamW:大模型参数到底怎么更新?

训练模型的本质是更新参数。

但是参数怎么更新,不是随便做的。
这就需要 optimizer,优化器

LLaMA 使用的是 AdamW

要理解 AdamW,我们先从最简单的 SGD 开始。


5.1 SGD:最简单的梯度下降

SGD 全称是 Stochastic Gradient Descent,中文叫 随机梯度下降

它的更新公式是:

θt+1=θt−ηgt \theta_{t+1}=\theta_t-\eta g_t θt+1=θtηgt
逐项解释:

  • (θt\theta_tθt):第 (t) 步时的模型参数;
  • (θt+1\theta_{t+1}θt+1):更新后的模型参数;
  • (η\etaη):learning rate,学习率,控制每一步走多大;
  • (gtg_tgt):第 (t) 步的梯度;
  • (−ηgt-\eta g_tηgt):沿着让 loss 下降的方向更新参数。

这个公式的意思是:

参数朝着 loss 下降最快的方向走一步。

但是 SGD 有一个问题:
它对所有参数使用同一个学习率,不够灵活。


5.2 Adam:给每个参数自适应步长

Adam 全称是 Adaptive Moment Estimation

它比 SGD 更复杂,也更适合大模型训练。

Adam 会维护两个统计量:

一阶动量:梯度的滑动平均
二阶动量:梯度平方的滑动平均

一阶动量公式:

mt=β1mt−1+(1−β1)gt m_t = \beta_1 m_{t-1} + (1-\beta_1)g_t mt=β1mt1+(1β1)gt

逐项解释:

  • (mtm_tmt):第 (t) 步的一阶动量;
  • (mt−1m_{t-1}mt1):上一步的一阶动量;
  • (β1\beta_1β1):控制历史梯度保留多少的系数;
  • (gtg_tgt):当前梯度;
  • ((1−β1)gt(1-\beta_1)g_t(1β1)gt):当前梯度对动量的贡献。

一阶动量可以理解为:

最近一段时间梯度主要往哪个方向走。

二阶动量公式:

vt=β2vt−1+(1−β2)gt2 v_t = \beta_2 v_{t-1} + (1-\beta_2)g_t^2 vt=β2vt1+(1β2)gt2

逐项解释:

  • (vtv_tvt):第 (t) 步的二阶动量;
  • (vt−1v_{t-1}vt1):上一步的二阶动量;
  • (β2\beta_2β2):控制历史梯度平方保留多少的系数;
  • (gt2g_t^2gt2):当前梯度的平方;
  • ((1−β2)gt2(1-\beta_2)g_t^2(1β2)gt2):当前梯度平方对二阶动量的贡献。

二阶动量可以理解为:

这个参数的梯度波动有多大。

Adam 更新公式通常写成:

θt+1=θt−ηm^tv^t+ϵ \theta_{t+1}= \theta_t - \eta \frac{\hat{m}_t}{\sqrt{\hat{v}_t}+\epsilon} θt+1=θtηv^t +ϵm^t

逐项解释:

  • (θt\theta_tθt):当前参数;
  • (θt+1\theta_{t+1}θt+1):更新后的参数;
  • (η\etaη):学习率;
  • (m^t\hat{m}_tm^t):偏差修正后的一阶动量;
  • (v^t\hat{v}_tv^t):偏差修正后的二阶动量;
  • (v^t\sqrt{\hat{v}_t}v^t ):二阶动量开方;
  • (ϵ\epsilonϵ):防止除零的小常数;
  • (m^tv^t+ϵ\frac{\hat{m}_t}{\sqrt{\hat{v}_t}+\epsilon}v^t +ϵm^t):自适应缩放后的更新方向。

Adam 的直觉是:

如果某个参数梯度方向稳定,就可以更放心地更新;
如果某个参数梯度波动很大,就应该谨慎更新。

所以 Adam 比 SGD 更适合复杂大模型。


5.3 Weight Decay:什么是权重衰减?

Weight Decay,中文叫 权重衰减

它的作用是:

每次更新时,让参数稍微变小一点,防止权重无限变大。

最直观的公式是:

θt+1=(1−ηλ)θt−ηgt \theta_{t+1}=(1-\eta\lambda)\theta_t -\eta g_t θt+1=(1ηλ)θtηgt

逐项解释:

  • (θt\theta_tθt):当前参数;
  • (θt+1\theta_{t+1}θt+1):更新后的参数;
  • (η\etaη):学习率;
  • (λ\lambdaλ):weight decay 系数;
  • ((1−ηλ)θt(1-\eta\lambda)\theta_t(1ηλ)θt):把原来的参数稍微缩小;
  • (−ηgt-\eta g_tηgt):根据梯度更新参数。

如果 (\lambda) 很小,那么每一步只是轻微衰减。

直观理解:

不要让模型参数变得过大;
不要让模型靠特别大的权重死记训练集;
让模型保持更平滑、更稳定。

5.4 L2 正则是什么?

Regularization,中文叫 正则化
它的作用是防止模型过拟合。

L2 regularization,中文叫 L2 正则

它是在原始 loss 上加一个参数惩罚项:

L′(θ)=L(θ)+λ2∣θ∣22 L'(\theta)= L(\theta) + \frac{\lambda}{2}|\theta|_2^2 L(θ)=L(θ)+2λθ22

逐项解释:

  • (L′(θ)L'(\theta)L(θ)):加入 L2 正则后的总 loss;
  • (L(θ)L(\theta)L(θ)):原始任务 loss;
  • (λ\lambdaλ):正则化强度;
  • (θ\thetaθ):模型参数;
  • (∣θ∣22|\theta|_2^2θ22):参数平方和;
  • (λ2∣θ∣22\frac{\lambda}{2}|\theta|_2^22λθ22):惩罚大参数的项。

其中:

∣θ∣22=∑iθi2 |\theta|_2^2 = \sum_i \theta_i^2 θ22=iθi2

逐项解释:

  • (θi\theta_iθi):第 (i) 个参数;
  • (θi2\theta_i^2θi2):这个参数的平方;
  • (∑iθi2\sum_i \theta_i^2iθi2):所有参数平方加起来。

L2 正则的直觉是:

参数越大,惩罚越大。


5.5 为什么 AdamW 要把 Weight Decay 解耦?

在普通 SGD 中,L2 正则和 weight decay 的效果非常接近。

但是在 Adam 里,它们不再等价。

原因是 Adam 会对梯度进行自适应缩放。

如果把 L2 正则加进 loss,梯度会变成:

gt′=gt+λθt g_t' = g_t + \lambda\theta_t gt=gt+λθt

逐项解释:

  • (gt′g_t'gt):加入 L2 正则后的梯度;
  • (gtg_tgt):原始任务 loss 的梯度;
  • (λθt\lambda\theta_tλθt):来自 L2 正则项的梯度;
  • (θt\theta_tθt):当前参数。

然后 Adam 会对整个 (gt′g_t'gt) 做自适应缩放。

也就是说,(λθt\lambda\theta_tλθt) 这个本来应该“稳定衰减参数”的项,也被 Adam 的分母 (v^t+ϵ\sqrt{\hat{v}_t}+\epsilonv^t +ϵ) 缩放了。

这会导致:

不同参数的衰减幅度不再统一;
weight decay 的效果被 Adam 的自适应机制扭曲。

AdamW 的做法是:

不把 weight decay 混进梯度里,而是单独对参数做衰减。

AdamW 的更新公式可以写成:

θt+1=θt−ηm^tv^t+ϵ−ηλθt \theta_{t+1}= \theta_t- \eta \frac{\hat{m}_t}{\sqrt{\hat{v}_t}+\epsilon}- \eta\lambda\theta_t θt+1=θtηv^t +ϵm^tηλθt

逐项解释:

  • (θt\theta_tθt):当前参数;
  • (θt+1\theta_{t+1}θt+1):更新后的参数;
  • (η\etaη):学习率;
  • (m^t\hat{m}_tm^t):偏差修正后的一阶动量;
  • (v^t\hat{v}_tv^t):偏差修正后的二阶动量;
  • (ϵ\epsilonϵ):防止除零的小常数;
  • (−ηm^tv^t+ϵ-\eta\frac{\hat{m}_t}{\sqrt{\hat{v}_t}+\epsilon}ηv^t +ϵm^t):Adam 根据 loss 梯度做的参数更新;
  • (−ηλθt-\eta\lambda\theta_tηλθt):单独的 weight decay 项。

一句话理解:

Adam 负责根据梯度优化 loss;
Weight decay 负责单独缩小参数;
二者不要混在一起。

这就是 AdamW 中 “W” 的意义。


六、Cosine Learning Rate Schedule:学习率为什么要按余弦下降?

6.1 Learning Rate 是什么?

Learning Rate,中文叫 学习率

它控制每一步参数更新的幅度。

在最简单的 SGD 公式里:

θt+1=θt−ηgt \theta_{t+1}=\theta_t-\eta g_t θt+1=θtηgt

逐项解释:

  • (θt\theta_tθt):当前参数;
  • (θt+1\theta_{t+1}θt+1):更新后的参数;
  • (η\etaη):学习率;
  • (gtg_tgt):梯度。

如果 (η\etaη) 太大:

一步走太远,可能错过最优点;
训练可能震荡,甚至崩掉。

如果 (η\etaη) 太小:

每一步走太慢;
训练效率低,收敛困难。

所以学习率不能随便设。


6.2 为什么学习率不能一直固定?

训练不同阶段需要不同学习率。

训练刚开始时,模型参数是随机初始化的,状态不稳定。
如果一开始学习率太大,模型可能直接崩。

训练中期,模型开始学习规律,需要较大的学习率快速下降 loss。
训练后期,模型接近较优区域,需要小学习率慢慢微调。

所以合理的学习率变化应该是:

刚开始:慢慢升起来;
中间:保持较强学习能力;
后期:逐渐降下来。

这就引出了:

Warmup + Cosine Decay

6.3 Warmup:为什么要预热?

Warmup,中文叫 预热

它的作用是:

训练刚开始时,不要一上来就用最大学习率,而是让学习率从小慢慢升高。

Warmup 的线性公式可以写成:

ηt=ηmax⁡tTwarmup \eta_t= \eta_{\max} \frac{t}{T_{\text{warmup}}} ηt=ηmaxTwarmupt

逐项解释:

  • (ηt\eta_tηt):第 (t) 步的学习率;
  • (ηmax⁡\eta_{\max}ηmax):最大学习率;
  • (ttt):当前训练步数;
  • (TwarmupT_{\text{warmup}}Twarmup):warmup 总步数;
  • (tTwarmup\frac{t}{T_{\text{warmup}}}Twarmupt):当前 warmup 进度。

当 (t=0) 时:

ηt=0 \eta_t = 0 ηt=0

当 (t=Twarmupt=T_{\text{warmup}}t=Twarmup) 时:

ηt=ηmax⁡ \eta_t = \eta_{\max} ηt=ηmax

也就是说,学习率从 0 逐渐升到最大值。


6.4 Cosine Decay:余弦学习率衰减

Warmup 结束后,学习率开始按余弦曲线下降。

常见公式是:

ηt=ηmin⁡+12(ηmax⁡−ηmin⁡)(1+cos⁡(πp)) \eta_t= \eta_{\min} + \frac{1}{2} (\eta_{\max}-\eta_{\min}) \left( 1+\cos(\pi p) \right) ηt=ηmin+21(ηmaxηmin)(1+cos(πp))

其中:

p=t−TwarmupTtotal−Twarmup p= \frac{t-T_{\text{warmup}}} {T_{\text{total}}-T_{\text{warmup}}} p=TtotalTwarmuptTwarmup

逐项解释第一个公式:

  • (ηt\eta_tηt):第 (t) 步的学习率;
  • (ηmin⁡\eta_{\min}ηmin):最小学习率,也就是训练后期的学习率下限;
  • (ηmax⁡\eta_{\max}ηmax):最大学习率;
  • (12(ηmax⁡−ηmin⁡)\frac{1}{2}(\eta_{\max}-\eta_{\min})21(ηmaxηmin)):控制下降幅度;
  • (cos⁡(πp)\cos(\pi p)cos(πp)):余弦函数,控制平滑下降;
  • (ppp):warmup 之后的训练进度。

再解释 §:

  • (ttt):当前训练步数;
  • (TwarmupT_{\text{warmup}}Twarmup):warmup 结束的步数;
  • (TtotalT_{\text{total}}Ttotal):总训练步数;
  • (ppp):从 warmup 结束到训练结束的进度,范围从 0 到 1。

当 (p=0) 时:

cos⁡(0)=1 \cos(0)=1 cos(0)=1

所以:

ηt=ηmax⁡ \eta_t = \eta_{\max} ηt=ηmax

当 (p=1) 时:

cos⁡(π)=−1 \cos(\pi)=-1 cos(π)=1

所以:

ηt=ηmin⁡ \eta_t = \eta_{\min} ηt=ηmin

也就是说,学习率从最大值平滑下降到最小值。


6.5 为什么用 Cosine,而不是直线下降?

余弦下降有一个特点:

刚开始下降慢;
中间下降快;
最后下降又变慢。

这很符合训练过程:

前期模型还在快速学习,不希望太快降低学习率。
中期可以逐渐降低,让模型朝更稳定方向收敛。
后期接近较优解,需要非常小的步子慢慢微调。

可以用一个简化图理解:

学习率
↑
|        warmup
|          /\
|         /  \
|        /    \
|       /      \
|______/        \________
|
+----------------------------→ training steps

其中:

左边上升:warmup
右边平滑下降:cosine decay

LLaMA 使用 cosine learning rate schedule,是为了让长期训练更稳定。


七、高效训练:显存、计算和并行

LLaMA 不只是训练配方好,工程实现也很关键。

大模型训练最容易遇到三个问题:

显存不够;
计算太慢;
多 GPU 通信成本高。

LLaMA 在 efficient implementation 部分提到了一些关键优化。


7.1 Efficient Causal Attention:为什么不存完整 Attention Matrix?

标准 Attention 需要计算:

S=QKTdk S = \frac{QK^T}{\sqrt{d_k}} S=dk QKT

逐项解释:

  • (SSS):attention score matrix;
  • (QQQ):Query 矩阵;
  • (KTK^TKT):Key 矩阵转置;
  • (QKTQK^TQKT):每个 token 对每个 token 的注意力分数;
  • (dkd_kdk):Q/K 向量维度;
  • (dk\sqrt{d_k}dk ):缩放因子。

如果序列长度是 (n),那么 attention score matrix 的大小是:

n×n n \times n n×n

如果 (n=4096),那么一个 head 的 attention 矩阵就是:

4096×4096 4096 \times 4096 4096×4096

这个矩阵非常大。

更重要的是,LLaMA 是 causal attention。
当前 token 不能看未来 token。

所以 attention 矩阵中上三角部分是无效的:

      t1  t2  t3  t4
t1    ✓   ✗   ✗   ✗
t2    ✓   ✓   ✗   ✗
t3    ✓   ✓   ✓   ✗
t4    ✓   ✓   ✓   ✓

被 mask 掉的未来位置本来就不能用。

因此,高效 causal attention 的思想是:

不要计算没用的未来位置,也不要完整存储巨大的 attention weights。

这可以减少显存占用和运行时间。


7.2 Activation Recomputation:用计算换显存

Activation,中文叫 激活值

它指的是神经网络前向传播过程中产生的中间结果。

训练时为什么要保存 activation?

因为反向传播需要用它们计算梯度。

但是大模型层数多、序列长、batch 大,activation 会非常占显存。

Activation Recomputation,中文可以叫 激活重计算

它的思路是:

前向传播时不保存所有中间结果,反向传播需要时再重新算一遍。

这是一种典型的:

用更多计算换更少显存

的方法。

它和 Activation Checkpointing 关系很近。

Checkpointing 的思路是:

只保存少数关键节点;
中间激活不存;
反向传播时从最近的 checkpoint 重新计算。

这对大模型训练非常重要。

尤其是 VLM 和长文档模型,因为图像 token、文本 token、页面 token 都会让序列变长。
序列一长,attention 和 activation 的显存都会暴涨。

所以 activation recomputation 是后续做视觉 RAG、长文档 VLM 必须掌握的工程技能。


7.3 Model Parallelism:模型并行

Model Parallelism,中文叫 模型并行

它解决的问题是:

一个模型太大,单张 GPU 放不下。

最直观的方式是把模型拆到多张 GPU 上。

比如:

GPU 1:前 20 层
GPU 2:中间 20 层
GPU 3:后 20 层

或者更细粒度地,把一层里的矩阵切开。

模型并行的核心思想是:

参数太大 → 拆参数

7.4 Sequence Parallelism:序列并行

Sequence Parallelism,中文叫 序列并行

它解决的问题是:

序列太长,单卡处理完整序列的 activation 和 attention 成本太高。

序列并行会把序列维度拆开。

例如一个序列有 4096 个 token,可以拆成:

GPU 1:token 1-1024
GPU 2:token 1025-2048
GPU 3:token 2049-3072
GPU 4:token 3073-4096

当然真实实现比这个复杂,因为 attention 需要 token 之间交互,所以 GPU 之间需要通信。

序列并行的核心思想是:

序列太长 → 拆 token 维度

这对长上下文和多模态模型特别重要。


7.5 Communication Overlap:通信和计算重叠

多 GPU 训练时,GPU 之间需要交换信息。

这个过程叫 communication,通信

如果 GPU 一边算完,一边干等通信完成,就会浪费大量时间。

Communication Overlap,中文可以叫 通信计算重叠

它的意思是:

在一部分 GPU 通信的同时,让另一部分计算继续进行,尽量减少等待。

可以简单理解为:

不要让 GPU 干等。

大模型训练不是只靠理论结构,还非常依赖这些工程优化。


八、LLaMA 如何证明自己强?Benchmark 不是只看分数

训练讲完后,我们必须看实验。

LLaMA 的实验部分不是只展示一个总分,而是从多个能力维度评估模型:

常识推理;
闭卷问答;
阅读理解;
数学推理;
代码生成;
多任务语言理解;
安全与真实性。

这对我们做研究很重要。

因为一个模型不能只说“效果好”,必须说明:

到底是哪种能力好?


九、Common Sense Reasoning:常识推理

Common Sense Reasoning,中文叫 常识推理

它测试的是模型是否理解人类日常常识。

比如:

一个人把冰淇淋放在太阳下,过一会儿会怎样?

正确答案应该是:

冰淇淋会融化。

LLaMA 使用了多个常识推理 benchmark:

Benchmark 主要测试内容
BoolQ 是/否判断
PIQA 物理常识
SIQA 社会互动常识
HellaSwag 场景后续预测
WinoGrande 代词消解与常识
ARC 科学常识推理
OpenBookQA 科学问答

这些任务共同测试模型是否具备基础常识和简单推理能力。

LLaMA 的结果说明:

LLaMA-13B 在很多常识推理任务上已经能超过 GPT-3 175B。

这非常关键,因为它说明模型强弱不只取决于参数量。


十、Closed-book QA:闭卷问答

Closed-book Question Answering,中文叫 闭卷问答

意思是:

模型回答问题时,不能检索外部文档,只能依靠参数中记住的知识。

这和 RAG 正好相反。

RAG 是开卷问答:

问题
↓
检索相关文档
↓
基于证据回答

Closed-book QA 是闭卷问答:

问题
↓
模型直接回答

LLaMA 使用的闭卷问答 benchmark 包括:

Natural Questions
TriviaQA

这些任务通常使用 Exact Match 评价。

Exact Match 公式是:

EM=1N∑i=1N1(y^i=yi) \text{EM}= \frac{1}{N} \sum_{i=1}^{N} \mathbf{1}(\hat{y}_i = y_i) EM=N1i=1N1(y^i=yi)

逐项解释:

  • (EM\text{EM}EM):Exact Match,精确匹配率;
  • (NNN):测试集问题总数;
  • (iii):第 (iii) 个问题;
  • (y^i\hat{y}_iy^i):模型生成的答案;
  • (yiy_iyi):标准答案;
  • (1(y^i=yi)\mathbf{1}(\hat{y}_i = y_i)1(y^i=yi)):指示函数,如果预测答案和标准答案完全一致,值为 1,否则为 0;
  • (∑i=1N\sum_{i=1}^{N}i=1N):把所有题目的正确情况加起来;
  • (1N\frac{1}{N}N1):除以题目总数,得到平均正确率。

例如:

问题 模型答案 标准答案 得分
Q1 Paris Paris 1
Q2 London Canberra 0
Q3 Jane Austen Jane Austen 1

那么:

EM=1+0+13=66.7 \text{EM}=\frac{1+0+1}{3}=66.7% EM=31+0+1=66.7

闭卷问答能反映模型参数中储存了多少事实知识。

但是它也有明显缺点:

知识可能过时;
答案不可追溯;
容易幻觉。

这也是为什么在专利、法律、医学等专业场景中,RAG 比纯闭卷回答更可靠。


十一、Reading Comprehension:阅读理解

Reading Comprehension,中文叫 阅读理解

它测试的是:

给模型一段文章,模型能否根据文章内容回答问题。

LLaMA 使用的阅读理解 benchmark 是 RACE

RACE 来自中学英语阅读理解题,分为:

RACE-middle
RACE-high

形式类似:

给一篇文章;
给一个问题;
给四个选项;
模型选择正确答案。

这类选择题通常使用 Accuracy。

Accuracy 公式是:

Accuracy=1N∑i=1N1(y^i=yi) \text{Accuracy}= \frac{1}{N} \sum_{i=1}^{N} \mathbf{1}(\hat{y}_i = y_i) Accuracy=N1i=1N1(y^i=yi)

逐项解释:

  • (Accuracy\text{Accuracy}Accuracy):准确率;
  • (NNN):测试样本总数;
  • (iii):第 (i) 个样本;
  • (y^i\hat{y}_iy^i):模型预测的选项;
  • (yiy_iyi):真实正确选项;
  • (1(y^i=yi)\mathbf{1}(\hat{y}_i = y_i)1(y^i=yi)):预测正确为 1,预测错误为 0。

RACE 和闭卷 QA 不同。

闭卷 QA 主要看模型参数里有没有记住知识。
阅读理解主要看模型能不能理解给定文本。

这对后续 RAG 很重要,因为 RAG 的生成阶段本质上就需要阅读理解能力。


十二、Mathematical Reasoning:数学推理

Mathematical Reasoning,中文叫 数学推理

LLaMA 使用了两个数学 benchmark:

MATH
GSM8K

MATH 更难,包含中学到竞赛级别数学题。
GSM8K 是小学/初中级别的数学文字题。

数学任务很重要,因为它不只是考记忆,而是考:

读题;
抽取数量关系;
多步推理;
计算;
输出答案。

LLaMA 论文中还使用了多数投票方法,也就是 majority voting

多数投票公式可以写成:

y^=arg⁡max⁡a∑j=1k1(yj=a) \hat{y}= \arg\max_a \sum_{j=1}^{k} \mathbf{1}(y_j=a) y^=argamaxj=1k1(yj=a)

逐项解释:

  • (y^\hat{y}y^):最终选择的答案;
  • (aaa):某个候选答案;
  • (kkk):对同一道题采样生成的答案数量;
  • (jjj):第 (j) 次生成;
  • (yjy_jyj):第 (j) 次生成的答案;
  • (1(yj=a)\mathbf{1}(y_j=a)1(yj=a)):如果第 (j) 次答案等于 (a),值为 1,否则为 0;
  • (∑j=1k1(yj=a)\sum_{j=1}^{k}\mathbf{1}(y_j=a)j=1k1(yj=a)):答案 (a) 出现的次数;
  • (arg⁡max⁡a\arg\max_aargmaxa):选择出现次数最多的答案。

例如模型生成 5 次:

第1次:6
第2次:6
第3次:7
第4次:6
第5次:8

答案 6 出现最多,所以最终答案是 6。

这说明一个现象:

大模型有时单次输出不稳定,多采样并投票可以提高数学题正确率。


十三、Code Generation:代码生成

Code Generation,中文叫 代码生成

LLaMA 使用的代码 benchmark 包括:

HumanEval
MBPP

HumanEval 通常给出函数说明和函数头,让模型补全代码。
MBPP 是 Mostly Basic Python Problems,主要是 Python 编程题。

代码生成不能只看文字像不像,必须看代码能不能运行。

因此常用指标是 pass@k

pass@k 的直观意思是:

对一道题生成 k 个候选代码,只要其中有一个通过测试,就算通过。

公式可以写成:

pass@k=1N∑i=1N1(∃j∈1,…,k:pass(ci,j)=1) \text{pass@}k= \frac{1}{N} \sum_{i=1}^{N} \mathbf{1} \left( \exists j \in {1,\dots,k}: \text{pass}(c_{i,j})=1 \right) pass@k=N1i=1N1(j1,,k:pass(ci,j)=1)

逐项解释:

  • (pass@k\text{pass@}kpass@k):生成 (k) 个候选时的通过率;
  • (NNN):测试题目总数;
  • (iii):第 (i) 道题;
  • (jjj):第 (j) 个候选代码;
  • (ci,jc_{i,j}ci,j):第 (i) 道题生成的第 (j) 个代码;
  • (pass(ci,j)\text{pass}(c_{i,j})pass(ci,j)):如果该代码通过测试用例,值为 1,否则为 0;
  • (∃j\exists jj):存在某个候选;
  • (1(⋅)\mathbf{1}(\cdot)1()):如果条件成立,值为 1,否则为 0。

例如一道题生成 5 个代码:

代码1:失败
代码2:失败
代码3:通过
代码4:失败
代码5:失败

那么 pass@5 对这道题就是 1。

LLaMA 在代码任务上的表现说明:

即使不是专门代码模型,只要预训练数据中有一定 GitHub 数据,模型也能获得代码能力。

不过要注意:

LLaMA 不是 Code Llama;
它有代码能力,但不是专门为代码优化的模型。

十四、MMLU:综合知识能力

MMLU 全称是 Massive Multitask Language Understanding

中文可以叫:

大规模多任务语言理解 benchmark。

它覆盖很多学科:

数学
物理
计算机
法律
医学
历史
哲学
经济学
心理学
社会科学

MMLU 常用于评估模型综合知识和推理能力。

LLaMA 在 MMLU 上使用 5-shot 设置。

5-shot 的意思是:

在正式问题之前,给模型 5 个示例,让模型模仿示例格式回答。

它不是微调。

区别是:

5-shot prompting:只在输入里给例子,不更新参数;
fine-tuning:用数据继续训练模型参数。

MMLU 使用选择题,因此也可以用 Accuracy:

Accuracy=1N∑i=1N1(y^i=yi) \text{Accuracy}= \frac{1}{N} \sum_{i=1}^{N} \mathbf{1}(\hat{y}_i = y_i) Accuracy=N1i=1N1(y^i=yi)

逐项解释:

  • (Accuracy\text{Accuracy}Accuracy):准确率;
  • (NNN):测试题目数量;
  • (iii):第 (i) 道题;
  • (y^i\hat{y}_iy^i):模型预测选项;
  • (yiy_iyi):正确选项;
  • (1(y^i=yi)\mathbf{1}(\hat{y}_i = y_i)1(y^i=yi)):预测正确为 1,预测错误为 0。

LLaMA 在 MMLU 上并不是全面超过 Chinchilla 和 PaLM。

这点很重要。

它说明:

LLaMA 很强,但不是每个能力维度都最强。

尤其 MMLU 涉及很多专业知识,训练数据的知识覆盖、数据质量、专业领域比例都会影响结果。


十五、如何正确理解 LLaMA 的实验结果?

LLaMA 实验部分最重要的结论不是某个具体分数,而是以下几点。


15.1 LLaMA-13B 是论文最有冲击力的模型

LLaMA-13B 参数量只有 13B。
GPT-3 是 175B。

两者参数量差距巨大。

但是 LLaMA-13B 在多数 benchmark 上超过 GPT-3。

这说明:

参数量不是唯一决定因素;
训练 token 数非常关键;
训练配方非常关键;
数据质量和数据组成也非常关键。

如果用一句话总结:

LLaMA-13B 证明了“小模型充分训练”可以挑战“大模型欠训练”。


15.2 LLaMA-65B 是强基础模型,但不是所有任务都赢

LLaMA-65B 可以和 Chinchilla-70B、PaLM-540B 竞争。

但在 MMLU 等任务上,LLaMA-65B 并不是完全领先。

这说明:

benchmark 是能力切片;
没有一个 benchmark 可以代表全部能力;
不同数据来源会影响不同任务表现。

15.3 Few-shot 能力来自预训练,不等于指令对齐

LLaMA 1 原论文主要讲的是 base model。

它能做 few-shot,不代表它就是 chat model。

要区分:

LLaMA base:
基础语言模型,会续写,会 few-shot,但不一定稳定听指令。

LLaMA instruct / chat:
经过指令微调或对齐,更像聊天助手。

这点非常重要。

很多人会误以为 LLaMA 原模型就是聊天模型,其实不是。


十六、对视觉 RAG 和专利理解的启发

这篇博客虽然讲的是 LLaMA 的训练和实验,但对视觉 RAG 很有启发。


16.1 专业任务不能只靠参数记忆

闭卷 QA 说明模型参数中确实存储了一部分知识。

但是专业场景不能只靠这个。

比如专利任务:

某个部件编号在哪张图中?
某个权利要求对应哪个结构?
两个专利图是否构成相似设计?
某个结构是否存在侵权风险?

这些问题都需要证据。

所以专利系统更适合:

检索证据
↓
定位页面/区域
↓
基于证据回答

这就是视觉 RAG 的意义。


16.2 实验设计要拆能力维度

LLaMA 没有只用一个 benchmark 证明自己强,而是拆成很多能力:

常识推理
闭卷问答
阅读理解
数学推理
代码生成
MMLU
安全测试

你以后做视觉 RAG,也应该拆能力。

比如:

能力 可能指标
页面检索 Recall@k
图文匹配 Accuracy / Recall
区域定位 IoU
问答生成 EM / F1 / 人工评价
证据引用 Citation Accuracy
幻觉控制 Hallucination Rate
长文档理解 跨页问答准确率

其中 Recall@k 可以写成:

Recall@k=Number of relevant documents retrieved in top kTotal number of relevant documents \text{Recall@}k= \frac{ \text{Number of relevant documents retrieved in top }k }{ \text{Total number of relevant documents} } Recall@k=Total number of relevant documentsNumber of relevant documents retrieved in top k

逐项解释:

  • (Recall@k\text{Recall@}kRecall@k):前 (k) 个结果中的召回率;
  • (kkk):取前几个检索结果,比如 1、5、10;
  • relevantdocumentsrelevant documentsrelevantdocuments:真正相关的文档;
  • retrievedintop(k)retrieved in top (k)retrievedintop(k):被模型排在前 (k) 的相关文档。

区域定位常用 IoU:

IoU=∣A∩B∣∣A∪B∣ \text{IoU}= \frac{|A \cap B|}{|A \cup B|} IoU=ABAB

逐项解释:

  • (IoU\text{IoU}IoU):Intersection over Union,交并比;
  • (A):模型预测区域;
  • (B):真实标注区域;
  • (A∩BA \cap BAB):预测区域和真实区域的重叠部分;
  • (A∪BA \cup BAB):预测区域和真实区域的并集;
  • IoU 越高,说明定位越准。

这就是 LLaMA 实验部分对我们做研究的启发:

不要只说模型强,要说明强在哪里,用什么指标证明。


十七、总结:LLaMA 强在哪里?

现在我们可以回答标题的问题:

LLaMA 为什么小而强?

答案不是单一因素,而是多个因素叠加。


17.1 数据层面

LLaMA 使用公开数据,但数据来源丰富:

网页
百科
书籍
代码
论文
问答社区

这些数据共同支撑了模型的语言、知识、代码、推理能力。


17.2 规模层面

LLaMA 受 Chinchilla Scaling Law 启发,不盲目堆参数,而是重视训练 token 数。

核心经验是:

D≈20N D \approx 20N D20N

其中:

  • (D):训练 token 数;
  • (N):模型参数量;
  • 20:经验比例。

LLaMA 尤其让 7B、13B 这样的小模型吃了大量 token,因此小模型表现非常强。


17.3 结构层面

LLaMA 使用成熟但有效的结构细节:

Decoder-only Transformer
RMSNorm
Pre-Norm
RoPE
SwiGLU
Causal Attention

这些不是凭空炫技,而是都服务于稳定性、表达能力和推理效率。


17.4 优化层面

LLaMA 使用:

AdamW
Cosine Learning Rate Schedule
Warmup
Weight Decay
Gradient Clipping

AdamW 公式再次写一遍:

θt+1=θt−ηm^tv^t+ϵ−ηλθt \theta_{t+1}=\theta_t- \eta \frac{\hat{m}_t}{\sqrt{\hat{v}_t}+\epsilon}- \eta\lambda\theta_t θt+1=θtηv^t +ϵm^tηλθt

逐项解释:

  • (θt\theta_tθt):当前参数;
  • (θt+1\theta_{t+1}θt+1):更新后的参数;
  • (η\etaη):学习率;
  • (m^t\hat{m}_tm^t):一阶动量;
  • (v^t\hat{v}_tv^t):二阶动量;
  • (ϵ\epsilonϵ):防止除零;
  • (λ\lambdaλ):weight decay 系数;
  • 最后一项 (−ηλθt-\eta\lambda\theta_tηλθt):单独的权重衰减。

这套优化策略让模型训练更稳定。


17.5 工程层面

LLaMA 使用高效训练实现:

不存完整 attention weights;
减少无效 causal mask 计算;
activation recomputation;
model parallelism;
sequence parallelism;
communication overlap。

这些工程细节保证了大模型可以真正训练起来。


十八、全文总结

LLaMA 的成功不是因为它发明了一个全新的 Transformer,而是因为它把已有的大模型训练经验组合得非常成功。

一句话总结:

LLaMA 证明了:使用公开数据、合理模型规模、充分训练 token、稳定优化器和高效工程实现,小参数 Decoder-only Transformer 也可以获得非常强的基础语言模型能力。

更简洁地说:

LLaMA 不是结构革命,
而是训练配方、数据策略和工程效率的胜利。

它对后续开源大模型生态的意义非常大。

因为从 LLaMA 开始,7B、13B 这类模型真正成为学术界、个人开发者和普通实验室可以研究、微调、部署的对象。

而对于后续多模态模型来说,LLaMA 也提供了一个非常重要的语言底座。

很多 VLM 的基本思路都可以理解为:

视觉编码器负责看图;
语言模型负责理解、推理和生成;
中间通过 projector 或 adapter 把视觉特征接入语言模型。

所以,读懂 LLaMA 的训练和实验,不只是为了理解一个语言模型。
它也是继续学习 LLaVA、BLIP-2、Qwen-VL、ColPali、视觉 RAG 和 OCR-free 文档理解的基础。

下一篇我们就可以正式进入:

LLaMA 论文完整精读:从 Abstract 到 Conclusion,把整篇论文串起来。

更多推荐