LLM WIKI · 课程精读

LEARNING UNIT · 19

SFT、LoRA 与知识蒸馏

比较合成思维链、低秩旁路、初始化、梯度差异与教师学生迁移。

已整理章节
8 节
单元来源
7 条视频
总时长
17:54
状态
已发布
学习位置
19 / 20
01

主题讲解 · 03:24

预训练与 SFT 的输出梯度究竟差在哪里

学习目标

  • 从 next-token prediction 写出序列 logits 与标签的 shape。
  • 推出单位置 softmax 交叉熵对 logits 的梯度 pyp-y
  • 比较预训练与 response-only SFT 的有效监督位置。
  • 区分“提示位置 logits 的直接梯度为零”和“提示不会影响参数梯度”。
  • 识别 padding、特殊 token 与不同数据整理策略带来的实现边界。

前置与衔接

本课假设自回归 causal language model。

输入是一段长度为 TT 的 token 序列,词表大小为 VV

模型在每个位置输出一个 VV 维 logits 向量。

视频讨论的是训练刚开始时输出层梯度的结构差异, 不是说预训练和 SFT 使用不同的交叉熵公式。

图 1

自回归语言模型把整段序列映射为逐位置 logits,每一行都对应对下一个 token 的词表分布。

原视频 · 00:20 ↗

先固定记号:

ZRT×V,P=softmax(Z).Z\in\mathbb{R}^{T\times V},\qquad P=\operatorname{softmax}(Z).

Zi,:Z_{i,:} 是位置 ii 的 logits,Pi,:P_{i,:} 是相应词表概率。

核心讲解

1. 标签必须与输入错开一位

causal LM 在位置 ii 预测下一个 token,而不是复原当前位置 token。

若原序列是

(x1,x2,,xT),(x_1,x_2,\ldots,x_T),

那么用于预测的配对可写成

(x1x2),(x2x3),,(xT1xT).(x_1\rightarrow x_2), (x_2\rightarrow x_3),\ldots, (x_{T-1}\rightarrow x_T).
图 2

训练标签相对输入左移一位:位置 i 的输出负责预测原序列中的下一个 token。

原视频 · 01:00 ↗

因此一段 TT 个 token 的样本通常只有 T1T-1 个 next-token 监督位置。

实现还可能追加 EOS,或把 BOS 计入输入; 应以实际 input_idslabels 与 ignore mask 为准。

2. 单位置交叉熵为何给出 p−y

对一个有效位置,设 one-hot 标签为 yy,预测概率为 pp

交叉熵是

=v=1Vyvlogpv.\ell=-\sum_{v=1}^{V}y_v\log p_v.

softmax 与交叉熵合并求导得到

zv=pvyv.\frac{\partial \ell}{\partial z_v}=p_v-y_v.
图 3

单个位置的 softmax 交叉熵以 one-hot 标签监督词表 logits,其梯度为预测概率减去标签。

原视频 · 01:40 ↗

正确类别处的梯度是 pgold1p_{gold}-1, 其他类别处是 pvp_v

这说明每个有效位置都产生一个 VV 维梯度向量。

3. 序列损失只是把有效位置聚合起来

令有效监督位置集合为 M\mathcal{M},数量为 MM

采用 mean reduction 时

L=1MiMi.L=\frac{1}{M}\sum_{i\in\mathcal{M}}\ell_i.

因此

LZi,:={Pi,:Yi,:M,iM,0,iM.\frac{\partial L}{\partial Z_{i,:}}= \begin{cases} \dfrac{P_{i,:}-Y_{i,:}}{M}, & i\in\mathcal{M},\\ 0, & i\notin\mathcal{M}. \end{cases}
图 4

把单位置的 p−y 沿序列堆叠,就得到输出 logits 矩阵的逐行梯度。

原视频 · 02:20 ↗

所以真正决定差异的是集合 M\mathcal{M}, 以及 reduction 的分母,不是另换了一套导数。

4. 预训练通常监督所有有效 next-token 位置

语言模型预训练希望学习整段语料的下一个 token 分布。

在理想化的无 padding 序列中, M\mathcal{M} 包含全部可预测位置。

图 5

预训练通常在所有有效的 next-token 位置计算损失,因此这些输出行都获得直接监督梯度。

原视频 · 02:40 ↗

因此 logits 梯度矩阵的每个有效行都形如

(Pi,:Yi,:)/M.(P_{i,:}-Y_{i,:})/M.

这里的“全部”不应机械理解为张量中的每一行。

padding、某些特殊 token、跨文档边界位置都可能被实现掩掉。

5. response-only SFT 只监督回答区间

一条对话样本通常由 prompt 和 response 拼接而成。

若训练目标只学习回答,prompt 对应 label 会被设为 ignore index。

图 6

响应式 SFT 只在回答位置计损失:提示位置的 logits 直接梯度为零,回答位置仍是 p−y 的平均。

原视频 · 03:00 ↗

此时 M\mathcal{M} 只包含 response 的 next-token 位置。

prompt 位置输出 logits 的直接梯度为零, response 位置仍是同一个 pyp-y 形式。

mean reduction 的分母也应是有效 response token 数, 而不是整个拼接序列长度。

6. “prompt 梯度为零”只限于哪一层

必须把以下两个命题分开:

  1. prompt 位置 logits 的直接 loss 梯度为零;
  2. prompt token 对共享参数的总梯度贡献为零。

第一个命题在 response-only mask 下成立。

第二个命题通常不成立。

回答位置的隐藏状态可以通过 causal attention 读取 prompt 的 K、V。

回答位置的损失因此会沿 attention 路径反传到 prompt 相关的中间表示, 并继续更新共享的 embedding、attention、FFN 等参数。

换句话说,prompt 没有被要求“在自己的位置预测下一个 token”, 但它仍然作为条件上下文影响回答预测。

7. 实现与版本边界

视频使用“预训练监督全部、SFT 只监督回答”的典型对比。

现实中还存在:

  • 对 prompt 也计算损失的 completion LM 数据整理方式。
  • 只掩 system/user,保留 assistant 多轮回答的 chat template。
  • packing 后对样本边界、padding 与 EOS 的额外 mask。
  • sum、固定 token 数归一化或跨设备 token-level mean。

这些实现会改变 M\mathcal{M} 或缩放系数, 但单个有效位置的基本梯度仍是 pyp-y

跟练与练习

原视频跟练

编者练习

一条拼接序列有 9 个可预测位置,其中 4 个属于 prompt、5 个属于 response。 采用 response-only mean loss 时,写出 prompt 行与 response 行的 logits 梯度。

查看参考答案

有效集合只有 5 个 response 位置。
prompt 行的直接梯度为零;
每个 response 行的梯度为
Pi,:Yi,:5.\frac{P_{i,:}-Y_{i,:}}{5}.
这并不推出 prompt 中间表示或共享参数没有梯度,
因为 response 计算依赖 prompt 上下文。

常见误区

  • 把同位置 token 当成 causal LM 的监督标签,忽略一位 shift。
  • 认为 SFT 换了一种交叉熵;其实主要差异是 loss mask。
  • 把 prompt logits 的零梯度误解为 prompt 完全不参与反向传播。
  • 用总序列长度而非有效 label 数解释 mean reduction。
  • 说预训练“每个位置都有梯度”却忽略 padding 和特殊 token mask。
  • 把输出层初始梯度差异直接等同于所有参数梯度的逐元素差异。

本课小结

  • 单个有效位置的 logits 梯度是 pyp-y
  • 序列训练通过有效位置集合 M\mathcal{M} 聚合这些梯度。
  • 预训练通常覆盖全部有效 next-token 位置。
  • response-only SFT 只覆盖回答位置。
  • prompt 位置 logits 可无直接损失,但 prompt 仍能通过回答条件路径影响共享参数。
  • 精确判断必须查看真实 labels、ignore mask 与 reduction。
02

主题讲解 · 01:55

从专家答案反推训练用推理过程

学习目标

  • 识别“有问题和专家答案、没有解释过程”的监督缺口。
  • 说明强 teacher 如何以文档与答案为条件生成合成理由。
  • 区分合成推理 SFT 与 logit-level knowledge distillation。
  • 划清 teacher、student、专家答案与执行反馈的职责。
  • 理解合成理由需要独立核验,不能因语言流畅就当作真实因果链。

前置与衔接

本课围绕 kernel 生成举例。

已有资源包括硬件技术文档与专家编写的 kernel 代码。

专家代码可以视为目标答案, 但它并不会自动告诉 student 为什么选择某种 tile、访存或并行策略。

图 1

案例拥有硬件技术文档和专家 kernel 代码答案,却缺少可直接用于监督的解题理由。

原视频 · 00:00 ↗

视频画面提到 AscendKernelGen, 并口述一个更早的相似思路来源。

本课只采用画面可证实的流程, 不把项目归属、年份或首创关系扩写为已独立核验的历史事实。

核心讲解

1. 答案监督缺少了什么

若数据只有

(q,a),(q,a),

其中 qq 是问题、aa 是专家 kernel, student 可以学习从题目到答案的 token 映射。

但当答案依赖硬件约束与多步设计选择时, 直接映射可能难学,也缺少可检查的中间依据。

图 2

仅凭题目很难直接解释专家为何选择某种 tile 或访存方案,答案并不自动等于推理监督。

原视频 · 00:20 ↗

这里缺少的是一段训练用 rationale:

r=解释文档约束如何支持答案 a 的文本.r=\text{解释文档约束如何支持答案 }a\text{ 的文本}.

它是后来合成的监督对象, 不等于从专家脑中真实记录下来的原始思考过程。

2. 先固定 student 的最终任务

student 的目标仍是根据问题生成可用 kernel。

图 3

目标任务是让待训练模型从问题生成 kernel;监督数据需要把题目与可核验的求解过程、答案对齐。

原视频 · 00:40 ↗

为了给它更密集的训练信号, 可以把目标序列组织为

y=[r;a],y=[r;a],

即先输出理由,再输出答案。

训练样本成为

(q,[r;a]).(q,[r;a]).

这里的分号表示拼接, 具体 chat template、分隔 token 与 loss mask 由实现决定。

3. teacher 不是只看问题自由发挥

强 teacher 同时获得:

  • 问题 qq
  • 硬件技术文档 dd
  • 已知专家答案 aa

然后生成

rpteacher(rq,d,a).r\sim p_{teacher}(r\mid q,d,a).
图 4

更强的 teacher 同时参考技术文档与专家答案,生成解释该答案的合成推理文本。

原视频 · 01:00 ↗

给定答案很关键:

teacher 的任务是为一个已知可取答案构造依据, 不是独立求解后再碰巧得到相同代码。

这也带来“事后合理化”风险:

teacher 可能写出语言上连贯、实际上并未决定该答案的理由。

4. 数据装配与 student SFT

得到合成理由后, 将问题、理由与答案装配成监督样本。

图 5

将问题、合成理由和专家答案组织成监督样本,再对较小的 student 做 SFT。

原视频 · 01:20 ↗

若 prompt 只含问题,response 为理由加答案, 常见 response-only SFT 损失是

LSFT=tresponselogpstudent(ytq,y<t).L_{SFT}=-\sum_{t\in response} \log p_{student}(y_t\mid q,y_{<t}).

student 学的是 teacher 生成的离散文本 token 与专家答案 token。

这属于 synthetic-data SFT, 不是直接拟合 teacher logits 的经典 knowledge distillation。

5. teacher/student 边界必须明确

teacher 的职责是生成候选理由。

student 的职责是通过 SFT 学习给定目标序列。

专家答案提供最终代码目标, 技术文档提供可引用的硬件事实。

这四者不能互相替代:

  • teacher 更强,不代表其理由自动真实。
  • 专家代码正确,不代表每段合成解释都正确。
  • student 复现理由,不代表已经通过执行测试。
  • 文档事实正确,不代表具体优化选择在所有输入上最优。

6. 执行反馈属于后续阶段

视频最后提出运行生成的 kernel, 观察正确性与性能反馈,再继续优化。

图 6

student 学习生成理由与答案,后续还可运行 kernel,用正确性和性能反馈继续优化。

原视频 · 01:40 ↗

这一步和前面的离线 SFT 应分阶段描述:

  1. teacher 生成理由;
  2. 筛选并装配 SFT 数据;
  3. student 做 next-token 训练;
  4. 运行 student 生成的 kernel;
  5. 用测试反馈筛选数据或进入后续优化。

执行成功能验证最终代码在测试条件下可用, 却不会逆向证明合成理由就是唯一或真实的因果解释。

7. 视频外补充:如何降低合成理由风险

以下是编者补充,不是视频逐句结论。

可对合成理由设置三类门槛:

  • 文档一致性:每个硬件约束能在给定文档中定位。
  • 代码一致性:理由提到的 tile、内存层级、并行策略与答案代码相符。
  • 执行一致性:代码通过正确性测试,并在目标硬件上测量性能。

还可以让另一模型或规则检查器专门寻找理由与代码的矛盾, 但自动评审也不能代替关键样本的人审与真实执行。

跟练与练习

原视频跟练

编者练习

有一段专家 kernel 通过了测试, teacher 声称“因为共享内存容量为 128 KB,所以选择该 tile”。 要接受这条理由,至少还应检查什么?

查看参考答案

至少检查:
• 目标硬件与配置下的共享内存容量是否确为 128 KB;
• 该 kernel 的实际 tile 与共享内存占用是否符合理由;
• 线程块、双缓冲等额外占用是否已计入;
• 代码是否在目标输入与硬件上通过正确性测试;
• 若声称性能更优,还要和明确基线做实测。
测试通过只能支持代码可用,
不能单独证明这段自然语言就是设计选择的真实来源。

常见误区

  • 把专家答案当作天然包含完整推理过程。
  • 把 teacher 的流畅解释当作已验证事实。
  • 把离散文本 SFT 称为直接匹配 teacher logits 的蒸馏。
  • 认为给 teacher 看答案后生成的理由一定是忠实因果链。
  • 用最终代码执行成功替代对每条理由的文档与代码核对。
  • 把视频画面中的项目名、年份或来源扩写为已证实的首创结论。

本课小结

  • 问题与专家答案之间可能缺少可用于监督的解释过程。
  • 强 teacher 可在问题、文档与答案条件下合成 rationale。
  • student 再对问题、理由、答案组成的离散序列做 SFT。
  • 这不是纯粹的 teacher-logit distillation。
  • 合成理由可能事后合理化,必须对文档、代码与执行结果分别核验。
  • SFT 与后续执行反馈是相连但不同的训练阶段。
03

主题讲解 · 03:46

从向量外积看懂 LoRA 的低秩旁路

学习目标

  • 区分 Hadamard 积、内积、外积与三维叉积。
  • 用 shape ledger 写清 LoRA 旁路的每次矩阵乘法。
  • 解释秩一 LoRA 更新为何恰好是两个向量的外积。
  • 把一般秩 RR 的更新展开成 RR 个秩一矩阵之和。
  • 对齐板书右乘约定与 PyTorch 常见权重存储约定。

前置与衔接

本课讨论一个无偏置的线性层。

视频采用“样本在行上”的右乘记法:

XRN×D,WRD×K,Y=XW.X\in\mathbb{R}^{N\times D},\qquad W\in\mathbb{R}^{D\times K},\qquad Y=XW.

NN 是 token 或样本数,DD 是输入维,KK 是输出维。

先固定这个约定, 再讨论不同库中转置后的写法。

核心讲解

1. 四种“向量乘法”不要混用

给定两个同维向量 a,bRda,b\in\mathbb{R}^{d}

  • Hadamard 积 aba\odot b 逐元素相乘,输出仍是 dd 维向量。
  • 内积 aTba^Tb 对逐元素乘积求和,输出标量。
  • 外积 abTab^T 让每个 aia_i 与每个 bjb_j 配对,输出矩阵。
  • 叉积 a×ba\times b 通常指三维中的几何运算,输出三维向量。
图 1

列向量与行向量的外积生成矩阵;它和内积、Hadamard 积、叉积是不同运算。

原视频 · 00:40 ↗

例如

[12][34]=[3468].\begin{bmatrix}1\\2\end{bmatrix} \begin{bmatrix}3&4\end{bmatrix} = \begin{bmatrix}3&4\\6&8\end{bmatrix}.

外积矩阵的第 (i,j)(i,j) 个元素是 aibja_i b_j

2. LoRA 把大更新拆成两个小矩阵

全量微调直接学习与 WW 同形的更新 ΔW\Delta W

LoRA 改为参数化

ΔW=AB,\Delta W=AB,

其中

ARD×R,BRR×K,Rmin(D,K).A\in\mathbb{R}^{D\times R},\qquad B\in\mathbb{R}^{R\times K},\qquad R\ll\min(D,K).

训练时冻结 WW,只更新 AABB

图 2

LoRA 冻结基座权重 W,只训练低秩旁路 A、B,并把 XAB 加到原输出 XW。

原视频 · 01:20 ↗

前向为

Y=XW+XAB.Y=XW+XAB.

参数量从 DKDK 降为 R(D+K)R(D+K)

这只是可训练矩阵参数量比较, 不是说运行时显存与计算量必然按同一比例下降。

3. 用 shape ledger 排除错误顺序

完整链条是

XN×DAD×R(XA)N×R,X_{N\times D}A_{D\times R} \rightarrow (XA)_{N\times R},

再乘

(XA)N×RBR×K(XAB)N×K.(XA)_{N\times R}B_{R\times K} \rightarrow (XAB)_{N\times K}.

它与

XWRN×KXW\in\mathbb{R}^{N\times K}

同形,因此可以相加。

图 3

按右乘约定,X∈R^{N×D}、W∈R^{D×K}、A∈R^{D×R}、B∈R^{R×K},所以 AB 与 W 同形。

原视频 · 02:00 ↗

若只记“A、B 是两个小矩阵”而不写轴, 很容易把 ABABBABA 与转置混为一谈。

4. 为什么训练旁路可以合并

矩阵乘法对加法满足分配律:

XW+XAB=X(W+AB).XW+XAB=X(W+AB).

因此可定义

W=W+AB.W'=W+AB.
图 4

分配律给出 XW+XAB=X(W+AB),因此低秩更新可以在部署前合并进主权重。

原视频 · 02:20 ↗

合并后线性层仍然只有一个 D×KD\times K 权重, 输入输出 shape 与基座层一致。

“结构一致”不表示参数值没变; 任务适配信息已经写进 WW'

5. 初始旁路为何通常设为零输出

视频采用

A 随机初始化,B=0.A\ \text{随机初始化},\qquad B=0.

于是

AB=0,qquadY=XW.AB=0,qquad Y=XW.
图 5

视频采用 A 随机、B 全零,使初始 AB=0,从而旁路初始不改变基座层输出。

原视频 · 02:40 ↗

这样训练起点保持基座层原有函数。

同时 AA 非零使 BB 的首步梯度通常可用, 不会像两个因子都置零那样形成梯度死锁。

具体梯度将在本单元后续课程中展开。

6. 秩一时就是外积

R=1R=1 时,

ARD×1,BR1×K.A\in\mathbb{R}^{D\times 1},\qquad B\in\mathbb{R}^{1\times K}.

AA 是列向量,BB 是行向量, 所以 ABAB 正是一个 D×KD\times K 外积矩阵。

图 6

当秩 R=1 时,A 是列向量、B 是行向量,AB 正是外积;一般 R 则是 R 个秩一外积之和。

原视频 · 03:20 ↗

一般 RR 下,写出 AA 的列与 BB 的行:

A=[a1,,aR],A=[a_1,\ldots,a_R],
B=[b1TbRT].B= \begin{bmatrix} b_1^T\\ \vdots\\ b_R^T \end{bmatrix}.

AB=r=1RarbrT.AB=\sum_{r=1}^{R}a_r b_r^T.

因此“一般 LoRA 像外积”更准确的说法是: 它把更新写成有限个秩一外积之和。

7. 实现约定与视频外补充

板书使用 XWXWABAB 的右乘约定。

PyTorch nn.Linear 常把参数存为

WstoreRK×DW_{store}\in\mathbb{R}^{K\times D}

并计算 XWstoreTXW_{store}^T

相应 LoRA 文档常写

ΔWstore=BA,\Delta W_{store}=BA,

其中 ARR×DA\in\mathbb{R}^{R\times D}BRK×RB\in\mathbb{R}^{K\times R}

这与板书在转置一致时表达同一低秩更新, 不能脱离 shape 只比较字母顺序。

此外,常见实现还使用缩放

s=αR,Y=XW+sXAB.s=\frac{\alpha}{R},\qquad Y=XW+sXAB.

视频为解释外积省略了该项。

它是实现配置与优化尺度, 不能默认所有 LoRA 都有 s=1s=1

跟练与练习

原视频跟练

编者练习

D=6D=6K=4K=4R=2R=2, 写出 AABBABAB 的 shape,并把 ABAB 写成外积之和。

查看参考答案

AR6×2,BR2×4,ABR6×4.A\in\mathbb{R}^{6\times2},\qquad B\in\mathbb{R}^{2\times4},\qquad AB\in\mathbb{R}^{6\times4}.
A=[a1,a2]A=[a_1,a_2]
B=[b1T;b2T]B=[b_1^T;b_2^T],则
AB=a1b1T+a2b2T.AB=a_1b_1^T+a_2b_2^T.
每一项都是一个 6×46\times4 的秩至多为一的外积矩阵。

常见误区

  • 把外积误写成逐元素积或内积。
  • 只背 ABAB,却不检查 DRKD、R、K 三个轴。
  • 认为一般 rank-RR 更新就是单个外积;它是至多 RR 个外积之和。
  • 忽略 nn.Linear.weight 的存储转置,机械复制板书字母顺序。
  • 把结构可合并误解为权重没有变化。
  • 默认视频省略的 α/R\alpha/R 缩放在所有实现中都等于一。

本课小结

  • 外积把列向量与行向量组合成矩阵。
  • LoRA 用 ARD×RA\in\mathbb{R}^{D\times R}BRR×KB\in\mathbb{R}^{R\times K} 参数化更新。
  • ABABWW 同形,因此 XW+XABXW+XAB 可以合并。
  • rank 1 时 ABAB 就是外积。
  • 一般 rank RRABABRR 个秩一外积之和。
  • 迁移到具体库时必须同时核对 shape、转置、因子命名与缩放。
04

主题讲解 · 02:16

LoRA 旁路为何能在部署前合并回主权重

学习目标

  • 比较全量微调与 LoRA 对主权重的更新方式。
  • 用矩阵 shape 证明低秩旁路输出能与主分支相加。
  • 解释 LoRA 为何只在训练阶段需要显式旁路。
  • 区分 adapter checkpoint、未合并加载与 merged model。
  • 识别缩放、量化与浮点精度对“等价合并”的边界。

前置与衔接

沿用右乘记法:

XRN×D,WRD×K.X\in\mathbb{R}^{N\times D},\qquad W\in\mathbb{R}^{D\times K}.

基础线性层为

Y=XW.Y=XW.

本课中的“结构不变”特指: LoRA 合并后可以恢复为一个同输入输出 shape 的普通线性层。

它不表示训练期间从未添加模块, 也不表示微调后的权重数值与基座权重相同。

核心讲解

1. 全量微调直接更新主权重

全量微调让 WW 参与优化,得到

W=update(W).W'=\operatorname{update}(W).

推理时仍计算

Y=XW.Y=XW'.
图 1

全量微调直接把 W∈R^{D×K} 更新为 W′,输入输出 shape 不变但主权重数值改变。

原视频 · 00:20 ↗

WW'WW shape 相同, 所以层的接口不变,但全部 DKDK 个权重都可能改变。

2. 先声明矩阵约定

板书采用论文式右乘 XWXW

图 2

板书用行向量右乘 XW;常见线性层库可能存储转置后的权重,含义相同但矩阵书写方向不同。

原视频 · 00:40 ↗

PyTorch nn.Linear 通常存储 [K,D][K,D]weight, 前向相当于 XWstoreTXW_{store}^{T}

所以具体库里的因子 shape、A/B 名称与乘法顺序可能转置或互换。

本课所有推导都以板书右乘记法为准, 迁移到代码时必须重新核对实际参数 shape。

3. LoRA 在训练期注入同形更新

LoRA 冻结 WW,引入

ARD×R,BRR×K.A\in\mathbb{R}^{D\times R},\qquad B\in\mathbb{R}^{R\times K}.

定义

ΔW=ABRD×K.\Delta W=AB\in\mathbb{R}^{D\times K}.
图 3

A∈R^{D×R} 与 B∈R^{R×K} 相乘得到 ΔW∈R^{D×K},正好与 W 同形。

原视频 · 01:00 ↗

因为 ΔW\Delta WWW 同形, 训练前向可以写成

Y=XW+XΔW.Y=XW+X\Delta W.

若实现含缩放 s=α/Rs=\alpha/R,则实际更新是

ΔWeff=sAB.\Delta W_{eff}=sAB.

4. 旁路是微调时注入的

预训练完成的基座模型原本只有主权重 WW

LoRA 微调时才为目标层插入低秩分支, 冻结 WW 并训练 ABA、B

图 4

预训练模型原本只有 W,LoRA 微调阶段才注入并训练低秩 A、B,基座 W 保持冻结。

原视频 · 01:20 ↗

训练结构包含两条路径:

XWX\rightarrow W

XAB.X\rightarrow A\rightarrow B.

两条路径的输出相加。

因此“微调前后模型结构可以不变”不能描述训练瞬间; 训练期确实增加了旁路。

5. 为什么常保存 A、B 而非完整模型

RD,KR\ll D,K 时,

R(D+K)DK.R(D+K)\ll DK.

所以常见 adapter checkpoint 保存:

  • ABA、B 的参数;
  • rank、alpha、target modules 等配置;
  • 必要时额外可训练模块。
图 5

常见做法保存低秩因子与配置,而不必保存完整 ΔW;这样便于小体积发布和切换任务。

原视频 · 01:40 ↗

这样同一个基座模型可以搭配多个任务适配器。

不过“只保存 A、B”不是不可违背的定律。

工具也可能导出 ΔW\Delta W、完整 merged model, 或连同 bias、embedding 等额外参数一起保存。

6. 合并恢复单路径线性层

由分配律

XW+XΔW=X(W+ΔW).XW+X\Delta W=X(W+\Delta W).

定义

W=W+ΔWW'=W+\Delta W

后,推理只需计算

Y=XW.Y=XW'.
图 6

上线前可令 W′=W+ΔW 并移除旁路,部署层恢复为单个同 shape 的线性权重。

原视频 · 02:00 ↗

显式 A/B 旁路可以移除, 层又回到一个普通的 D×KD\times K 权重。

这就是合并后“结构恢复”的代数依据。

7. 合并不是唯一部署方式

保留未合并 adapter 也很常见,尤其用于:

  • 在同一基座上快速切换多个任务。
  • 动态组合或加权多个 adapter。
  • 只分发小型 adapter checkpoint。

代价是推理时仍需额外旁路计算, 并管理基座与 adapter 的版本匹配。

merged model 则适合固定任务、希望减少额外分支的部署。

选择哪种形式是工程决策, 不是 LoRA 数学要求必须合并。

8. 量化与数值精度边界

在理想实数运算下, XW+XΔWXW+X\Delta WX(W+ΔW)X(W+\Delta W) 完全相等。

实际浮点计算会因运算顺序与舍入产生微小差别。

若基座权重处于低比特量化格式, 合并通常还涉及:

  1. 将权重还原到可计算精度;
  2. 加入 sABsAB
  3. 按目标格式重新量化。

重新量化可能引入额外误差。

因此对 QLoRA 或其他量化适配器, 不能只凭代数式宣称 bitwise 完全一致。

跟练与练习

原视频跟练

编者练习

某 LoRA 层使用缩放 s=α/Rs=\alpha/R。 写出正确的合并公式,并说明少乘 ss 会发生什么。

查看参考答案

正确公式是
W=W+sAB=W+αRAB.W'=W+sAB=W+\frac{\alpha}{R}AB.
若错误地合并为 W+ABW+AB
适配更新的幅度会相差一个缩放因子,
因此不再与训练时未合并前向等价。
具体误差方向取决于 ss 大于还是小于 1。

常见误区

  • 说 LoRA 从头到尾都不改变模型结构;训练期明确注入了旁路。
  • 把“输入输出 shape 不变”理解成“权重数值不变”。
  • 忘记缩放 α/R\alpha/R,合并出错误权重。
  • 认为 LoRA checkpoint 永远只包含 A、B 两个张量。
  • 认为 LoRA 必须合并后才能部署。
  • 对量化基座宣称合并前后必然 bitwise 完全一致。

本课小结

  • 全量微调直接更新 WW,LoRA 则学习低秩 ΔW\Delta W
  • ABABWW 同形,所以旁路输出能与主分支相加。
  • LoRA 旁路只在微调时注入,基座权重保持冻结。
  • 常见 checkpoint 保存小型 adapter 与配置。
  • W=W+sABW'=W+sAB 可把训练旁路合并回单一线性层。
  • 未合并部署、缩放、量化与浮点舍入都是需要显式说明的实现边界。
05

主题讲解 · 03:19

LoRA 为什么不能把两个低秩因子同时置零

学习目标

  • 在固定矩阵约定下推导 LoRA 两个因子的梯度。
  • 用 shape 检查 L/A\partial L/\partial AL/B\partial L/\partial B
  • 解释双零初始化为何造成梯度死锁。
  • 解释双随机初始化为何会扰动预训练函数。
  • 理解“一零一非零”如何兼顾零初始更新与可启动梯度。
  • 识别不同实现交换因子命名和零初始化方向的边界。

前置与衔接

本课沿用视频的右乘约定:

XRN×D,WRD×K,X\in\mathbb{R}^{N\times D}, \quad W\in\mathbb{R}^{D\times K},
ARD×R,BRR×K.A\in\mathbb{R}^{D\times R}, \quad B\in\mathbb{R}^{R\times K}.

LoRA 前向写成

Y=X(W+AB)=XW+XAB.Y=X(W+AB)=XW+XAB.
图 1

按本视频右乘约定,LoRA 层写作 Y=X(W+AB),其中 W 冻结、A 与 B 可训练。

原视频 · 00:20 ↗

WW 冻结,只有 ABA、B 参与优化。

若实现带缩放 s=α/Rs=\alpha/R, 可把以下 XABXAB 替换为 sXABsXAB; 它不改变零或非零的逻辑,只缩放相应梯度。

核心讲解

1. 先从标量乘积建立直觉

y=abcd.y=abcd.

bb 求导时,

Lb=aLycd.\frac{\partial L}{\partial b} =a\frac{\partial L}{\partial y}cd.
图 2

标量乘积的链式法则提示:对某个因子求导时,梯度会乘上其余因子。

原视频 · 01:00 ↗

如果参与乘积的另一个因子为零, 梯度路径就可能被乘成零。

矩阵乘法也遵循相同的乘积法则, 只是必须同时处理转置与 shape。

2. 忽略冻结主分支,聚焦 XAB

令上游梯度为

G=LYRN×K.G=\frac{\partial L}{\partial Y} \in\mathbb{R}^{N\times K}.

因为 WW 不更新, 初始化问题的关键是低秩分支

Ylora=XAB.Y_{lora}=XAB.

可以先设

H=XARN×R,H=XA\in\mathbb{R}^{N\times R},

再写

Ylora=HB.Y_{lora}=HB.

3. 推导 B 的梯度

对线性层 Ylora=HBY_{lora}=HB, 权重梯度为输入转置乘上游梯度:

LB=HTG.\frac{\partial L}{\partial B}=H^TG.

代回 H=XAH=XA

LB=(XA)TG=ATXTG.\frac{\partial L}{\partial B} =(XA)^TG =A^TX^TG.

shape 检查:

(R×D)(D×N)(N×K)=R×K,(R\times D)(D\times N)(N\times K) =R\times K,

BB 完全一致。

4. 推导 A 的梯度

先从 Ylora=HBY_{lora}=HB 返回 HH

LH=GBT.\frac{\partial L}{\partial H}=GB^T.

再从 H=XAH=XA 返回 AA

LA=XTLH=XTGBT.\frac{\partial L}{\partial A} =X^T\frac{\partial L}{\partial H} =X^TGB^T.

shape 检查:

(D×N)(N×K)(K×R)=D×R,(D\times N)(N\times K)(K\times R) =D\times R,

AA 完全一致。

图 3

令 G=∂L/∂Y,则 ∂L/∂A=XᵀGBᵀ,∂L/∂B=(XA)ᵀG,shape 分别与 A、B 对齐。

原视频 · 01:40 ↗

两条公式共同揭示:

AA 的梯度显式乘 BBBB 的梯度显式乘 AA

5. A、B 同时全零会发生什么

A=0,B=0,A=0,\qquad B=0,

那么初始更新确实为

AB=0.AB=0.

但同时

LA=XTG0T=0,\frac{\partial L}{\partial A}=X^TG0^T=0,
LB=0TXTG=0.\frac{\partial L}{\partial B}=0^TX^TG=0.
图 4

若 A=B=0,则 AB=0 且两个因子的梯度也同时为零,优化第一步就无法启动。

原视频 · 02:20 ↗

优化器第一步无法更新任一因子, 下一步仍然保持全零,形成固定点。

只要没有其他打破对称或额外梯度的机制, 这个 LoRA 分支就永远学不起来。

6. A、B 同时随机会发生什么

若两个因子都从连续随机分布初始化, 一般有

AB0.AB\ne 0.

于是训练开始前

Y=XW+XABY=XW+XAB

已经不同于基座输出 XWXW

图 5

若 A、B 都随机,则初始 AB 通常非零,会立即扰动预训练层的输出;影响大小还取决于初始化尺度。

原视频 · 02:40 ↗

视频用“表现差、胡言乱语”强调风险。

更严谨地说,输出扰动大小取决于:

  • A、B 的初始化方差;
  • rank RR
  • 缩放 α/R\alpha/R
  • 输入与层激活的尺度。

双随机并不逻辑上保证模型立即完全失效, 但它放弃了“从预训练函数原样起步”的重要性质。

7. A 随机、B 为零如何启动

视频采用

A=A00,B=0.A=A_0\ne0,\qquad B=0.

初始时

AB=0,AB=0,

所以旁路不改变基座输出。

首步梯度为

LAB=0=0,\left.\frac{\partial L}{\partial A}\right|_{B=0}=0,
LBB=0=A0TXTG,\left.\frac{\partial L}{\partial B}\right|_{B=0} =A_0^TX^TG,

后者通常非零。

图 6

本视频采用 A 随机、B=0:初始 ΔW=0,首步 ∂A=0 而 ∂B 通常非零,随后 B 激活 A 的梯度。

原视频 · 03:00 ↗

因此第一步先更新 BB

一旦 BB 离开零, XTGBTX^TGB^T 也能让 AA 获得梯度。

这不是说 AA 永远不更新, 只是它的首步梯度在该初始化方向下为零。

8. 交换 A、B 名称时结论如何迁移

某些论文或代码写

ΔW=BA\Delta W=BA

并采用相反的 shape 与因子命名。

也可能把另一个因子设零。

不要死记“A 必须随机、B 必须为零”。

不变的原则是:

  1. 两个因子的乘积初始为零,使模型函数不变;
  2. 其中一个因子非零,使另一个因子的梯度路径可用;
  3. 因子 shape、乘法方向与实际前向完全一致。

库版本、初始化函数与 target module 不同, 都应以运行时参数与源码为准。

跟练与练习

原视频跟练

编者练习

若改用 A=0A=0B=B00B=B_0\ne0, 初始输出是否改变?首步哪个因子有梯度?

查看参考答案

因为 AB=0AB=0
初始 LoRA 输出仍为零,基座函数不变。

LA=XTGB0T\frac{\partial L}{\partial A} =X^TGB_0^T
通常非零,而
LB=0TXTG=0.\frac{\partial L}{\partial B} =0^TX^TG=0.
因此这一命名约定下先更新 AA
随后非零的 AA 再激活 BB 的梯度。

常见误区

  • 只检查 AB=0AB=0,不检查 L/A\partial L/\partial AL/B\partial L/\partial B
  • 认为双零初始化只是“第一步稍慢”;它会形成持续梯度死锁。
  • 把双随机带来的风险说成无条件、与尺度无关的完全失效。
  • 认为零初始化的那个因子首步也必然没有梯度。
  • 死记 A/B 名称,而不核对具体实现中的乘法顺序和 shape。
  • 忘记 α/R\alpha/R 会缩放梯度,虽然不改变零/非零结构。

本课小结

  • L/A=XTGBT\partial L/\partial A=X^TGB^T,shape 为 D×RD\times R
  • L/B=ATXTG\partial L/\partial B=A^TX^TG,shape 为 R×KR\times K
  • 双零让两个梯度互相截断,LoRA 分支无法启动。
  • 双随机通常使初始低秩更新非零,扰动预训练函数。
  • 一零一非零既保持初始函数,又保留一条首步梯度路径。
  • 真正可迁移的规则依赖乘积、shape 与梯度路径,而不是 A/B 字母名称。
06

主题讲解 · 02:38

从逐位置概率分布看懂知识蒸馏

学习目标

  • 沿 Transformer 前向流定位知识蒸馏所比较的输出。
  • 说明 teacher 与 student 内部维度可不同、输出词表却必须对齐。
  • 用编码长度解释熵、交叉熵与 KL 散度的关系。
  • 写准逐位置 forward KL 的方向与求和轴。
  • 从逐位置 KL 构造序列蒸馏损失并说明梯度只更新 student。
  • 识别 temperature、hard-label 混合与位置 mask 等实现边界。

前置与衔接

本课讨论自回归语言模型的 output distillation。

teacher 是较大的模型,student 是较小的模型。

二者读取相同 token 序列, 各自在每个有效位置预测下一个 token 的词表分布。

图 1

教师与学生处理同一 token 序列,并在逐位置词表分布之间计算 KL 散度来训练学生。

原视频 · 00:00 ↗

为避免符号混乱,固定:

Pt(v)=pteacher(xt+1=vxt),P_t(v)=p_{teacher}(x_{t+1}=v\mid x_{\le t}),
Qt(v)=pstudent(xt+1=vxt).Q_t(v)=p_{student}(x_{t+1}=v\mid x_{\le t}).

tt 是序列位置,vv 是词表中的 token 类别。

核心讲解

1. KL 比较的是哪一层

输入 token 先嵌入为矩阵 XX

经过 Q、K、V 投影、causal attention、FFN 与词表投影后, 模型才得到逐位置 logits。

softmax 将 logits 变为词表概率。

图 2

每个 token 经 Q、K、V 与因果 attention 流向逐位置的 next-token 词表分布。

原视频 · 00:20 ↗

本视频的 KL 发生在 teacher 与 student 的输出概率之间, 不是直接比较二者内部的 Q、K、V 或 FFN 隐状态。

若要做 hidden-state distillation, 还需另行处理层对齐与维度投影;那不是本课主线。

2. 模型可以不同,输出事件空间要一致

teacher 可以层数更多、hidden size 更宽。

student 可以层数更少、hidden size 更窄。

它们内部张量不必同 shape。

图 3

教师可更深更宽、学生可更浅更窄,但二者在相同位置必须输出可对齐的词表概率。

原视频 · 01:00 ↗

但要直接计算 output KL, 二者必须在同一位置对同一个词表事件集合给出概率。

也就是说

Pt,QtRV,P_t,Q_t\in\mathbb{R}^{V},

且 token id 到词表项的映射一致。

若 tokenizer 或 vocabulary 不同, 不能不经对齐就逐元素计算 KL。

3. 编码树中的熵

视频用编码长度解释 KL。

假设事件真实出现频率按 PP 分布。

若编码长度按 PP 设计, 事件 vv 的理想码长是

P(v)=logP(v).\ell_P(v)=-\log P(v).

平均最优码长是熵

H(P)=vP(v)logP(v).H(P)=-\sum_v P(v)\log P(v).

这里“最优码长”是在理想化概率编码意义下描述的。

4. 用 Q 的码长编码 P 产生交叉熵

如果事件仍按 PP 出现, 却使用根据 QQ 设计的码长

Q(v)=logQ(v),\ell_Q(v)=-\log Q(v),

平均码长是

H(P,Q)=vP(v)logQ(v).H(P,Q)=-\sum_v P(v)\log Q(v).
图 4

编码树类比中,教师分布 P 决定事件频率;用 P 的最优码长得到熵,用学生分布 Q 的码长得到交叉熵。

原视频 · 01:20 ↗

关键点是: 两种平均都由 P(v)P(v) 加权。

QQ 决定的是第二套码长, 不是把事件的实际出现频率改成 QQ

在蒸馏中,teacher 的 PP 是训练目标分布。

它不是自然界字面意义上的“真实数据分布”, 只是编码类比中被固定为参考分布的一方。

5. KL 是多出来的平均码长

交叉熵减去熵:

H(P,Q)H(P)=vP(v)logP(v)Q(v).H(P,Q)-H(P) =\sum_v P(v)\log\frac{P(v)}{Q(v)}.

这就是

DKL(PQ).D_{KL}(P\Vert Q).

因此视频中的蒸馏方向是

DKL(PteacherQstudent),D_{KL}(P_{teacher}\Vert Q_{student}),

常称 forward KL。

KL 不对称:

DKL(PQ)DKL(QP).D_{KL}(P\Vert Q)\ne D_{KL}(Q\Vert P).

交换 teacher 与 student 不只是改写符号, 会改变损失的加权方式与优化行为。

6. 单个序列位置如何计算

在位置 tt

Lt=v=1VPt(v)logPt(v)Qt(v).L_t=\sum_{v=1}^{V} P_t(v)\log\frac{P_t(v)}{Q_t(v)}.
图 5

单个位置按 D_KL(P_teacher∥Q_student)=Σ_v p_v log(p_v/q_v) 比较完整词表分布。

原视频 · 02:00 ↗

画面示例的一项是

0.7log0.70.6.0.7\log\frac{0.7}{0.6}.

这只是一项, 完整 KL 还必须对该位置的全部词表项求和。

若使用自然对数,单位是 nat; 若使用以 2 为底的对数,单位是 bit。

只要训练与解释保持一致, 底数变化相当于固定尺度变化。

7. 沿序列位置聚合

设有效位置集合为 M\mathcal{M}

序列蒸馏损失可写成

LKD=1MtMDKL(PtQt).L_{KD}=\frac{1}{|\mathcal{M}|} \sum_{t\in\mathcal{M}}D_{KL}(P_t\Vert Q_t).
图 6

在每个有效 next-token 位置求 KL,再沿序列位置聚合为学生模型的蒸馏损失。

原视频 · 02:20 ↗

padding、无效 label 或特定对话区间可从 M\mathcal{M} 排除。

训练时通常将 teacher 输出视为常量并停止梯度, 只反向更新 student 参数。

否则优化就不再是“固定教师指导学生”的标准设定。

8. KL 与 soft-label cross entropy 的梯度关系

对固定 teacher 分布 PP

DKL(PQ)=H(P,Q)H(P).D_{KL}(P\Vert Q)=H(P,Q)-H(P).

H(P)H(P) 与 student 参数无关。

因此最小化 forward KL 与最小化 soft-label cross entropy

vP(v)logQ(v)-\sum_v P(v)\log Q(v)

对 student 有相同梯度。

保留 KL 写法的价值是: 它明确表达两个分布的距离方向, 并使编码长度解释更完整。

9. 视频外补充:temperature 与 hard labels

以下是常见实现补充,不是视频逐句给出的配置。

蒸馏常用温度 τ\tau 软化分布:

Pt(τ)=operatornamesoftmax(ztteacher/τ),P_t^{(\tau)}=operatorname{softmax}(z_t^{teacher}/\tau),
Qt(τ)=operatornamesoftmax(ztstudent/τ).Q_t^{(\tau)}=operatorname{softmax}(z_t^{student}/\tau).

τ>1\tau>1 会让低概率类别携带更多相对信息。

有些实现将蒸馏项乘 τ2\tau^2 以补偿梯度尺度, 并与真实 token 的 hard-label CE 混合:

L=λτ2LKD+(1λ)LCE.L=\lambda\tau^2L_{KD}+(1-\lambda)L_{CE}.

是否使用温度、τ2\tau^2、混合系数与具体 reduction, 必须以实现配置为准。

跟练与练习

原视频跟练

编者练习

teacher 在某位置给出 P=(0.7,0.2,0.1),P=(0.7,0.2,0.1), student 给出 Q=(0.6,0.3,0.1).Q=(0.6,0.3,0.1). 写出 DKL(PQ)D_{KL}(P\Vert Q),并说明为何不能只算第一项。

查看参考答案

使用自然对数:
DKL(PQ)=0.7log0.70.6+0.2log0.20.3+0.1log0.10.1.D_{KL}(P\Vert Q) =0.7\log\frac{0.7}{0.6} +0.2\log\frac{0.2}{0.3} +0.1\log\frac{0.1}{0.1}.
最后一项为零,
但第二项不是零。
KL 衡量完整事件空间上的分布差异,
只取 teacher 最大概率类别会丢掉其余 soft targets 的信息。

常见误区

  • 直接比较 teacher 与 student 的内部矩阵,却没有处理不同 hidden size。
  • 认为模型大小不同就无法蒸馏;output KL 只要求位置与词表事件对齐。
  • 把 teacher 分布字面称为真实数据分布,而忽略它只是固定训练目标。
  • DKL(PQ)D_{KL}(P\Vert Q)DKL(QP)D_{KL}(Q\Vert P) 当作同一个损失。
  • 只计算 0.7log(0.7/0.6)0.7\log(0.7/0.6),遗漏词表其余项。
  • 对 padding 或被 mask 位置也无条件求平均。
  • 让 teacher 与 student 同时被蒸馏损失更新,却仍称为固定教师蒸馏。
  • 把 temperature、τ2\tau^2 或 hard-label 混合当成视频已经指定的配置。

本课小结

  • teacher 与 student 可有不同深度和 hidden size。
  • output distillation 要求二者的 token 位置与词表事件空间对齐。
  • 熵使用 P 的最优码长,交叉熵用 Q 的码长编码按 P 出现的事件。
  • 二者之差是 DKL(PteacherQstudent)D_{KL}(P_{teacher}\Vert Q_{student})
  • KL 在每个有效位置对完整词表求和,再沿序列聚合。
  • 标准训练固定 teacher,只用该损失更新 student。
  • 温度、hard-label 混合和 mask 是实现相关配置,不能从简图中默认。
07

主题讲解 · 00:36

一张图读懂 LoRA 的低秩更新

学习目标

  • 用一张矩阵图比较全量微调与 LoRA。
  • 写清输入、基座权重、两个低秩因子的 shape。
  • 说明为什么 LoRA 只训练小矩阵而冻结大矩阵。
  • 解释缩放 α/R\alpha/R 的位置与作用。
  • 证明低秩更新可以与主权重相加并在部署前合并。
  • 划清参数效率、秩上界与量化部署的解释边界。

前置与衔接

短视频用矩形宽高表达矩阵 shape。

本课将图中的 nmrn、m、r 统一写为:

  • NN:样本或 token 数;
  • DD:输入特征维;
  • KK:输出特征维;
  • RR:LoRA rank。

采用行向量右乘约定:

XRN×D,WRD×K.X\in\mathbb{R}^{N\times D},\qquad W\in\mathbb{R}^{D\times K}.
图 1

同一线性层中,全量微调直接训练大矩阵 W;LoRA 冻结 W 并叠加低秩旁路。

原视频 · 00:00 ↗

若具体库把线性层权重存成 [K,D][K,D], 代码中的因子顺序可能转置; 本课先按画面的右乘数学约定推导。

核心讲解

1. 全量微调更新完整权重

基础线性层是

Y=XW.Y=XW.

全量微调直接让 WW 参与反向传播与优化。

图 2

全量微调让与输入相乘的完整权重矩阵 W 参与更新。

原视频 · 00:06 ↗

可训练参数量是

DK.DK.

微调后得到与 WW 同 shape 的新权重 WW'

输入输出接口没有改变, 但完整矩阵的参数值都可能被更新。

2. LoRA 冻结 W 并增加旁路

LoRA 不直接更新 WW

它冻结基座权重, 再引入两个可训练小矩阵 ABA、B

图 3

LoRA 保持大矩阵 W 冻结,只让新增低秩分支承担任务更新。

原视频 · 00:12 ↗

前向写成

Y=XW+XΔW.Y=XW+X\Delta W.

XWXW 是原主分支, XΔWX\Delta W 是新旁路。

训练梯度更新 ABA、B, 不更新被冻结的 WW

3. 瘦高 A 与扁平 B 如何相乘

ARD×R,A\in\mathbb{R}^{D\times R},
BRR×K.B\in\mathbb{R}^{R\times K}.

AA 把输入特征从 DD 压到低秩维 RRBB 再从 RR 映射到输出维 KK

图 4

瘦高矩阵 A 与扁平矩阵 B 经中间秩 R 相乘,形成与 W 同形的更新。

原视频 · 00:18 ↗

shape 链为

XN×DAD×R(XA)N×R,X_{N\times D}A_{D\times R} \rightarrow (XA)_{N\times R},
(XA)N×RBR×KXABRN×K.(XA)_{N\times R}B_{R\times K} \rightarrow XAB\in\mathbb{R}^{N\times K}.

因此旁路输出与 XWXW 同 shape。

4. AB 为什么是低秩更新

矩阵乘积满足

rank(AB)min(rank(A),rank(B))R.\operatorname{rank}(AB) \le \min(\operatorname{rank}(A),\operatorname{rank}(B)) \le R.

所以

ABRD×KAB\in\mathbb{R}^{D\times K}

虽然与 WW 同 shape, 但其秩至多为 RR

LoRA 的建模假设是: 任务适配所需的权重改变量可以由较低秩结构有效表达。

这不意味着任何任务的最佳全量更新都严格低秩, 而是用受限参数化换取训练与存储效率。

5. 缩放 α/R 不能漏掉

视频明确把有效更新写为

ΔW=αRAB.\Delta W=\frac{\alpha}{R}AB.
图 5

LoRA 的有效更新为 (α/R)AB;缩放不改变 shape,但决定旁路幅度。

原视频 · 00:24 ↗

α/R\alpha/R 是标量, 不改变矩阵 shape 或秩上界, 但会改变旁路输出与梯度的尺度。

完整前向是

Y=X(W+αRAB).Y=X\left(W+\frac{\alpha}{R}AB\right).

若训练时使用该缩放, 部署合并时也必须保留同一个系数。

6. 参数量为何更小

LoRA 的可训练参数量是

DR+RK=R(D+K).DR+RK=R(D+K).

Rmin(D,K)R\ll\min(D,K)

时,通常有

R(D+K)DK.R(D+K)\ll DK.

这解释了参数高效微调中的“参数高效”。

但它不自动保证训练总显存按同一比例降低。

激活、优化器实现、量化方式与目标模块范围 也会决定实际内存和速度。

7. 为什么能合并回一个矩阵

因为 WWαRAB\frac{\alpha}{R}AB 都是 D×KD\times K, 可以定义

W=W+αRAB.W'=W+\frac{\alpha}{R}AB.

于是

Y=XW.Y=XW'.
图 6

因为 (α/R)AB 与 W 同形,W+(α/R)AB 可以在部署前合并为一个新权重。

原视频 · 00:30 ↗

合并后不再需要显式计算 A、B 旁路, 线性层恢复为单矩阵前向。

“恢复”指结构与 shape, 并不是回到原来的数值 WW

适配信息已经进入 WW'

8. 视频外补充:并非部署时都要合并

以下是实现边界,不是短视频逐句结论。

也可以保留未合并 adapter:

  • 同一基座快速切换不同任务。
  • 只分发较小的 adapter checkpoint。
  • 运行时动态组合多个 adapter。

这时每次前向仍计算旁路, 但获得了任务切换能力。

若基座权重采用低比特量化, 合并往往需要反量化、相加、再量化。

有限精度会引入舍入误差, 不能仅凭实数代数式宣称合并前后 bitwise 完全一致。

跟练与练习

原视频跟练

编者练习

给定 D=4096D=4096K=4096K=4096R=8R=8, 比较完整更新 ΔW\Delta W 与 LoRA 因子 ABA、B 的参数量。

查看参考答案

完整更新需要
DK=4096×4096=16,777,216DK=4096\times4096=16{,}777{,}216
个参数。
LoRA 因子需要
R(D+K)=8(4096+4096)=65,536R(D+K)=8(4096+4096)=65{,}536
个参数。
两者相差 256 倍。
这个比较只针对该线性层的可训练矩阵参数,
不等于端到端训练显存或速度也恰好相差 256 倍。

常见误区

  • 认为 LoRA 仍然更新大矩阵 WW;标准旁路设定冻结它。
  • 把 A、B 的几何形状看懂了,却没写出 DRKD、R、K 的收缩轴。
  • 认为 ABABWW 同 shape 就一定满秩;其秩至多为 RR
  • 漏掉视频明确给出的 α/R\alpha/R 缩放。
  • 把参数量降低比例直接当成总显存或吞吐提升比例。
  • 认为 LoRA 必须合并后才能部署。
  • 把实数代数等价扩张成量化实现中的 bitwise 等价。
  • 脱离具体库的权重存储 shape,机械照搬 A/B 字母顺序。

本课小结

  • 全量微调训练完整 WW,LoRA 冻结 WW 并训练 A、B。
  • ARD×RA\in\mathbb{R}^{D\times R}BRR×KB\in\mathbb{R}^{R\times K}
  • ABABWW 同 shape,但秩至多为 RR
  • 有效更新是 αRAB\frac{\alpha}{R}AB,缩放决定旁路幅度。
  • LoRA 可训练参数量为 R(D+K)R(D+K)
  • W=W+αRABW'=W+\frac{\alpha}{R}AB 允许部署前合并为单矩阵。
  • 是否合并、如何量化以及库中的转置命名都属于实现边界。
08

单元综合

从监督信号到参数更新:SFT、LoRA 与知识蒸馏的统一训练账本

单元能力目标

完成本单元后,应能从三个互相独立的维度分析模型适配:

  1. 监督什么:硬标签 token、合成 rationale,还是 teacher 的完整概率分布?
  2. 在哪些位置监督:全部 next-token 位置,还是只在 response mask 内?
  3. 更新哪些参数:全量权重,还是 LoRA 的低秩因子?

还应能:

  • labels 与 ignore mask 判断真实损失覆盖范围;
  • 区分合成数据 SFT 与 logit 知识蒸馏;
  • 用 shape 与外积推导 LoRA 的低秩更新;
  • 判断 LoRA 初始化是否保留初始函数并保持首步梯度路径;
  • 用 forward KL 解释 teacher/student 的逐位置分布迁移;
  • 区分训练表示、checkpoint 表示与部署表示。

概念连接

1. 先把序列训练写成逐位置损失

对输入序列的第 tt 个有效位置,模型输出 logits ztz_t 与概率

pt=softmax(zt).p_t=\operatorname{softmax}(z_t).

one-hot 目标为 yty_t 时,单位置交叉熵满足

Lt=ytTlogpt,L_t=-y_t^T\log p_t,
Ltzt=ptyt.\frac{\partial L_t}{\partial z_t}=p_t-y_t.

整个序列的损失由有效位置集合 M\mathcal M 聚合:

L=1MtMLt.L = \frac1{|\mathcal M|} \sum_{t\in\mathcal M}L_t.

预训练、SFT 和蒸馏的关键差别之一,就是 M\mathcal M 和目标分布怎样定义。

2. 预训练与 response-only SFT 的 mask 差异

因果语言模型预训练通常让所有有效 token 位置参与 next-token 预测。

response-only SFT 常把 prompt 对应标签设为 ignore,只让回答位置参与直接交叉熵。

因此 prompt 位置 logits 的直接损失梯度可以为零。

但 prompt token 仍参与回答位置的前向条件:

  • prompt 隐状态影响后续 attention;
  • 共享参数在回答位置继续被使用;
  • 回答损失可以沿条件路径更新共享参数。

“prompt logits 无直接梯度”不等于“prompt 对训练没有影响”。

3. SFT 的真实边界在 labels,而不是页面分区

判断一条训练样本哪些位置被监督,应检查:

  • tokenized input_ids
  • labels
  • ignore index;
  • attention mask;
  • loss reduction 与有效 token 数。

“这是用户消息”或“这是助手消息”的界面标签,不足以证明损失 mask 的实现。

不同模板还可能让特殊 token、工具调用、思维过程或多轮回答采用不同监督规则。

4. 合成 rationale 是扩充硬标签序列

有些数据只有问题与专家答案,缺少中间解释过程。

可以让强 teacher 在问题、参考资料与答案条件下生成 rationale,再组成训练序列:

xrationaleanswer.x \rightarrow rationale \rightarrow answer.

student 随后对这段离散 token 序列做 SFT。

这种方式迁移的是 teacher 生成的文本轨迹,而不是 teacher 在每个位置的完整词表概率。

因此它更准确地属于 synthetic-data SFT。

5. 合成解释需要独立验证忠实性

teacher 知道最终答案时,可能生成“看起来合理”的事后解释,但解释不一定是得到答案的真实因果路径。

对合成 rationale 至少应分别检查:

  • 是否引用了正确文档证据;
  • 中间事实和公式是否成立;
  • 代码或操作是否可执行;
  • 最终答案是否与执行结果一致;
  • 是否泄漏不应作为输入的信息。

执行成功可以验证结果,却不能自动证明自然语言理由完全忠实。

6. LoRA 改变的是参数化,不改变监督目标

对线性层

Y=XW,Y=XW,

全量微调直接更新

WRD×K.W\in\mathbb{R}^{D\times K}.

LoRA 冻结 WW,令更新为

ΔW=sAB,\Delta W = sAB,

其中

ARD×R,BRR×K,A\in\mathbb{R}^{D\times R}, \qquad B\in\mathbb{R}^{R\times K},
s=αRs=\frac{\alpha}{R}

是常见缩放。

前向为

Y=XW+sXAB.Y=XW+sXAB.

损失仍可来自 SFT、偏好学习或其他目标;LoRA 只限制可训练更新所在的参数子空间。

7. rank 1 是外积,一般 rank 是外积和

R=1R=1 时,

ARD×1,BR1×K,A\in\mathbb{R}^{D\times1}, \qquad B\in\mathbb{R}^{1\times K},

所以 ABAB 是一个列向量与行向量的外积,秩最多为 1。

一般 RR 时:

AB=r=1RarbrT.AB = \sum_{r=1}^{R} a_rb_r^T.

因此

rank(AB)R.\operatorname{rank}(AB)\le R.

LoRA 用 R(D+K)R(D+K) 个参数表达一个 D×KD\times K 更新矩阵。

8. shape 比 A/B 名称更可靠

不同论文与库可能交换 AABB 的名称,或按 PyTorch 权重存储约定使用转置形式。

迁移实现时应检查:

  1. 输入 XX 的最后一维;
  2. 主权重在数学公式中的乘法方向;
  3. 两个因子的实际 shape;
  4. 乘积是否与 WW 同 shape;
  5. α/R\alpha/R 或其他缩放放在哪里。

只背“先 A 后 B”不能防止转置错误。

9. 为什么 LoRA 可以合并部署

因为 ABABWW 同 shape,可以预先计算

W=W+sAB.W'=W+sAB.

之后推理只执行

Y=XW.Y=XW'.

训练图中的旁路因此可以变成部署图中的单一权重矩阵。

但“可合并”不代表必须合并:

  • 多租户可能保留多个 adapter 动态切换;
  • 未合并部署会保留额外小矩阵乘;
  • 已量化权重的合并可能需要反量化、重合并与再量化;
  • 合并顺序与精度会带来数值差异。

10. LoRA 初始化必须同时满足两个条件

理想初始化希望:

  1. 初始 ΔW=0\Delta W=0,不扰动预训练函数;
  2. 至少一个低秩因子在第一步能收到非零梯度。

设上游梯度为

G=LY.G=\frac{\partial L}{\partial Y}.

在右乘约定下:

LA=sXTGBT,\frac{\partial L}{\partial A} = sX^TGB^T,
LB=sATXTG.\frac{\partial L}{\partial B} = sA^TX^TG.

A=0A=0B=0B=0,两个梯度都为零,旁路无法启动。

11. 一零一非零保留首步梯度路径

A=0A=0BB 非零,则:

AB=0,AB=0,

初始函数不变;同时

LA=sXTGBT\frac{\partial L}{\partial A} = sX^TGB^T

通常可以非零。

反过来也可以构造同样原则的初始化,取决于具体因子命名和乘法方向。

关键规则不是“哪个字母置零”,而是:乘积初始为零,并保留一条非零梯度路径。

12. 知识蒸馏迁移完整输出分布

teacher 与 student 可以有不同深度、hidden size 和内部结构。

如果做 output distillation,两者需要在监督位置与词表事件空间上对齐。

teacher 在位置 tt 给出分布

Pt(v),P_t(v),

student 给出

Qt(v).Q_t(v).

forward KL 为

DKL(PtQt)=vVPt(v)logPt(v)Qt(v).D_{KL}(P_t\Vert Q_t) = \sum_{v\in\mathcal V} P_t(v) \log\frac{P_t(v)}{Q_t(v)}.

13. KL、交叉熵与 teacher 固定

KL 可写为

DKL(PQ)=H(P,Q)H(P).D_{KL}(P\Vert Q) = H(P,Q)-H(P).

对固定 teacher,H(P)H(P) 不随 student 参数变化,因此最小化 forward KL 等价于最小化 teacher 到 student 的交叉熵。

标准蒸馏训练中 teacher 应 detach,不让 student 的损失反向更新 teacher。

损失先在每个有效位置对完整词表求和,再按 mask 沿序列聚合。

temperature、τ2\tau^2 补偿、hard-label 混合权重都属于实现配置,不能从一张 KL 简图中默认。

14. 合成理由与 logit 蒸馏的根本差别

合成理由 SFT:

  • teacher 先离散生成一条文本;
  • student 只看到这条选定序列;
  • 监督是 hard token labels。

logit 蒸馏:

  • teacher 在每个位置提供整个词表分布;
  • student 学习相对概率结构;
  • 低概率候选与类别相似性也可进入信号。

二者可以组合,但不能因为都有 teacher 就视为同一方法。

对比与决策

1. 三个维度独立选择

可以使用:

  • response-only SFT + 全量微调;
  • response-only SFT + LoRA;
  • 合成 rationale SFT + LoRA;
  • hard-label SFT + logit distillation;
  • 蒸馏损失 + 全量或低秩参数更新。

监督类型、监督 mask 和参数化方式可以自由组合,分析时不要把它们绑定成单一套餐。

2. 何时选合成 rationale

当训练数据缺少中间解释,且有可靠 teacher、证据或执行器可验证时,合成 rationale 能扩充显式推理轨迹。

若无法验证理由忠实性,应降低信任,避免把流畅解释当作真实过程。

3. 何时选 LoRA

当希望减少可训练参数、保存多个小型 adapter,或保持基座冻结时,LoRA 很合适。

若任务更新需要高秩变化,过小的 RR 可能成为表达瓶颈。

部署选择还要考虑 adapter 是否动态切换、是否合并,以及量化权重如何处理。

4. 何时选 logit 蒸馏

当 teacher 输出分布包含比 one-hot 标签更丰富的相对概率信息,且能对齐位置与词表时,logit 蒸馏可迁移软目标。

如果 teacher 与 student 词表不一致,需要额外映射,不能直接逐词表计算 KL。

综合训练

编者练习

一个对话样本含 120 个 prompt token 与 80 个 response token。response-only SFT 将 prompt labels 设为 ignore。请说明哪些 logits 有直接损失梯度,以及 prompt 为什么仍能影响参数更新。

查看参考答案

直接交叉熵只覆盖 response 对应的 80 个有效预测位置,prompt 位置 logits 没有直接损失项。但回答位置的隐藏状态通过 causal attention 读取 prompt 上下文,且 prompt 与 response 共用 embedding、attention、MLP 等参数。回答损失因此沿条件计算图更新共享参数;“prompt logits 无直接监督”不等于“prompt 对梯度无影响”。精确位置还需按 shifted labels、特殊 token 和实际 mask 检查。

编者练习 2

XR32×4096X\in\mathbb{R}^{32\times4096}WR4096×11008W\in\mathbb{R}^{4096\times11008},LoRA rank 为 16。写出 AABBABAB 的 shape、可训练参数量,并说明双零初始化的问题。

查看参考答案

AR4096×16A\in\mathbb{R}^{4096\times16}BR16×11008B\in\mathbb{R}^{16\times11008}ABR4096×11008AB\in\mathbb{R}^{4096\times11008}。可训练参数量为 16(4096+11008)=24166416(4096+11008)=241664。若 A=B=0A=B=0,则 L/A=XTGBT=0\partial L/\partial A=X^TGB^T=0L/B=ATXTG=0\partial L/\partial B=A^TX^TG=0,旁路不能启动。应让一个因子为零、另一个非零,使初始乘积为零但保留首步梯度路径。

编者练习 3

给定 teacher 分布 P=(0.7,0.2,0.1)P=(0.7,0.2,0.1),student 分布 Q=(0.5,0.4,0.1)Q=(0.5,0.4,0.1)。写出 forward KL,并说明为什么这比只用类别 1 的 one-hot 标签包含更多信息。

查看参考答案

DKL(PQ)=0.7log(0.7/0.5)+0.2log(0.2/0.4)+0.1log(0.1/0.1)D_{KL}(P\Vert Q)=0.7\log(0.7/0.5)+0.2\log(0.2/0.4)+0.1\log(0.1/0.1)。one-hot 标签只说明第一类是目标;teacher 分布还说明第二类具有 0.2 概率、第三类具有 0.1 概率,student 会被约束去匹配这种相对结构。teacher 分布仍只是蒸馏目标,不是不可质疑的真实分布。

进入下一单元前

  • 已能从 labels 与 ignore mask 判断 SFT 的直接监督位置。
  • 已能区分 prompt logits 无直接梯度与 prompt 对回答路径无影响。
  • 已能区分合成 rationale 的 hard-label SFT 与逐位置 logit distillation。
  • 已能写出 LoRA 的 shape、rank、参数量、合并公式和梯度初始化条件。
  • 已能说明训练旁路、adapter checkpoint 与合并部署权重的差别。
  • 已能写出 forward KL,并检查 teacher detach、词表对齐和位置 mask。
  • 若仍会按 A/B 字母死记初始化,回看 P146 并重新画实际乘法图。
  • 若仍会把“使用 teacher”统称为蒸馏,回看 P143 与 P147 的监督对象差异。