楼层: 首页/ 算法与AI/ 模块七 · Transformer 与大模型进阶
范

模块七 · Transformer 与大模型进阶

Transformer & LLM Deep Dive · 从公式到千亿参数

4.9 节给了注意力公式,但没讲 Q/K/V 从哪来、为什么除以 √dk、BERT 和 GPT 到底差在哪、千亿模型怎么训。这一模块把这些"论文里的硬骨头"啃完。

上一模块讲了怎么训稳神经网络,这一模块把 Transformer 的硬骨头啃完。为什么需要?Q/K/V 从哪来、为什么除 √dk、BERT 和 GPT 差在哪、千亿模型怎么训——这些是你看懂任何大模型论文的门槛。学完你能推导自注意力、说清预训练范式。下一模块看大模型怎么长出手脚。

本模块要学什么(按这个顺序学)
自注意力推导 → 多头/位置编码RoPE → BERT vs GPT → 预训练/指令微调 → 并行训练/FlashAttention → 量化/QLoRA

7.1 自注意力详细推导

Self-Attention Derivation · Q/K/V 到底从哪来

想四步推导

第一步:Q/K/V 怎么来?输入序列 X(n×dmodel),乘以三个可学习矩阵:

Q = XWQ,  K = XWK,  V = XWV

WQ, WK ∈ ℝdmodel×dk,WV ∈ ℝdmodel×dv。同一个输入 X,通过不同的线性变换,变成三种角色:Q 是"查询"(我要找什么),K 是"键"(我能匹配什么),V 是"值"(我实际带的信息)。

第二步:算相似度。每个 query 跟所有 key 做点积:scores = QKT(n×n 矩阵,scoresij = 第 i 个 query 与第 j 个 key 的相似度)。

第三步:为什么除以 √dk?假设 Q、K 的每个元素独立取自均值 0、方差 1 的分布。点积 q·k = ∑i=1..dk qiki,方差 = dk(独立变量乘积求和的方差相加)。维度越大,点积方差越大,softmax 输入会变得极端(一个值远大于其他),进入饱和区,梯度几乎为零。除以 √dk 把方差拉回 1,保持 softmax 分布平滑。

第四步:softmax 加权求和。

Attention(Q,K,V) = softmax(QKT / √dk) V

softmax 把每行变成概率分布(和为 1),再乘 V 就是"按关注程度加权的信息汇总"。

例:softmax 不缩放会怎样?
dk=512,点积方差 512,标准差 ≈22.6。两个点积 22.6 和 −22.6。
解:softmax([22.6, −22.6]) = [1/(1+e−45.2), e−45.2/(1+e−45.2)] ≈ [1, 0]。一个权重≈1,其他≈0,几乎不跟 V 混合,梯度≈0。除以 √512≈22.6 后变成 [1, −1],softmax ≈ [0.73, 0.27],分布健康。这就是 √dk 的全部意义。
记
小结

① Q/K/V = X 乘三个权重矩阵。② 点积测相似度。③ √dk 防方差爆炸。④ softmax 归一化后乘 V。

7.2 多头注意力与位置编码

Multi-Head Attention & Positional Encoding

想多头:并行看不同关系

单头注意力只能学一种关注模式。多头把 dmodel 切成 h 份(如 512/8=64),每头独立算 Attention,最后拼起来再乘 WO。有的头看语法,有的头看指代,有的头看位置邻近——多视角融合。

MultiHead(Q,K,V) = Concat(head₁,…,headh) WO,  headi = Attention(QWiQ, KWiK, VWiV)

位位置编码:注意力不认顺序

自注意力是"集合运算"——打乱词序结果一样。但语言有顺序!必须额外注入位置信息。

正弦位置编码(原版):用不同频率的 sin/cos 编码位置:

PE(pos, 2i) = sin(pos / 100002i/dmodel)
PE(pos, 2i+1) = cos(pos / 100002i/dmodel)

把 PE 直接加到词嵌入上。好处:能泛化到训练时没见过的长度。

可学习位置编码:直接把位置当参数学(BERT/GPT-2 用)。简单但不能外推到更长序列。

RoPE(旋转位置编码):把位置信息编码成旋转矩阵乘在 Q/K 上。LLaMA/Qwen 等现代大模型标配,通过旋转角度自然编码相对位置,支持长度外推。

记
小结

① 多头=多视角并行。② 位置编码补顺序,正弦可外推,可学习简单。③ RoPE 是现代大模型标配。

7.3 Encoder-Decoder 架构:BERT vs GPT vs T5

Encoder / Decoder / Encoder-Decoder · 三大派系

想三种掩码策略决定三种模型

① Encoder-only(BERT):双向注意力,每个词能看到左右所有词。预训练任务:掩码语言模型(MLM)——把句子里 15% 的词遮住,让模型猜。适合理解类任务:分类、实体识别、检索。

② Decoder-only(GPT/LLaMA):因果掩码(causal mask),每个词只能看到自己和左边的词。预训练任务:自回归语言模型——预测下一个词。适合生成类任务:聊天、写作、代码。这是当今大模型主流。

③ Encoder-Decoder(T5/BART):Encoder 双向看输入,Decoder 因果生成输出。预训练:把原文改成"伪句"再还原。适合翻译、摘要这种"输入→输出"任务。

表 7-1 三大派系对比
BERT(Encoder)GPT(Decoder)T5(Enc-Dec)
注意力双向因果(只看左)Encoder 双向,Decoder 因果
预训练任务掩码 MLM下一词预测文本到文本
擅长理解/分类/检索生成/对话翻译/摘要
记
小结

① 掩码策略决定模型性格。② BERT 懂、GPT 写、T5 翻译。③ 聊天用 GPT 系,搜索用 BERT 系。

7.4 大模型训练流程:预训练 → SFT → RLHF/DPO

LLM Training Pipeline · 千亿模型是怎么炼出来的

想三段式流水线

① 预训练(Pre-training):几万亿 token 自监督学下一词。成本几千万到几亿美元。产出一个"什么都知道但不会聊天"的基础模型(Base Model)。

② 监督微调 SFT:用几万~几十万条"指令-回答"对(人工标注),教会模型"听到指令要怎么回答"。从续写机器变成对话助手。这一步便宜,数据质量决定上限。

③ 对齐(Alignment):让回答符合人类偏好。两条路线:

RLHF:人对多个回答排序 → 训奖励模型 RM → 用 PPO 强化学习优化 LLM。复杂、贵、不稳定。

DPO(Direct Preference Optimization):跳过奖励模型和 RL,直接用偏好对(chosen/rejected)做二元交叉熵优化。简单稳定,是当今主流。

例:为什么预训练完还要 SFT?
Base 模型看到"写一首关于秋天的诗"。
解:Base 模型会续写:"写一首关于秋天的诗。秋天是收获的季节……春天播种……"——它把你当续写 prompt,而不是对话。SFT 教它:收到这种指令,直接输出诗,不要续写问题本身。对齐的本质是教"格式"和"风格",不是新知识。
记
小结

① 预训练学知识,SFT 学格式,DPO/RLHF 学偏好。② DPO 比 RLHF 简单稳定,主流。③ 数据质量 > 数据数量。

7.5 Scaling Law 与涌现能力

Scaling Laws · 模型越大越强是有数学规律的

想幂律缩放

OpenAI 2020 发现:测试损失 L 随参数量 N、数据量 D、计算量 C 呈幂律下降:

L(N) ≈ (Nc/N)αN,  αN ≈ 0.076

直觉:不是"大一点好一点"的线性关系,而是"翻 10 倍参数,损失降一点点"——但这一点点在长链推理上可能是质的飞跃。

涌现能力(Emergence):小模型完全不会的能力(如多步推理、代码生成),在模型规模跨过某个阈值后突然出现。这不是魔法,而是指标从"随机"跳到"可用"的临界点。

Chinchilla 定律:参数和数据要同步增长,约每翻 6 倍参数配 1 倍数据。早年 GPT-3 数据没喂够(参数浪费),Chinchilla 修正了这个配比。

记
小结

① 损失随规模幂律下降。② 涌现是跨过阈值的相变。③ 参数和数据要按比例同步增长。

7.6 上下文窗口、KV Cache 与长度外推

Context Window / KV Cache · 为什么能聊天但越来越慢

想KV Cache 是什么

自回归生成:每次生成一个新 token,都要把前面所有 token 重新过一遍注意力——这太浪费了,因为前面的 K、V 没变。

KV Cache:把历史 token 的 K、V 缓存起来。生成新 token 时,只需算新 token 的 Q,跟缓存的 K、V 算注意力。复杂度从 O(n²) 降到 O(n) 每步。这就是为什么生成长文本比短文本慢——缓存越来越大。

上下文窗口:模型一次能看的最大 token 数(如 4K/32K/128K/1M)。超出就忘。

长度外推:训练时只见过 4K,怎么用到 128K?方法:RoPE 插值(PI)、NTK-aware 插值、YaRN。本质是把位置编码的频率调低,让模型能"想象"更长的位置。

记
小结

① KV Cache 缓存历史 K/V,把 O(n²) 变 O(n)。② 上下文窗口是一次能记多长。③ RoPE 插值支持外推。

7.7 量化:INT8 / INT4 / QLoRA

Quantization · 把 16 位模型压成 4 位还能跑

想为什么要量化

原始模型权重是 FP16(16 位浮点)。7B 模型约 14GB 显存,普通人消费级显卡跑不动。量化:把权重从 16 位压到 8 位甚至 4 位整数,显存减半/减到四分之一。

INT8 量化:权重用 8 位整数表示,推理时反量化回浮点。精度损失很小(<1%),显存减半。

INT4 量化(GPTQ/AWQ):压到 4 位,7B 模型只要 ~4GB。精度有损失但可用。

QLoRA:量化 + 高效微调。把基座模型 4 位量化冻结,只训练很小的 LoRA 适配器(<1% 参数)。让 7B 模型在单张 24GB 显卡上就能微调——这是 2023 年个人玩大模型的转折点。

精度

FP16 > INT8 > INT4,损失递增。

显存

7B 模型:FP16=14GB,INT8=7GB,INT4=3.5~4GB。

记
小结

① 量化用整数近似浮点,省显存。② INT8 损失小,INT4 可跑消费卡。③ QLoRA=量化基座+小适配器,个人微调大模型的钥匙。

7.8 LoRA / QLoRA / PEFT:只学 1% 参数怎么微调大模型

LoRA / QLoRA / PEFT · 全量微调太贵,冻结基座学小补丁

想引子与大白话

引子:全量微调 7B 模型,连梯度带优化器状态要 60GB 显存。普通人 24GB 卡想微调?LoRA 说:基座冻结不动,只在旁边学一个小"补丁"。

① LoRA(Low-Rank Adaptation):冻结原始权重 W,在旁路加两个小矩阵 A(r×d)和 B(d×r),让更新 ΔW = B·A。r 通常取 8~64,参数量从 d² 降到 2dr——通常 <1% 原参数量。推理时可把 BA 合并回 W,零延迟。

Wnew = Wfrozen + B·A,  B∈ℝd×r, A∈ℝr×d,r ≪ d

② QLoRA:7.7 已说——把基座 4 位量化冻结,只训 LoRA。再加上双重量化和分页优化器,7B 模型单卡 24GB 微调可行。

③ PEFT 家族:Parameter-Efficient Fine-Tuning 的统称。除了 LoRA 还有:Prefix Tuning(在输入前加可学向量)、Prompt Tuning(只学 embedding)、Adapter(在层间插小瓶颈)。LoRA 是其中最通用、效果最好的。

④ 多任务 LoRA:一个基座挂多个 LoRA(一个写代码、一个写诗、一个客服),按场景切换。省得为每个任务存一个完整模型。

例:d=4096,r=16,LoRA 比全量微调省多少参数?
全量 ΔW 是 4096×4096。
解:全量一层 1677 万参数;LoRA 一层 4096×16 + 16×4096 ≈ 13.1 万,约为全量的 0.8%。几十层加起来总训练参数也就几个亿的零头。这就是为什么一张 24GB 卡能微调 7B——基座不动,只训这 1%。
什么时候用

显存有限、数据少、要一基座多任务→LoRA/QLoRA。有海量数据+多卡集群、追求极致效果→全量微调。

工程里

Hugging Face PEFT / LLaMA-Factory / unsloth 都是 LoRA 工具链。.safetensors 存几十 MB 的 LoRA 权重,随用随挂。

防坑

坑:r 设太大。r 大了逼近全量微调,省显存的意义就没了;r 太小学不动。一般 r=8~64 起步。另外 LoRA 要挂在正确的位置(通常 attention 的 q_proj/v_proj),挂错层效果暴跌。推理记得把 BA 合并回 W,否则每次多算两个矩阵乘。

练一练

基础LoRA 为什么用两个小矩阵相乘,而不是直接学一个 d×d 的 ΔW?

看答案直接学 d×d 就是全量微调。拆成 d×r 乘 r×d(秩 r 远小于 d),参数量从 d² 压到 2dr,用低秩假设省参数——微调更新本来就处在低秩子空间。

进阶QLoRA 和 LoRA 的区别在哪?

看答案LoRA 基座是 FP16 可训练也可冻结;QLoRA 把基座量化成 4 位整数冻结,只训 LoRA。QLoRA 在 LoRA 基础上再省一半多显存,是个人微调 7B 的标配。

自评反馈:答对了继续;低秩分解为什么省参数,回看这一节。

记
小结

① LoRA=冻结基座+学低秩补丁 BA,<1% 参数。② QLoRA=4 位量化基座+LoRA,单卡微调。③ PEFT 是家族,LoRA 最通用。④ 一基座多 LoRA 切换。

7.9 提示工程:Few-shot / CoT / ReAct

Prompt Engineering · 不更新参数,只改输入就提分

想引子与大白话

引子:同一个模型,提问方式不同,回答质量天差地别。提示工程就是不花一分钱训练,只靠怎么写 prompt 把模型榨出更多性能——这是用大模型最便宜的优化。

① Zero-shot:直接问,"把这句翻译成英文"。模型靠预训练见过的任务直接答。

② Few-shot:在 prompt 里给几个示例("苹果→apple,香蕉→banana,葡萄→?"),模型照着模式做。示例怎么排、给几个,都影响效果。

③ Chain-of-Thought(CoT,思维链):让模型"一步步想"。提示词加一句"Let's think step by step",多步推理题准确率暴涨。因为模型把中间步骤也写出来,等于给自己搭了脚手架。

④ ReAct:8.2 讲过——CoT 只在脑子里想,ReAct 边想边调工具。CoT 适合纯推理,ReAct 需要查外部信息。

⑤ 自洽性(Self-Consistency):让模型用不同推理路径答同一题多次,取多数票。比单次 CoT 更稳。

例:"一个班 30 人,男生比女生多 6 人,女生几人?" 直接答 vs CoT
直接问模型容易口算错。
解:直接答可能瞎蒙 12。CoT:"设女生 x 人,男生 x+6,x+(x+6)=30,2x=24,x=12。"逼它写出方程,中间步骤就暴露了推导,最后答 12。多步推理题一定要 CoT。
实战技巧

给角色("你是资深律师")、给格式("用 JSON 输出")、给约束("不超过 100 字")、给示例。复杂任务拆成多步 prompt。

边界

提示工程是免费午餐,但天花板低于微调。能靠 prompt 解决的别微调;prompt 调到极限还不行,再上 SFT/LoRA。

记
小结

① Few-shot 给示例,CoT 逼它一步步想。② ReAct 边想边查工具。③ 提示工程零成本提分,但别代替微调。

费曼学习法:讲给别人听

① 用自己的话解释:不看公式,口头推一遍 softmax(QKᵀ/√dk)V 每步在干嘛。

② 举个反例 / 生活例子:反例——为什么要除 √dk?不除会发生什么?

③ 哪里还说不清:BERT(双向)和 GPT(自回归)一个看两边一个只看左边,为什么训练目标因此完全不同?