大模型 · Transformer · 神经网络底层原理
从单个神经元到千亿参数大模型 · 分层讲解(通俗主体 + 可折叠技术细节)· 每个关键论断附原始论文来源
📖 如何阅读本文
正文用通俗语言 + 类比讲清每个概念的核心思想,所有人可读;标有 🔬 的灰色框是可折叠的技术细节(含数学公式、推导、维度变化),供有技术背景或想深入者展开。每个关键概念标注原始论文 arXiv 编号,便于溯源核证。
🗺️三层认知地图
理解大模型,先建立一张"三层地图"。这三层是包含关系而非并列——大模型是 Transformer 架构的特例,Transformer是神经网络的一种。理解每一层如何突破前一层的局限,整条技术脉络就理顺了。
解决什么:如何让机器从数据中自动"学习"规律,而不是由人手写规则。它的基本单元是模仿生物神经元的"神经元"——接收输入、加权求和、通过激活函数产生输出。无数神经元层层连接,通过反向传播算法自动调整参数。
起源:McCulloch-Pitts 神经元模型 1943;Rosenblatt 感知机 1958;反向传播 Rumelhart et al. 1986
解决什么:传统神经网络处理"序列"(如一句话)时,必须一个词一个词地算(RNN),既慢又容易忘记前面内容。Transformer 用注意力机制让每个词一次性"看到"句子里所有其他词,实现并行计算和长距离依赖建模。这是大模型的唯一架构基石。
Vaswani et al., "Attention Is All You Need", arXiv:1706.03762, 2017
解决什么:当把 Transformer 做得极大(千亿参数)、用海量文本训练后,模型涌现出惊人的语言理解和生成能力。大模型 = 超大 Transformer + 海量数据 + 规模定律 + 对齐技术。它不是新架构,而是把 Transformer 推到极致的工程产物。
GPT-3, arXiv:2005.14165;Scaling Law, arXiv:2001.08361
🔗一张图看懂全链路
从原始文本到 AI 回答,数据流经这条完整链条。本文将自下而上逐一拆解每一环。
大模型的本质,是在做"下一个词预测"(next-token prediction):给定前面所有词,预测下一个最可能出现的词。所有令人惊叹的能力——对话、推理、写代码——都源自这个被反复执行亿万次的简单任务。
第一篇 · 神经网络基础
一切从这里开始。这一篇讲清:单个神经元如何工作、如何堆叠成网络、网络如何"学习"(反向传播)、用什么标准衡量对错(损失函数)、如何改进(优化器)。
① 神经元与感知机 McCulloch-Pitts 1943 / Rosenblatt 1958
通俗理解:一个人造神经元做的事情极其简单——它有若干个输入(比如 x₁, x₂, x₃),每个输入有一个"权重"(重要性 w₁, w₂, w₃)。神经元把所有输入乘以各自的权重后加起来,再加上一个"偏置"(基础倾向 b),然后通过一个"激活函数" f 决定输出什么。
感知机的数学表达
单个神经元的输出:
其中 w 是权重向量,x 是输入向量,b 是偏置标量,f 是激活函数。
感知机(Perceptron)是 Rosenblatt 于 1958 年提出的最早的可学习神经元模型,激活函数是阶跃函数(输出 0 或 1)。1969 年 Minsky 指出单层感知机无法解决 XOR(异或)问题,这曾导致神经网络研究进入"寒冬",直到多层网络与反向传播算法成熟才复苏。
② 多层感知机(MLP):为什么需要"层"和"非线性"
单个神经元能力有限。把许多神经元排成一列叫一层;把多层串联起来(输入层 → 隐藏层 → 输出层),就构成了多层感知机。前一层每个神经元的输出作为后一层每个神经元的输入。
两个关键点:
- 隐藏层让网络能学习输入的"中间表示"——网络自己发现数据的有用特征,而非靠人手写。
- 激活函数必须是非线性的。若所有层都是线性的,多层叠加在数学上等价于一层(线性组合的线性组合仍是线性的),网络再深也没用。非线性激活赋予网络逼近任意复杂函数的能力(万能逼近定理)。
前馈计算:一层 MLP 的完整算式
设输入向量 x(维度 d_in),隐藏层有 H 个神经元,输出维度 d_out。
第一层(隐藏层):
第二层(输出层):
所谓"训练神经网络",就是找到合适的 W₁, b₁, W₂, b₂ 使 y 尽可能接近真实答案。一个百亿参数大模型,本质就是数百万个这样的 W 矩阵的集合。
③ 激活函数:神经元的"决策方式"
激活函数决定神经元如何把加权输入转化为输出。它的非线性是神经网络能力的基础。
| 激活函数 | 公式 | 特点 / 用途 |
|---|---|---|
| Sigmoid | σ(x) = 1 / (1 + e⁻ˣ) | 输出 (0,1),早期常用;缺点:梯度易消失、非零中心 |
| Tanh | tanh(x) = (eˣ − e⁻ˣ)/(eˣ + e⁻ˣ) | 输出 (−1,1),零中心;仍有梯度消失问题 |
| ReLU | ReLU(x) = max(0, x) | 计算极快、缓解梯度消失;现代网络主力。Transformer 前馈网络默认用 ReLU/GeLU |
| GELU | x · Φ(x) | ReLU 的平滑变体;GPT、BERT 等大模型广泛使用 |
ReLU 在正区间梯度恒为 1,不会像 Sigmoid 那样在反向传播时层层衰减(梯度消失),使得训练几十上百层的网络成为可能。它是 2012 年后深度学习爆发的工程基础之一。
④ 前向传播与反向传播:网络如何"学习"
前向传播(Forward):数据从输入层逐层计算到输出层,得到预测结果。这就是"使用"网络的过程。
反向传播(Backpropagation):网络"学习"的核心算法。它计算每个参数对当前误差的贡献(梯度),然后微调参数以减少误差。这个过程依赖微积分的链式法则,从输出层向输入层逐层反推。
反向传播的数学本质(链式法则)
设损失函数为 L,网络中某参数为 w。反向传播要算的是偏导数 ∂L/∂w——损失对参数的梯度。
对于多层网络,损失对深层参数的梯度通过链式法则逐层展开:
反向传播算法(Rumelhart, Hinton, Williams, 1986)高效地复用中间结果,一次性算出所有参数的梯度,复杂度仅约为前向传播的 2 倍。现代深度学习框架(PyTorch、TensorFlow)的"自动微分"自动完成这一过程。
梯度下降更新:算出梯度后,沿梯度反方向更新参数:
⑤ 梯度下降直观理解:网络如何"下山" Robbins & Monro 1951 / Kingma & Ba arXiv:1412.6980
上一节讲了反向传播算出"梯度"——它告诉你每个参数该往哪个方向调。但具体怎么调、调多大幅度、用什么节奏,就是梯度下降(Gradient Descent)要回答的问题。它是所有优化器(SGD、Adam)的共同骨架。
三个关键概念
- 梯度 = 最陡方向。梯度是损失对各参数的偏导数向量,指向损失上升最快的方向。所以更新参数时要沿梯度的反方向走(下坡),这就是"梯度下降"名字的由来。
- 学习率 η(learning rate)= 步子大小。每步走多远由 η 决定,它是训练最重要的超参数之一。
- 太大:一步跨过山谷,在对面的山坡上震荡甚至发散,永远到不了谷底。
- 太小:每步挪一点,下到谷底要无穷无尽的时间,还可能卡在半山腰的小坑里(局部最优)。
- Mini-batch SGD(小批量随机梯度下降)。算梯度时不用全部训练数据(太慢),而是每次随机抽一小批(如 32/64/128 条)来估计梯度。好处有二:① 速度快(一批比全量省得多);② 随机性反而是好事——它让下山路径带有抖动,有助于跳出浅坑、找到更优的谷底。
梯度下降的更新公式 与 三种变体
参数更新公式(沿梯度反方向走一步):
根据每次用多少数据算梯度,分三种:
| 变体 | 每次用的数据 | 特点 |
|---|---|---|
| 批量梯度下降 BGD | 全部训练数据 | 梯度准、稳定,但极慢、内存吃不下 |
| 随机梯度下降 SGD | 每次 1 条 | 极快但抖动剧烈,难以收敛 |
| 小批量 SGD | 一小批(32~512) | 工程默认,兼顾速度与稳定性 |
局部最优(local minima):山地里不止一个谷。全量梯度下降可能卡在某个浅谷;而 mini-batch SGD 的随机性会"踉跄"一下,抖出浅谷,更可能落到更深的谷(更好的解)。这是随机性在优化中的妙用。
现代深度学习和大模型训练几乎不用裸 SGD,而用 Adam(Kingma & Ba, arXiv:1412.6980)。它在 SGD 基础上加了两个智能机制:① 动量(Momentum)——累积历史梯度方向,像带上惯性,下坡更稳、更快;② 自适应学习率——为每个参数单独维护一个学习率,常更新的参数自动调小、少更新的自动调大。大模型里上亿个参数,每个都有自己的步子大小,这是 Adam 比固定学习率的 SGD 强大的关键(详见下一节技术细节框中的 Adam 公式)。
⑥ 损失函数与优化器:衡量对错与改进方向
损失函数(Loss Function)衡量预测值与真实值的差距,是学习的"靶心"。对语言模型,最核心的是交叉熵损失——它衡量模型预测的下一个词的概率分布,与真实那个词的差距。
优化器(Optimizer)决定如何根据梯度更新参数。最基础的是梯度下降(SGD);现代深度学习与大模型训练几乎都用 Adam(自适应矩估计),它为每个参数维护独立的自适应学习率。
交叉熵损失 与 Adam 优化器
交叉熵损失(语言模型核心)。设模型对词表 V 中每个词预测概率 pᵢ,真实下一个词是词 c:
预测越准(p_c 越接近 1),L 越接近 0。语言模型训练就是在大规模语料上最小化所有位置的平均交叉熵。所谓"loss"就是平均交叉熵,Scaling Law 研究的正是它如何随规模下降。
Adam(Kingma & Ba, arXiv:1412.6980, 2014)结合了动量(历史梯度方向)和自适应学习率(按梯度方差缩放),对超参数不敏感、收敛快:
v_t = β₂·v_{t−1} + (1−β₂)·g_t² # 二阶矩(梯度平方)
w_t = w_{t−1} − η · m̂_t / (√v̂_t + ε)
⑦ 困惑度 Perplexity(PPL):loss 的"人话版" 交叉熵的指数变换
看语言模型评测榜时,除了 loss,更常出现的指标是困惑度(Perplexity, PPL)。它和交叉熵损失本质上是同一个东西的两种表达——PPL 就是 loss 做了一次指数变换。
loss 是对数尺度(如 2.0、3.5),数值差距感觉不直观;PPL 是指数尺度(如 e²·⁰≈7.4、e³·⁵≈33),差距被放大,更直观地体现模型好坏。几乎所有语言模型评测都用 PPL 作为核心指标——它和 loss 等价(知道一个就能算出另一个),但更贴合人对"困惑程度"的直觉。
⑧ 过拟合与正则化:为什么"练太多反而考砸"
训练时 loss 一直在降,是不是模型就越来越好?不一定。深度学习里有个反直觉的现象:模型可能在训练数据上表现越来越好,但在没见过的数据上反而越来越差。这就是过拟合(Overfitting)——理解它,是理解大模型 Scaling Law"为什么数据必须和参数同步放大"的前提。
过拟合的现象与本质
典型现象:训练 loss 持续下降,但验证 loss 先降后升——转折点之后,模型不是在"学规律",而是在"背噪声"。这个转折点就是早停(Early Stopping)的时机。
根本原因:当模型容量(参数量)远大于数据所蕴含的信息时,模型有足够富余的能力去记住训练数据里的偶然噪声和细节(比如某张图恰好有个污点),而不是学到背后真正的通用规律。"记住了"≠"理解了"——记住的东西无法泛化到新数据。
正则化:约束模型,逼它学"规律"而非"背答案"
正则化(Regularization)是一切防止过拟合手段的统称,核心思想是给模型加约束,让它没那么多富余容量去死记硬背。常见方法:
| 方法 | 原理 | 直觉 |
|---|---|---|
| L2 正则化(权重衰减) | 在损失里加一项 λ·‖w‖²,惩罚过大的权重 | 逼权重保持小而分散,不让某个参数"独大"去硬记噪声 |
| L1 正则化 | 加 λ·‖w‖₁,倾向于产生稀疏权重(很多为 0) | 自动做特征选择,扔掉无关维度 |
| Dropout | 训练时随机"丢弃"一部分神经元(置零) | 强迫网络冗余学习——不能依赖某几个神经元,每条信息要多路径备份,提升鲁棒性 |
| 早停 Early Stopping | 监控验证 loss,一旦回升就停止训练 | 在模型"开始背噪声"前及时刹车 |
| 数据增强 | 人为制造变体(图像翻转、文本同义改写) | 扩充有效数据量,稀释噪声的影响 |
正则化的本质是在"训练集拟合"和"泛化能力"之间做权衡(bias-variance tradeoff)——完全不约束会过拟合,约束太狠又会欠拟合(学不到东西)。
过拟合正是 Scaling Law 研究要回答的核心问题之一:参数量 N 和数据量 D 该怎么配比?如果参数很大而数据太少(如早期 GPT-3:175B 参数 / 300B tokens),模型就有大量富余容量去背训练集,严重过拟合、浪费算力。Chinchilla(arXiv:2203.15556)的结论——最优训练 token 数约为参数量的 20 倍——本质上就是一条避免过拟合的经验配比:数据量必须和参数量同步放大,让模型"有足够多的题可做",从而学到通用规律而非死记硬背。这也是为什么 DeepSeek、Llama 等现代大模型动辄用万亿级 token 训练的原因。
第二篇 · 深度学习与表示学习
把神经网络做"深"是现代 AI 成功的关键,但也带来了训练难题。这一篇讲清:为什么要深、深带来的问题(梯度消失)及其解法(残差连接、归一化),以及为什么 Transformer 能取代曾经的 CNN/RNN。
① 为什么要"深"——层次化特征表示
浅层网络理论上也能逼近任何函数(万能逼近定理),但所需神经元数呈指数增长。深层网络用更少参数表达更复杂函数,因为每一层在前一层基础上抽象出更高层次的特征——这叫表示学习。
② 自编码器(Autoencoder):表示学习的最简模型 Hinton & Salakhutdinov 2006
"表示学习"听起来抽象,有没有一个最简单的模型能直观演示它?有——自编码器(Autoencoder)。它的核心思想是"自我压缩再解压":把输入压缩成一个低维的"精华表示",再尝试从这个精华还原出原始输入。
核心洞察:潜在表示 z 的维度远小于输入 x。要在如此大的压缩比下还能重构出输入,编码器被迫丢弃冗余、提炼出最本质的特征——这就是"学到好的表示"。如果不压缩(z 和 x 同维),网络大可以直接"复制粘贴",就什么也学不到。
重构误差(Reconstruction Error):输入 x 与重构 x̂ 的差距。误差越小,说明潜在表示的信息承载力越强、表示能力越好。训练自编码器就是最小化这个重构误差。
自编码器的训练目标 与 现代意义
损失函数(最小化重构误差):
注意自编码器是无监督学习——不需要任何标签,只靠"输入=目标"自我重构就能学到有用的表示。这种"数据本身即是监督信号"的特性,正是后来大模型"用下一个词预测做无监督预训练"思想的雏形。
历史地位与现代传承:Hinton 等人 2006 年用自编码器复兴了深度学习研究。它的"压缩→潜在空间"思想一路演进:
- 降噪自编码器:重构被加噪的输入,学更鲁棒的表示。
- VAE(变分自编码器):让潜在空间结构化、可生成,是重要生成模型。
- 扩散模型(Diffusion):现代图像生成(Stable Diffusion、DALL·E)的技术祖先之一,其"逐步去噪还原"与自编码器的"重构"一脉相承。
理解了自编码器,就理解了"潜在空间 / 表示学习"这个贯穿现代生成式 AI 的核心概念。
③ 梯度消失与残差连接(ResNet) He et al. arXiv:1512.03385
把网络做深立刻遇到致命问题:梯度消失/爆炸。反向传播时梯度要逐层相乘,层数一多,梯度会指数级缩小(消失,网络学不动)或放大(爆炸,训练崩溃)。这曾让 20+ 层网络几乎无法训练。
残差连接(Residual Connection / Skip Connection)是 2015 年 ResNet 提出的革命性结构,巧妙解决此问题:不直接学习目标映射,而是学习"残差",并额外把输入直接"跳连"到输出相加。
残差连接的算式与直觉
普通层:y = F(x)。残差层:
为什么有效:梯度反向传播时,+x 这条捷径让梯度可以"直达"浅层(梯度至少为 1),打破了连乘衰减。这使得训练 100+ 层甚至 1000 层网络成为可能。ResNet 因此在 ImageNet 上夺冠(2015)。
残差连接是 Transformer 的标配组件——每个注意力子层和前馈子层都包了一个残差连接:output = LayerNorm(x + Sublayer(x))。没有 ResNet 的工程经验,就不会有可训练的深层 Transformer。
④ 归一化(Normalization):稳定训练的"减震器" Ba et al. arXiv:1607.06450
深层网络中,每层输入的分布会随训练不断变化(内部协变量偏移),导致训练不稳定。归一化层把数据强制拉回均值 0、方差 1 的稳定分布,显著加速并稳定训练。
BatchNorm(2015)
在一个 batch 的样本间做归一化。适合 CNN、固定 batch size 训练。但对序列长度可变的 NLP 任务和超长序列不友好。
LayerNorm(2016)
在单个样本的特征维度上做归一化,与 batch 大小无关。Transformer 和所有大模型的标准选择。
LayerNorm 公式
对单个向量 x(一个 token 的隐藏表示),在其所有维度上:
LN(x) = γ · (x − μ) / √(σ² + ε) + β
γ、β 是可学习参数,恢复表达能力。LayerNorm 让每个 token 的表示数值稳定,是深层 Transformer 能稳定训练的关键之一(Ba et al., "Layer Normalization", arXiv:1607.06450)。
⑤ CNN 与 RNN:被 Transformer 取代的前辈
Transformer 之前,处理序列/数据的主流神经网络有两类。理解它们的局限,才能理解 Transformer 为何是革命。
| 架构 | 擅长 | 致命局限 |
|---|---|---|
| CNN(卷积网络) | 图像(局部特征、空间结构) | 感受野受限于卷积核大小,捕捉长距离依赖需堆很多层 |
| RNN / LSTM | 序列(早期 NLP、语音) | 必须逐步串行计算(无法并行),且长序列会"遗忘"早期信息 |
① 并行:自注意力让所有位置同时计算,可充分利用 GPU,训练速度数量级提升;② 长距离:任意两个词之间距离恒为 1 步注意力,没有 RNN 的遗忘问题。这两点使"用整个互联网文本训练千亿模型"在工程上成为可能。
⑥ RNN/LSTM 门控机制:序列建模的前王者 Hochreiter & Schmidhuber 1997 / Cho et al. arXiv:1406.1078
上表说 RNN 有"遗忘早期信息"的致命局限。那在 Transformer 出现之前的二十年里,人们是怎么缓解这个问题的?答案是 LSTM(长短期记忆网络)和它的简化版 GRU——它们通过精巧的"门控"机制,曾是序列建模(语音、翻译、文本生成)的绝对王者。理解它们为何最终被 Transformer 取代,能更深刻地理解自注意力的革命性。
RNN 的核心难题:梯度消失与长期依赖丢失
原始 RNN 处理序列时,把上一步的"隐藏状态"作为这一步的输入,形成记忆。但反向传播要把梯度沿时间步一步步往回传,链条一长,梯度就指数级衰减(消失)或爆炸。结果是:模型"前面说的话全忘了"——读到句尾已经记不起句首的内容,无法建模长距离依赖。
LSTM 的解法:三个"门"控制记忆的保留与丢弃
LSTM(Hochreiter & Schmidhuber, 1997)的解法是引入一条贯穿所有时间步的"细胞状态"(cell state),并用三个门(gate)——本质是 sigmoid 控制的小开关(输出 0~1)——精确控制信息的流向:
| 门 | 作用 | 直觉 |
|---|---|---|
| 遗忘门 f | 决定细胞状态里丢掉哪些旧信息 | "上一句的主语已经不重要了,忘掉吧" |
| 输入门 i | 决定把哪些新信息写进细胞状态 | "这个新出现的人名很关键,记下来" |
| 输出门 o | 决定细胞状态里哪些部分作为当前输出 | "现在该用到刚才记的人名了,输出它" |
细胞状态的更新公式(核心是一条加法通路,让梯度可以长程流转而不衰减):
h_t = o_t ⊙ tanh(C_t) # 输出门控制暴露多少
关键在于 f_t ⊙ C_{t−1} 这条加法通路:当遗忘门 f_t 接近 1 时,细胞状态几乎原样传递,梯度也能无衰减地反向流过长序列——这正是 LSTM 能记住几百步之前信息的原因。
三个门的本质是选择性记忆——像人会自动"重要的留下、噪声丢弃"一样,LSTM 通过可学习的门,自己学会在序列里该记什么、该忘什么、该用什么。这比原始 RNN 的"无差别覆盖式记忆"聪明得多。这种"门控"思想后来也渗透进了其它架构(如 GRU、甚至部分注意力变体)。
GRU:LSTM 的简化版
GRU(门控循环单元,Cho et al., arXiv:1406.1078)把 LSTM 的三个门合并成两个(更新门、重置门),并取消了独立的细胞状态。参数更少、训练更快,在多数任务上效果与 LSTM 相当,是 LSTM 的流行替代。
LSTM/GRU 解决了"长期依赖",但有一个无法逾越的硬伤:必须逐步串行计算。处理第 t 个词必须先算完第 t−1 个词,无法并行。这让它们在海量数据 + GPU 并行的时代显得极慢。Transformer 用自注意力一举取代了它:所有位置同时计算、任意两词距离恒为 1 步——既全并行又无遗忘。所以并不是 LSTM 的门控思想错了,而是串行计算范式在"大力出奇迹"的规模下被并行范式淘汰。
第三篇 · Transformer 全解
这是全篇核心。Transformer 是所有现代大模型的架构基础,其灵魂是"注意力机制"。这一篇逐步拆解:注意力的直觉、自注意力(QKV)、多头注意力、位置编码、Encoder/Decoder 的关系。
① 注意力机制的直觉
"注意力"源自一个直觉:处理一个词时,应该更"关注"句子中与之相关的其他词。比如"The animal didn't cross the street because it was tired"中,"it"指代谁?人脑会自动判断它指 animal 而非 street——注意力机制让模型学会这种"分配关注度"。
Query(查询 Q)——你想找什么(当前词:"it 指代谁?")
Key(键 K)——每本书/每个词的标签("animal""street"各自的标签)
Value(值 V)——每本书的实际内容(检索到后要取用的信息)
用 Q 和每个 K 比较相关度,按相关度加权取出对应的 V——这就是注意力。
② 自注意力(Self-Attention):QKV 机制 arXiv:1706.03762
"自"注意力指 Q、K、V 都来自同一个输入序列(句子里每个词既当查询者也当被查询者)。每个词的最终表示,是所有词的 V 按注意力权重加权求和的结果——这样每个词都融合了整句话的上下文信息。
具体步骤:输入序列先通过三个不同的权重矩阵,变换出 Q、K、V 三个矩阵;然后用 Q 和 K 算"相关度分数",softmax 归一化成权重,再对 V 加权求和。
缩放点积注意力的完整公式与维度
核心公式(Vaswani et al., 2017):
逐步拆解(设序列长度 n,每个向量维度 d_k):
Q·Kᵀ:n×n 矩阵,第 i 行 j 列 = 第 i 个词与第 j 个词的"相关度"(点积)/ √d_k:缩放。防止点积过大导致 softmax 进入梯度极小的饱和区(d_k 是键向量维度)softmax(·):对每行做归一化,把分数变成加起来等于 1 的注意力权重· V:用权重对 V 加权求和 → 每个 token 得到融合了全局上下文的新表示
QKV 的来源:输入 X 通过三个可学习矩阵变换:
所以自注意力本质上是:学习三个矩阵 W_Q, W_K, W_V,让模型自己决定每个词该如何关注其他词。
当 d_k 较大时,点积 Q·Kᵀ 的数值会很大,使 softmax 输出趋近 one-hot(一个词 1、其余 0),梯度几乎为 0,训练停滞。除以 √d_k 把方差控制在合理范围。这个看似小的工程细节对训练稳定性至关重要。
③ 因果注意力掩码(Causal Mask):Decoder 不能"作弊" Vaswani et al. arXiv:1706.03762
自注意力让每个词都能"看到"句子里所有其他词——这对 BERT 这种理解任务很好(可以双向看全句)。但 GPT 这类 Decoder(生成模型)有个铁律:生成第 i 个词时,绝对不能偷看第 i+1、i+2… 这些"未来"的词,否则就是作弊(答案提前泄露)。如何在自注意力里实现"只许看过去、不许看未来"?答案就是因果掩码(Causal Mask)。
下三角掩码矩阵:■ 可见 / □ 遮蔽
做法:在算 Q·Kᵀ 得到的 n×n 注意力分数矩阵上,叠加一个下三角掩码——把"未来"位置(上三角)的分数设为 −∞,softmax 后这些位置的权重就变成 0(被完全遮蔽)。
对于一个 4 词序列,掩码矩阵长这样:
位置1 位置2 位置3 位置4
位置1 → ■ □ □ □
位置2 → ■ ■ □ □
位置3 → ■ ■ ■ □
位置4 → ■ ■ ■ ■
■ = 可见(对角线及以下,即 ≤ 自己的位置),□ = 被遮蔽(严格大于自己的"未来"位置)。
- 位置 1(第一个词)只能看到自己——它没有任何前文。
- 位置 3能看到位置 1、2、3,但看不到位置 4(未来)。
- 位置 4(最后一个词)能看到全部。
这样每个位置 i 只能关注 ≤ i 的位置,保证了自回归生成(autoregressive)的合法性:预测下一个词时,模型真的只能依据已生成的前文,没偷看答案。
因果掩码不仅是"防作弊",它还直接保证了 KV Cache 可行。因为有了 mask,位置 i 的 K/V 一旦算出来,就永远不会被未来的计算改变——未来位置 j(j>i)只能"看"位置 i,而不会反过来修改 i 的 K/V。历史 token 的 K/V 永不变,所以才能放心地缓存起来反复用(详见第四篇 KV Cache)。可以说:没有因果掩码,就没有 KV Cache,也就没有今天高效的大模型推理。
④ 多头注意力(Multi-Head Attention)
单次自注意力只能学一种"关注模式"。多头注意力把 Q、K、V 分成 h 份(头),每个头独立做一次自注意力——相当于让模型同时从多个视角理解句子(一个头关注语法、一个关注指代、一个关注情感……),最后拼接起来。
多头注意力的算式
MultiHead = Concat(head_1, …, head_h) · W^O
每个头用独立的 W_i^Q, W_i^K, W_i^V(维度为 d_model/h),h 个头的结果拼接后用 W^O 投影回原维度。例如 GPT-3 用 96 个头。代价是计算量与头数成正比,但表达力显著增强。
⑤ 多头注意力的现代变体:MHA / MQA / GQA Shazeer arXiv:1911.02150 / Ainslie arXiv:2305.13245
标准的多头注意力(MHA)每个头都有自己独立的 K、V,带来强大表达力的同时,也留下一个"后遗症":KV Cache 的大小正比于头数 H。在大模型推理时,这个开销极为昂贵(详见第四篇 KV Cache)。于是人们从注意力结构本身动刀,发展出三种变体,成为现代大模型的标配设计选择。
| 变体 | K/V 的设计 | KV Cache 相对 MHA | 质量 / 速度权衡 |
|---|---|---|---|
| MHA(标准多头) | 每个头独立一套 K、V | 1× (基线) | 质量最好,但 KV Cache 最大 |
| MQA(Multi-Query) | 所有头共享同一套 K、V | 1/H (最省) | 推理最快、最省显存,但质量有明显下降 |
| GQA(Grouped-Query) | 把头分成 G 组,每组共享一套 K、V | 1/G (折中) | 质量接近 MHA,显存大幅省 —— 主流大模型首选 |
MHA / MQA / GQA 的本质:Q 头与 K/V 头的解耦
关键洞察:注意力里查询头数(num_attention_heads)与K/V 头数(num_key_value_heads)可以不相等。Q 头照常并行计算,而 K、V 只需按更少的"组"来生成和缓存。
- MHA:Q 头 = K/V 头 = H(如 32)
- MQA(Shazeer, arXiv:1911.02150):Q 头 = H,K/V 头 = 1(所有 Q 共享一套 K、V)
- GQA(Ainslie et al., arXiv:2305.13245):Q 头 = H,K/V 头 = G(如 8),即 H/G 个 Q 头共享一组 K、V
实例:DeepSeek-R1-Distill-Qwen-1.5B 的 config.json 中 num_attention_heads=12 而 num_key_value_heads=2,即每 6 个 Q 头共享一套 K、V —— KV Cache 仅为 MHA 的 1/6。
现代主流大模型 Llama 2/3、Mistral、Qwen 等几乎都采用 GQA。它在"KV Cache 内存"和"模型质量"之间取得了最佳平衡,是 KV Cache 优化中最有效、应用最广的方法之一。
例外:DeepSeek 不用 GQA,而是自研 MLA(Multi-head Latent Attention)——通过低维潜在向量压缩 K/V 来减少 KV Cache,与 GQA 思路类似但实现完全不同:GQA 是"多个 Q 头共享同一套 K/V 头",MLA 是"把 K/V 压缩到低维潜在向量再解压还原"。两者都能减小 KV Cache,但路线不同。
⑥ 位置编码(Positional Encoding)
自注意力有个"副作用":它对位置无感。因为每个词和所有词对称地计算注意力,打乱句子顺序,结果不变(词袋模型)。但语言顺序至关重要("狗咬人"≠"人咬狗")。位置编码把每个词的位置信息注入它的表示,让模型知道"谁在前谁在后"。
| 方式 | 原理 | 代表 |
|---|---|---|
| 正弦/余弦编码 | 用不同频率的 sin/cos 函数生成位置向量,加到词嵌入上 | 原始 Transformer(2017) |
| 可学习位置编码 | 每个位置一个可训练向量 | BERT、GPT-2/3 |
| RoPE 旋转位置编码 | 用旋转矩阵把相对位置编码进注意力 | LLaMA、Qwen、DeepSeek 等现代大模型主流 |
原始 Transformer 的正弦位置编码
PE(pos, 2i+1) = cos( pos / 10000^(2i/d) )
pos 是位置,i 是维度序号,d 是模型维度。不同频率的正余弦让每个位置有唯一编码,且能外推到训练时未见过的更长序列。
⑦ Encoder vs Decoder:GPT / BERT / T5 的根源
原始 Transformer 是编码器-解码器结构。后来人们只用其中一半,发展出三条至今影响深远的路线:
Decoder-only(GPT 路线)
只保留解码器,从左到右预测下一个词(自回归)。所有现代对话大模型(GPT、Claude、LLaMA、Qwen、DeepSeek)都是这条路线。
Encoder-only(BERT 路线)
只保留编码器,双向看全句,擅长理解(分类、检索)。代表 BERT。不适合生成。
Encoder-Decoder(T5 路线)
保留完整结构,把所有任务统一成"文本→文本"。代表 T5、BART。
Decoder-only 的自回归范式(预测下一个词)天然适合无监督的海量文本训练(不需要人工标注,下一个词就是天然标签),且生成能力强。Scaling Law 的力量让它在规模放大后,理解和生成能力全面超越另两条路线。
一个完整 Transformer 层的内部结构
大模型是把如下"Transformer Block"堆叠 N 次(GPT-3 是 96 层)。每层包含:
前馈网络 FFN 通常是两层 MLP 加激活函数(GELU):
每个子层都套 LayerNorm(x + Sublayer(x)) 的"残差+归一化"结构。注意力负责"词与词的信息混合",FFN 负责"每个位置的非线性变换",二者交替堆叠构成强大表征。
第四篇 · 大模型原理
把 Transformer 做到千亿参数、用全网文本训练,就跨入"大模型"领域。这一篇讲清大模型区别于普通神经网络的几个关键概念:语言模型简史、分词、词嵌入、预训练目标、规模定律、混合专家、KV Cache、上下文长度限制。
① 语言模型简史:从 n-gram 到 NNLM Bengio et al. 2003
在理解大模型"为什么会接话"之前,先回答一个更根本的问题:语言模型(Language Model)到底在做什么?答案出奇地简单——预测一句话出现的概率,或等价地,在给定前文的情况下预测下一个词的概率。今天 GPT/Claude 做的"下一个 token 预测",本质就是 70 多年前统计语言模型的延续。
n-gram 模型:靠"数频率"猜下一个词
最早的实用语言模型是 n-gram 模型:用训练语料里连续 n 个词出现的频率来估计概率。比如 trigram(n=3)会统计"今天 天气 真"出现多少次,据此估计"真"接在"今天 天气"后的概率。
n-gram 有两个致命缺陷:
- 只能看很短的上下文。受数据和计算限制,n 一般只能取 3 或 4。再远的上下文完全看不到,长距离依赖无从谈起。
- 无法理解词语相似性,泛化能力极差。模型只认"具体词串"。它学过"猫 喜欢 吃 鱼",但遇到"狗 喜欢 吃 骨头"会很茫然——因为它不知道"猫"和"狗"、"鱼"和"骨头"在语义上是相似的。没见过的词组合,概率就被估为 0。
维度灾难(Curse of Dimensionality)
假设要预测一句话里 10 个词的组合概率,每个词有 10 万种可能,那么总的组合数为 10万¹⁰——一个天文数字。训练语料再大,相对这个空间也极其稀疏:绝大多数合理的句子模型从未见过,概率只能估为 0。这就是"维度灾难",是传统 n-gram 无法跨越的根本障碍,也正是 Bengio 试图用神经网络攻克的难题。
NPLM(2003):词向量 + 神经网络,大模型原理的历史起点
2003 年,Bengio 等人提出 神经概率语言模型(NPLM, A Neural Probabilistic Language Model),一举解决 n-gram 两大缺陷。它的两大核心创新:
- 为每个词学习一个"词向量":把词映射成低维稠密向量,让相似词在向量空间里靠近——这样模型就知道"猫"和"狗"相似,能从"猫 吃 鱼"泛化到"狗 吃 骨头"。
- 用神经网络学习语言模型:网络能建模复杂的非线性关系,更好地利用上下文,并捕捉词语间的相似性,泛化到未见过的句子。
NPLM 的结构简洁而奠基性:
NPLM(2003)首次把词向量和神经网络引入语言模型,奠定了"用低维稠密向量表示语义、用网络学习语言规律"这条主线。Transformer(2017)和今天的大模型,本质上仍在这条路上狂奔——大模型原理的历史起点,正是这篇 2003 年的论文。理解了 NPLM,就理解了为什么大模型"能理解语言"。
② 分词(Tokenization):文本如何变成模型的输入 Sennrich et al. arXiv:1508.07909
神经网络只懂数字,不懂文字。第一步是把文本切成一个个token(词元),每个 token 映射为一个整数 ID,再查表变成向量。最主流的方法是 BPE(Byte Pair Encoding,字节对编码)。
BPE 不是按词切(词表太大、生词多),也不是按字符切(太碎、丢失语义),而是按统计高频子词切分。如"unbelievable"可能切成"un""believ""able"。好处:词表适中(几万)、能处理任何新词和拼写错误、常见词整体保留语义。
BPE 工作原理与 Token 计费
BPE 训练过程(Sennrich et al., arXiv:1508.07909):从字符级开始,反复合并语料中出现频率最高的相邻符号对,直到词表达到目标大小。合并规则保存下来,推理时按同样规则切分。
示例:"lower" "newer" "lower" → 统计发现 "er" 高频 → 合并为一个 token。最终常见后缀、词根都成为独立 token。
实践影响:API 按 token 计费,不同模型分词器不同(GPT 用 tiktoken/BPE 变体;中文一个字通常≈1 token,英文一个词≈1-2 token)。理解 token 是理解大模型"上下文长度""成本""速度"的基础。
③ 词嵌入(Embedding):从离散 token 到连续语义空间 Bengio et al. 2003 / Mikolov arXiv:1301.3781
token 只是一个整数 ID(如 "猫"→3472),数字本身没有语义。神经网络无法直接处理这种"无意义编号"。必须把每个 token 映射成一个低维稠密向量(如 4096 维浮点数),让语义相近的词在向量空间里距离也相近——这就是词嵌入(Word Embedding)。它是 2003 年 Bengio 神经概率语言模型(NPLM)的核心遗产。
one-hot 的缺陷 与 分布式表示
朴素的 one-hot 编码:每个词用一个长度=词表大小(如 50000)的向量表示,只有自己位置是 1,其余全 0。
- 缺陷 1:维度爆炸且全稀疏。50000 维向量只有 1 个 1,浪费严重。
- 缺陷 2:所有词两两正交。任意两个 one-hot 向量的点积都是 0,模型完全无法表达"猫"和"狗"相似——语义信息为零。
分布式表示(Distributed Representation):放弃 one-hot,让每个词用一个低维稠密向量(如 300 或 4096 维)表示,每一维都承载一部分语义。这就是 Bengio 在 NPLM(2003)中提出的革命性思想,也是所有现代词向量的基础。
词向量矩阵 与 查表过程
整个词表所有词的向量堆在一起,构成一个词向量矩阵(Embedding Matrix),维度为 vocab_size × hidden_size。
实例:DeepSeek-V3 的 vocab_size=129280,hidden_size=7168,则词向量矩阵 = 129280 × 7168 ≈ 9.26 亿参数,约占 1.77 GB(bfloat16)。
查表(Lookup)过程:拿到 token ID(如 3472),直接去矩阵里取第 3472 行,就得到该词的向量。这就是"嵌入层(Embedding Layer)"做的事——本质是一个可学习的查找表。
词向量最经典的特性是语义可由向量运算刻画。Mikolov 等人(Word2Vec, arXiv:1301.3781)发现:把"king"的向量减去"man"再加上"woman",得到的新向量,最接近的词恰好是"queen"。这说明词向量空间里编码了类比、性别、国家关系等结构。这种"几何即语义"的特性,是模型能理解语言的根本原因。
词向量的三种生成方式
| 方式 | 训练范式 | 代表 |
|---|---|---|
| Word2Vec | 独立训练:用中心词预测上下文(Skip-gram)或反之(CBOW),训练完向量固定供下游使用 | Word2Vec (arXiv:1301.3781) |
| GloVe | 独立训练:基于全局词共现矩阵优化 | GloVe (Pennington et al., 2014) |
| Transformer 嵌入层 | 端到端学习:嵌入矩阵只是模型的一层权重,随整个大模型一起预训练、反向传播更新 | GPT / BERT / LLaMA 等所有现代大模型 |
现代大模型几乎都用第三种——词向量不再是"事先训好再加载"的外部资源,而是模型自身权重的一部分(存在 model.safetensors 里)。这也是为什么同一个词在不同大模型里的向量不同:它们是各自模型在自己的语料和目标下学出来的。
④ 预训练目标:自回归语言建模
大模型预训练时到底在做什么任务?Decoder-only 大模型(GPT 路线)的核心目标只有一个:给定前文,预测下一个 token。这个看似简单的任务,在海量文本上重复万亿遍,就逼出了语言能力。
要准确预测下一个词,模型被迫理解语法、事实、推理、世界知识——因为只有真正"懂"了,才能猜对。比如要预测"法国的首都是___"的下一个词,模型必须"知道"巴黎。预训练因此把海量知识压缩进了参数。
| 路线 | 预训练目标 | 代表 |
|---|---|---|
| Decoder-only | 自回归:从左到右预测下一个词(causal LM) | GPT 全系、LLaMA、Qwen、DeepSeek |
| Encoder-only | 掩码语言建模 MLM:随机遮盖部分词,让模型还原 | BERT |
⑤ 规模定律(Scaling Law) Kaplan et al. arXiv:2001.08361 / Hoffmann et al. arXiv:2203.15556
这是大模型时代最重要的经验发现:模型性能(loss)随参数量、数据量、计算量呈可预测的幂律(power-law)提升。换句话说,只要持续放大规模,能力就会持续提升——这给了行业"大力出奇迹"的信心和路线图。
Kaplan Scaling Law(2020)与 Chinchilla 最优比例(2022)
Kaplan et al.(arXiv:2001.08361, 2020)发现测试损失随参数量 N、数据量 D、计算量 C 近似服从幂律:
这意味着性能可外推预测——先在小规模上拟合曲线,就能预测千亿模型的 loss。这是 GPT-3 及后续军备竞赛的理论依据。
Chinchilla(Hoffmann et al., arXiv:2203.15556, 2022)修正了 Kaplan 的结论:在固定计算预算下,模型和数据应同步放大,最优训练 token 数约为参数量的 20 倍(20 tokens/parameter)。此前 GPT-3(175B 参数 / 300B tokens)严重欠训练。
DeepMind 用 70B 参数 + 1.4T tokens 训练的 Chinchilla 反超了 5 倍大的 Gopher(MMLU 67.5%,提升 7%+)。这一发现深刻改变了训练策略——大家不再一味堆参数,而是投入更多数据。
⑥ 混合专家(MoE):用更少算力做更大模型 Shazeer arXiv:1701.06538 / Fedus arXiv:2101.03961
把模型做大,推理算力成本也线性飙升。混合专家(Mixture of Experts)是一个精妙的解法:模型里放很多个"专家"网络,但每个 token 只激活其中少数几个(其余休眠)。这样总参数很大(容量大),但单次计算量很小(成本低)。
MoE 的门控机制与代表模型
每个 MoE 层把传统的 FFN 替换为"门控路由 + 多个专家 FFN":
门控网络 G 根据输入 x 决定激活哪几个专家。Switch Transformer(Fedus et al., arXiv:2101.03961)简化为每个 token 只路由到 1 个专家,扩展到万亿参数。
| 模型 | 总参数 | 激活参数 | 专家数 |
|---|---|---|---|
| Mixtral | ~47B | ~13B | 8 选 2 |
| DeepSeek-V3 / R1 | 671B | 37B | 256 选 8 |
| openPangu 2.0 Pro | 505B | 18B | — |
MoE 的挑战是负载均衡(避免所有 token 都涌向少数专家)和通信开销(专家分布在不同 GPU)。DeepSeek 提出的无辅助损失负载均衡(auxiliary-loss-free)是重要工程创新。
⑦ KV Cache:推理加速的关键工程
大模型逐词生成回答,这种方式叫自回归解码(Auto-regressive Decoding):每生成一个新词,都要把它和前面所有已生成词拼起来,作为下一步的上下文。生成第 N 个词时,前 N−1 个词的 K、V 向量要重新算吗?不需要——它们在前面步骤已算过且永不会变。KV Cache 就是把这些已算好的 K、V 缓存起来,每生成一个新词只算新词的 K、V 并追加,避免重复计算。
为什么 KV Cache 把复杂度从 O(n²) 降到 O(n)
没有 KV Cache 时:生成第 N 个词,要重新计算前 N−1 个词的 K、V;生成第 N+1 个词,又要重新计算前 N 个词的 K、V……随着序列变长,重复计算量呈平方级增长,长文本几乎不可用。
有 KV Cache 后:历史词的 K、V 已缓存,每生成一个新词只需算这一个新词的 K、V 并追加进缓存,再用它的 Q 与缓存里所有 K 做注意力。每步计算量与序列长度无关(恒定),整体复杂度从二次方 O(n²) 降到线性 O(n)。
KV Cache 内存占用公式 与 实例
KV Cache 的总大小由五个因素决定:
L= 序列长度(输入+输出总 token 数)N= Transformer 层数H= 注意力头数D= 每个头的维度2= K 和 V 两份sizeof(dtype)= 每个数占的字节数(float16 / bfloat16 = 2 字节)
实例(Llama-7B,单序列)(注:Llama-7B 为 MHA 架构,32 头全独立 K/V;GQA 从 Llama-2 70B 起才采用):
注意:这只是单条序列的 KV Cache(尚未算模型参数本身)。若做批处理同时服务 32 个用户,仅 KV Cache 就要 67 GB——这正是大模型推理的显存大头。
TTFT、Prefill 阶段 与 KV Cache 三大限制
TTFT(Time-To-First-Token,首 token 响应时间):用户发出请求到收到第一个词的延迟,是体验的关键指标。TTFT 的主因是 Prefill 阶段——模型要一次性处理整段长上下文(prompt),计算所有 prompt 词的 K、V 并构建初始 KV Cache。prompt 越长,Prefill 越慢,TTFT 越高。
解码阶段(Decode)则相反:每步只算一个新词(得益于 KV Cache),单步很快,但逐步累积。
- 最大上下文长度:序列越长,KV Cache 越大,显存撑不住就截断。
- 批处理量(Batch Size):每条请求都要自己的 KV Cache,显存决定了能并发服务多少用户。
- 可部署的模型大小:模型越大(层数多、头数多),单条 KV Cache 就越大,留给批处理的余量越小。
这三条限制,催生了下一节的 MQA/GQA(从结构上减少 K、V 数量)和第五篇的 PagedAttention(从内存管理上榨干显存)。
⑧ 上下文长度限制:max_position_embeddings
翻看任何大模型的 config.json,都会看到一个关键参数 max_position_embeddings(如 DeepSeek-V3 = 163840)。它决定了模型能处理的最大序列长度,但这个"长度天花板"背后是一连串技术权衡。
max_position_embeddings 约束的是输入 prompt 与输出生成拼成完整序列后的总长度,而非只算输入。例如设为 4096,则"输入 3000 + 输出 1096"合法,但"输入 4000 + 输出 100"会触发截断。因为自回归模型把输入输出当成一条连续序列处理,所有 token 两两计算注意力,总长受限于位置编码覆盖范围。
为什么上下文不能无限长:三大瓶颈
① RoPE 远端失效。现代大模型多用旋转位置编码(RoPE),其旋转角度差异随位置距离指数级衰减。当两词距离超出训练长度(如原设计 4096),远端 token 的旋转差异趋近于零,模型无法区分它们的位置关系,注意力得分失效。
② 注意力稀释(Attention Dilution)。softmax 归一化后,序列越长,每个位置分到的注意力权重越分散。极端情况下,关键信息被均摊到海量 token 上,权重趋近 1/n,模型对关键信息的捕捉能力随长度下降。
③ 显存 O(n²) 黑洞。注意力机制要存储 (batch, heads, seq_len, seq_len) 的注意力矩阵,显存随序列长度平方增长。设 seq_len=163840,单头注意力矩阵就约 53.7 GB,128 头总计约 6874 GB——远超任何单卡 GPU。即便用 FlashAttention 规避存储完整矩阵,计算量仍是 O(n²)。
外推方案:YaRN 与 滑动窗口
训练时用较短长度(如 4096),推理时却想用更长上下文——这叫长度外推(Extrapolation)。主流方案:
- YaRN(Yet another RoPE extensioN):在推理时调整 RoPE 的频率参数,临时扩展长度上限。代价是超出原训练长度后,准确率会下降约 5–20%。
- 滑动窗口注意力(Sliding Window):每个 token 只关注最近 N 个 token(窗口大小 N ≤ max_position),而非全部。内存与序列长度无关,适合长文本流式推理(如 Mistral、LongFormer),但跨窗口的长程依赖会断裂。
- 分块处理(Chunking):把超长文档切成多块分别处理,再合并结果。缺点是块间信息丢失可达 15–30%。
所以 max_position_embeddings 不是简单的数字设定,而是硬件算力、数据质量、算法创新三者的动态平衡点——既要给模型足够的能力空间,又要防止它被自身的计算重量压垮。
⑨ config.json 关键字段解读:模型结构的"身份证" HuggingFace Transformers 标准
从 HuggingFace 下载一个大模型,除了体量巨大的权重文件,一定还有一个几十行的 config.json。它是模型的"身份证"和施工图——把模型架构、各层维度、数据类型等关键信息全部写明,框架据此重建出正确的网络结构再加载权重。理解它的关键字段,就能在不读代码的情况下看懂一个模型长什么样。
| 字段 | 含义 | 实例(DeepSeek-R1-Distill-Qwen-1.5B) |
|---|---|---|
architectures | 模型架构类名,决定用哪套网络实现 | ["Qwen2ForCausalLM"](Qwen2 架构,因果语言建模) |
hidden_size | 隐藏层维度(每个 token 的向量维度 d) | 1536 |
num_attention_heads | 注意力头数(Q 头数 H) | 12 |
num_hidden_layers | Transformer 层数 N(堆叠几个 Block) | 28 |
num_key_value_heads | K/V 头数(小于 Q 头数即 GQA) | 2(每 6 个 Q 头共享一套 K/V) |
rope_theta | RoPE 旋转位置编码的基准频率 θ | 10000 |
max_position_embeddings | 最大可处理序列长度(输入+输出总和) | 131072 |
torch_dtype | 模型参数的数据类型(决定文件大小) | "bfloat16"(每参数 2 字节) |
vocab_size | 词表大小 V(决定词嵌入矩阵规模) | 151936 |
看到 hidden_size=1536、num_hidden_layers=28、num_key_value_heads=2 < num_attention_heads=12,就能立刻判断:这是个小模型(约 1.5B),用 GQA(K/V 头只有 2 个),KV Cache 仅为标准 MHA 的 1/6;torch_dtype=bfloat16 说明权重按每参数 2 字节存储。这几个数字组合起来,就勾勒出了模型的"身材轮廓"。
DeepSeek-V3(671B)的 config.json 关键值对比
作为对比,DeepSeek-V3(671B 总参 / 37B 激活的 MoE 模型)的关键字段明显大一个量级:
| 字段 | DeepSeek-V3 | 对比 1.5B 小模型 |
|---|---|---|
hidden_size | 7168 | 约为 1536 的 4.7 倍 |
num_hidden_layers | 61 | 约 2 倍层数 |
num_attention_heads | 128 | 远多于 12 头 |
num_key_value_heads | 128 | 与 Q 头数相等(见下方 MLA 注释,并非 GQA) |
vocab_size | 129280 | 略小(V3 词表反而更精简) |
max_position_embeddings | 163840 | 超长上下文 |
torch_dtype | "bfloat16" | 同为每参数 2 字节 |
DeepSeek-V3 用自研 MLA(Multi-head Latent Attention),不是 GQA/MQA。这里 num_attention_heads=128 与 num_key_value_heads=128 相等,并不代表它是标准 MHA 或 GQA——V3 的 K/V 通过 kv_lora_rank(潜在压缩维度)压成一个低维潜在向量,缓存和推理时只存/解压这个潜在向量,而非原始 128 个 K/V 头。所以"两个值相等"只是 HuggingFace 兼容字段下的表象,注意力机制本身与 GQA 完全不同。
注意:V3 还会有 MoE 相关字段(如 n_routed_experts 专家数、num_experts_per_tok 每 token 激活专家数),这是它总参 671B 但单次只激活 37B 的配置来源。
⑩ 模型文件大小与参数精度:671B 到底多大 参数量 × 每参数字节数
一个常被问的问题:671B 的大模型,model.safetensors 文件到底有多大?答案是——取决于用哪种精度存储。模型文件大小的本质公式极简:
参数量(如 671B = 6710 亿)由模型结构固定,剩下唯一变量就是"每参数字节数",即上一节(量化原理深化)那张精度表的内容:
| 精度 | 每参数字节 | 671B 模型文件大小(约) |
|---|---|---|
| FP32(float32 单精度) | 4 字节 | 671B × 4 = 2684 GB ≈ 2.68 TB |
| FP16(float16 半精度) | 2 字节 | 671B × 2 = 1342 GB ≈ 1.34 TB |
| BF16(bfloat16) | 2 字节 | 671B × 2 = 1342 GB ≈ 1.34 TB |
| INT8(8 位整数) | 1 字节 | 671B × 1 = 671 GB |
| INT4(4 位整数,如 Q4_K_M) | 0.5 字节 | 671B × 0.5 ≈ 335 GB |
同一个 671B 模型,FP32 要 2.68 TB(基本没人会用这么大的精度去存/推理),到 INT4 量化后只剩约 335 GB——缩小到原来的 1/8。这正是 Ollama 上 DeepSeek-V3 的 Q4_K_M 版本约 404GB 的来源(含少量元数据,且 4 位量化有 4.0~4.9 位的不同变体)。精度选择直接决定模型能不能塞进一块/几张 GPU。
混合精度训练:文件里的参数不一定是同一精度
model.safetensors 里的参数精度可能是不统一的。原因有二:
- 混合精度训练(Mixed Precision Training):为兼顾训练速度、显存占用与数值稳定性,现代模型训练时不同部分用不同精度——对精度敏感的部分(如注意力权重、损失计算相关)用 FP32,其余(如 FFN 权重)用 FP16/BF16。导出的权重文件里各张量自然精度各异。
- 量化部署:推理部署时为减小体积、加速,把部分或全部 FP16/BF16 权重进一步量化成 INT8/INT4。
要确认每个参数张量的真实精度,可以查看 config.json 的 torch_dtype(主精度),或用 HuggingFace Transformers 加载后遍历 model.named_parameters() 打印每个张量的 dtype。
⑪ model.safetensors 存什么:权重的安全容器 HuggingFace Safetensors 格式
下载模型时,model.safetensors 几乎总是最大的文件(小到几百 MB,大到数百 GB)。它里面装的是模型学习到的全部权重(Weights)——也就是反向传播亿万次后沉淀下来的、决定模型行为的那堆数字。
为什么是 .safetensors 而不是 pickle
Safetensors 是 HuggingFace 推出的一种安全、快速、简单的张量序列化格式,专门用来存储模型权重。
- 安全:传统 PyTorch 用
pickle格式存权重,而 pickle 在反序列化时可能执行任意代码(加载来路不明的 .bin 模型有被植入恶意代码的风险)。Safetensors 只存张量数据,不含任何可执行代码,从根上规避了这一安全风险。 - 快速:采用零拷贝(zero-copy)加载,读取比 pickle 更快。
所以现在 HuggingFace Hub 上新模型默认用 .safetensors,.bin(pickle)格式正逐步被淘汰。
权重文件里到底装了哪些权重
以一个 Transformer 大模型为例,model.safetensors 里存的就是前几篇讲过的所有可学习参数:
| 权重类型 | 对应组件 | 说明 |
|---|---|---|
| 词嵌入矩阵 | Embedding Layer | 词表 V × 隐藏维度的查找表(见 ③ 词嵌入) |
| 注意力权重 Q/K/V/O | 每层 Multi-Head Attention | 四个投影矩阵 W_Q, W_K, W_V, W_O(见 ② 自注意力) |
| FFN 权重 | 每层前馈网络 | 两层 MLP 的 W₁, W₂(含 MoE 时还有各专家的权重) |
| LayerNorm 参数(γ/β) | 每个归一化层 | 归一化的缩放与偏移两个可学习参数 |
| 偏置(Bias) | 各线性层 | 每个神经元的偏置项 b(部分模型如 LLaMA 不用偏置) |
为什么只存权重,不存优化器状态
训练阶段,Adam 等优化器会为每个参数额外维护动量、二阶矩等状态(optimizer state),这些状态加起来体积与权重相当甚至更大。但 model.safetensors 里不存这些——原因很简单:
- 推理只需要权重。前向传播算出预测,靠的是 W, b 这些参数本身,优化器状态在推理时用不到。
- 优化器状态只在"继续训练"时需要。若要断点续训,会单独保存一个
optimizer.pt之类的文件,与权重文件分离。
所以分发给用户做推理用的 model.safetensors 只保留做预测必需的权重,把与推理无关的训练状态全部剥离,让文件尽可能小、加载尽可能快。
第五篇 · 对齐与推理优化
预训练出的基础模型会"接话"但不懂"听指令"、会乱说话。让模型变得有用、诚实、无害(对齐),并让它学会深度推理,是 2022 年后大模型工程的核心。这一篇讲清 SFT、RLHF、CoT 推理模型,以及推理加速技术。
① SFT:监督微调——教模型"听指令"
预训练模型只会"续写"。SFT(Supervised Fine-Tuning,监督微调)用数万条人工编写的"指令-回答"示例微调模型,让它学会按人类指令格式作答,而不是无脑续写。这一步把"语言模型"变成"助手雏形"。
② RLHF:人类反馈强化学习——让模型"对齐"人类偏好 Ouyang et al. arXiv:2203.02155
SFT 后的模型仍可能啰嗦、错误、有害。RLHF(Reinforcement Learning from Human Feedback)是 ChatGPT 的核心对齐技术,分三步:
- SFT:先用指令数据微调(即上一步)。
- 训练奖励模型(RM):让模型对同一问题生成多个回答,人类标注员给回答排序;训练一个"奖励模型"学习人类的偏好打分。
- 强化学习优化:用奖励模型的分数作为奖励信号,用 PPO 等算法优化语言模型,让它生成高分回答。
InstructGPT(Ouyang et al., arXiv:2203.02155,2022 年 1 月提交)首次系统落地 SFT+RLHF,是ChatGPT(2022-11)的直接技术基础。RLHF 让模型从"会接话"变成"好用、安全、符合人类意图",是大模型走向大众的关键一跃。
RLHF 的目标函数(PPO)
RLHF 最大化奖励的同时,要防止模型为迎合奖励而"跑偏"(偏离原始语言能力),故加 KL 惩罚项:
其中 r_φ 是奖励模型打分,π_θ 是当前策略,π_SFT 是 SFT 模型,β 控制偏离程度。DeepSeek-R1 用的 GRPO(Group Relative Policy Optimization)是 PPO 的简化变体——免去价值网络,用组内相对优势估计,更省算力。
③ CoT 与推理模型:让模型"先想后答" Wei et al. arXiv:2201.11903
普通大模型直接给答案,遇到复杂数学/逻辑题容易出错。思维链(Chain-of-Thought, CoT)的发现(Wei et al., 2022):只要让模型在给出最终答案前,先一步步写出推理过程,准确率就大幅提升——就像人解难题要打草稿。
推理模型(OpenAI o1, 2024-09;DeepSeek-R1, 2025-01)把 CoT 推向极致:用强化学习直接训练模型自主生成高质量思维链。DeepSeek-R1-Zero 更进一步证明纯 RL(无 SFT)即可激发推理能力。
CoT 为何有效 / R1-Zero 的关键发现
Wei et al.(arXiv:2201.11903)发现:在 few-shot 示例中加入推理过程,模型在算术、常识、符号推理任务上显著提升。本质是把复杂问题分解为多个简单步骤,每步的计算量增加,但每步更可靠。
R1-Zero 的突破(arXiv:2501.12948):直接对基础模型做 RL(GRPO),用可验证奖励(数学题有标准答案)训练,不经过任何 SFT,推理能力就涌现——AIME 2024 pass@1 从 15.6% 提升到 71.0%(R1-Zero);进一步加入少量冷启动数据的 R1 模型则达到 79.8%。这颠覆了"必须先 SFT 再 RL"的常识。
④ 推理与训练优化技术
大模型的训练和推理极其昂贵,催生了一系列关键优化技术。这些技术是"用得起"大模型的工程基础。
| 技术 | 解决什么 | 来源 |
|---|---|---|
| FlashAttention | 注意力计算 IO 优化,精确加速(无近似),省显存 | Dao et al., arXiv:2205.14135, 2022 |
| LoRA | 微调时冻结原参数,只训练注入的低秩矩阵,省显存/算力 | Hu et al., arXiv:2106.09685, 2021 |
| 量化(Quantization) | 把参数从 16 位压缩到 8/4 位,大幅省显存、加速推理(轻微精度损失) | 工程方法 |
| 知识蒸馏(Distillation) | 用大模型(教师)的输出训练小模型(学生),小模型逼近大模型能力 | R1 蒸馏出 6 个小模型 |
| 并行训练 | 数据/张量/流水线并行,把千亿模型拆到数千 GPU 上训练 | 工程方法 |
FlashAttention 与 LoRA 的核心原理
FlashAttention(arXiv:2205.14135):注意力计算的瓶颈不是算力,而是GPU 高带宽内存(HBM)的读写(IO)。FlashAttention 用分块(tiling)+ 在线重缩放,把中间结果尽量留在高速 SRAM 中,减少对慢速 HBM 的读写。结果完全精确(exact attention),却快数倍、省数倍显存。几乎所有现代大模型推理都用它。
LoRA(Low-Rank Adaptation, arXiv:2106.09685):微调时冻结原权重 W₀,只训练一个低秩更新:
若原矩阵是 4096×4096(1600 万参数),取 r=8 则 B、A 共 (4096+4096)×8 ≈ 6.5 万参数,可训练参数减少 99%+,显存和算力大幅下降,而效果接近全参数微调。这是个人/小团队微调大模型的标准方法。
量化原理深化:从浮点到整数,scale 与 zero-point 的数学 工程方法 · KV Cache 量化 arXiv:2405.14256
上一节表格里提到"量化把参数从 16 位压缩到 8/4 位"。这里展开它背后的数学原理——量化到底在做什么,以及为什么"量化粒度"对精度影响巨大。
量化的本质:把一个浮点数范围映射到一个整数范围。具体靠两个参数完成:一个 Scale(缩放因子)决定浮点范围被压缩的程度;一个 Zero-point(零点偏移)记录"浮点数中的 0"对应量化后的哪个整数。
量化的核心公式:量化与反量化
把浮点值 F.P. 量化成整数,再用整数反量化回浮点值:
浮点值 = ( 量化值 − Zero-point ) × Scale
逐步拆解(以把 [−1.0, 1.0] 范围的浮点数量化到 [−128, 127] 的 INT8 为例,取 Scale = 1/127、Zero-point = 0):
- 浮点数
0.5→ 除以 Scale:0.5 / (1/127) = 63.5 - 加 Zero-point:
63.5 + 0 = 63.5 - 四舍五入(round)→ 得到量化整数
64 - 反量化:
(64 − 0) × (1/127) = 0.5039…(与原始 0.5 接近,但有舍入误差)
这个舍入误差就是量化"轻微精度损失"的来源。Scale 选得越贴合一组数据的真实分布范围,误差越小。
精度等级:每个参数占多少字节
量化的代价与收益,直观体现在"每个参数占几个字节"上。下表是常见精度等级(也是 G.章节后文计算模型文件大小的基础):
| 精度 | 位数 | 每参数字节 | 说明 |
|---|---|---|---|
| FP32(单精度浮点) | 32 位 | 4 字节 | 范围/精度最高,训练默认;推理太占显存 |
| FP16(半精度浮点) | 16 位 | 2 字节 | 比 FP32 省一半空间,精度略低 |
| BF16(Brain Float) | 16 位 | 2 字节 | 与 FP16 同为 2 字节,但动态范围更大,大模型训练主流 |
| INT8(8 位整数) | 8 位 | 1 字节 | 只占 FP32 的 1/4,计算更快,精度损失较大 |
| INT4(4 位整数) | 4 位 | 0.5 字节 | 极致压缩,推理常用于省显存(如 Q4_K_M 量化) |
量化粒度:Per-Tensor / Per-Channel / Per-Token
同样是量化到 INT8,用一套 Scale 还是多套 Scale,对精度影响极大。这就是"量化粒度(Quantization Granularity)"——为一个多大的范围共用同一组 Scale 和 Zero-point。
| 粒度 | Scale 共享范围 | 特点 |
|---|---|---|
| Per-Tensor(每张量) | 整个张量(整个矩阵/层)共用一个 Scale | 最省存储,但若张量内数值分布跨度大,少量离群值会撑大 Scale,其余值精度被严重拉低 |
| Per-Channel(每通道) | 每个通道(如每行/每列)独立一个 Scale | 更贴合各行/列各自的分布,精度更好,是权重量化的常见选择 |
| Per-Token(每 Token) | KV Cache 中每个 Token(甚至每个 Token 的 K/V 向量的每个维度)独立一套 Scale 和 Zero-point | 最细粒度,能精确捕捉每个 Token 各维度的真实分布,量化误差最小 |
推理过程中 KV Cache 的值非常活跃,分布随序列动态变化。若用粗粒度 Per-Tensor,少量数值大的 Token 会让全局 Scale 偏大,其余绝大多数 Token 的精度被压垮。Per-Token/Per-Channel 这种细粒度量化能为每个 Token 各自拟合最贴合的 Scale,从而把量化误差降到最低——这是 KV Cache 量化(如 ZipCache, arXiv:2405.14256)的关键设计。
对称量化 vs 非对称量化
根据 Zero-point 是否为 0,量化分两类:
- 对称量化(Symmetric):Zero-point = 0,即浮点的 0 量化的整数也是 0。整数范围关于 0 对称(如 INT8 用
[−128, 127])。计算简单、反量化快,适合分布大致关于 0 对称的权重。 - 非对称量化(Asymmetric):Zero-point ≠ 0,允许整数范围整体偏移以贴合分布不以 0 为中心的数据(如激活值常全为正)。精度更好,但量化/反量化多一次加法。
实践中,权重多用对称量化(分布对称、省算),激活/KV Cache多用非对称或细粒度量化(分布偏移大、需精拟合)。
⑤ PagedAttention 与 vLLM:KV Cache 的内存管理革命 Kwon et al. arXiv:2309.06180
前面看到 KV Cache 是显存大户。但问题不止"占用大",还有更隐蔽的内存浪费。传统推理引擎为每条请求的 KV Cache 预分配一整块连续显存,这在实际服务中暴露出致命问题,而 PagedAttention 借鉴操作系统虚拟内存的分页思想,彻底解决了它。
连续分配的三大浪费
- 内存碎片:不同请求序列长度不同,且会动态增长/结束,显存里很快布满零散小块。即使总剩余显存够,也找不到足够大的连续块给新请求,触发 OOM(显存不足)。
- 预分配浪费:为避免上述问题,常按"最大可能长度"预分配,但绝大多数请求用不满,造成大量闲置。
- 批处理填充(padding)浪费:一个批次里所有序列必须填充到最长序列的长度,短请求被迫陪跑,算力和显存双重浪费。
实测中,这些浪费可使显存利用率低至 20–40%——大多数显存不是被有效数据占用,而是被碎片和 padding 吃掉了。
PagedAttention:像操作系统管理内存那样管理 KV Cache
核心思想(Kwon et al., vLLM, arXiv:2309.06180):KV Cache 不再要求一整块连续显存,而是由许多固定大小的小块(Block / Page)组成,这些块可以分散在显存的任意位置。每条请求通过一张"逻辑→物理"映射表记录自己用了哪些物理块。
带来的三大收益:
- 消除碎片:显存利用率几乎拉满,几乎无浪费,OOM 大幅减少。
- 动态扩展:序列按需增长,无需预分配最大长度。
- 更大批处理量:同批可高效混跑不同长度的请求,无需 padding,吞吐显著提升。
写时复制(Copy-on-Write)共享前缀:多条请求常共享相同前缀(如同一个 system prompt)。PagedAttention 让它们共享同一批物理 Block,只有当某条请求开始生成自己独有的内容时,才复制出新 Block。这在多用户服务同一基础指令时省下大量显存。
PagedAttention 是开源推理引擎 vLLM 的核心技术。凭借几乎消除显存浪费、支持高并发混跑,vLLM 在主流大模型推理场景下把吞吐量(tokens/sec)提升了 2–4 倍,是当前 LLM 推理后端最先进的内存管理技术之一,也是多数线上大模型服务的事实标准之一。
🧭完整链条总结:从数学到产业
把全篇串起来,大模型的完整技术链条是这样的:
大模型 = "预测下一个词"这个极简目标 + Transformer 这个高效架构 + 规模定律这个放大杠杆 + RLHF/CoT 这套对齐与推理工程。它的每一次惊艳表现,都是这套链条在万亿参数和万亿 token 上运行的必然结果——而非魔法。
大模型强,但不是万能。它会"幻觉"(编造事实)、受训练数据污染影响榜单表现、"涌现"说法在学术界有争议(Schaeffer et al., arXiv:2304.15004)。理解原理,恰恰是为了既善用其力,也清醒认识其局限。
📚参考文献(已交叉验证)
本文每个关键论断的原始论文,arXiv 编号均已通过检索核证。
| 编号 | 论文 / 来源 | arXiv / 出处 | 年份 |
|---|---|---|---|
| 1 | Attention Is All You Need(Transformer) | arXiv:1706.03762 | 2017 |
| 2 | BERT | arXiv:1810.04805 | 2018 |
| 3 | GPT-3(Language Models are Few-Shot Learners) | arXiv:2005.14165 | 2020 |
| 4 | Scaling Laws for Neural Language Models | arXiv:2001.08361 | 2020 |
| 5 | InstructGPT(RLHF) | arXiv:2203.02155 | 2022 |
| 6 | Training Compute-Optimal LLM(Chinchilla) | arXiv:2203.15556 | 2022 |
| 7 | Chain-of-Thought Prompting Elicits Reasoning | arXiv:2201.11903 | 2022 |
| 8 | Switch Transformers(MoE) | arXiv:2101.03961 | 2021 |
| 9 | Outrageously Large NN(原始 Sparsely-Gated MoE) | arXiv:1701.06538 | 2017 |
| 10 | FlashAttention | arXiv:2205.14135 | 2022 |
| 11 | LoRA: Low-Rank Adaptation | arXiv:2106.09685 | 2021 |
| 12 | Deep Residual Learning(ResNet,残差连接) | arXiv:1512.03385 | 2015/2016 |
| 13 | Layer Normalization | arXiv:1607.06450 | 2016 |
| 14 | Neural MT of Rare Words with Subword Units(BPE) | arXiv:1508.07909 | 2016 |
| 15 | Adam: A Method for Stochastic Optimization | arXiv:1412.6980 | 2014 |
| 16 | Are Emergent Abilities a Mirage?(涌现争议) | arXiv:2304.15004 | 2023 |
| 17 | DeepSeek-R1 | arXiv:2501.12948 | 2025 |
| 18 | DeepSeek-V3 | arXiv:2412.19437 | 2024 |
| 19 | A Neural Probabilistic Language Model(NPLM,词向量+神经网络语言模型鼻祖) | JMLR 2003(Bengio et al.) | 2003 |
| 20 | Word2Vec(Distributed Representations of Words,king−man+woman≈queen) | arXiv:1301.3781 | 2013 |
| 21 | Fast Transformer Decoding(Multi-Query Attention, MQA) | arXiv:1911.02150 | 2019 |
| 22 | GQA: Training Generalized Multi-Query Transformer Models(Grouped-Query) | arXiv:2305.13245 | 2023 |
| 23 | Efficient Memory Management for LLM Serving(PagedAttention / vLLM) | arXiv:2309.06180 | 2023 |
| 24 | Keep the Cost Down(KV Cache 优化综述) | arXiv:2407.18003 | 2024 |