冻结基础分支LoRA 低秩分支量化/反量化
Transformer 与 QLoRA 矩阵实验台
看见 Q/K/V、LoRA A/B、NF4 量化和梯度,而不是只背 API 名称。
QKV · LoRA · NF4
Transformer block + LoRA 分支
基础权重被冻结并量化保存;LoRA 分支在目标 Linear 旁边产生小的低秩增量,最后逐元素相加。
参数量变化
拖动输入维度、输出维度和 rank,观察完整矩阵与 LoRA 的差距。
完整 W16.78 M
LoRA A+B131.07 K
占比0.78%
参数少不代表一定更强;rank 太小可能欠拟合,rank 太大又会增加显存和过拟合风险。
一层 Transformer 的数据流
| 张量 | 形状 | 含义 |
|---|---|---|
| X | [B,T,D] | Token 隐藏状态 |
| Q/K/V | [B,h,T,d] | 查询、匹配、内容 |
| QKᵀ | [B,h,T,T] | Token 之间的分数 |
| A·V | [B,h,T,d] | 加权取回内容 |
| MLP | [B,T,D] | 逐 Token 非线性变换 |
Y = X·dequant(W₀)ᵀ + (α/r)·(X·Aᵀ)·Bᵀ
从矩阵到梯度:为什么第一步 B 先动
这是一个可手算的 2×2 LoRA 例子。A 随机、B 全零,调整上游梯度 G 后重新计算梯度。
输入和超参数
当前矩阵
| 第 1 列 | 第 2 列 | |
|---|---|---|
| X | 1 | 2 |
| A 第1行 | 0.1 | 0.2 |
| A 第2行 | -0.1 | 0.3 |
| B 第1列 | 0 | 0 |
| B 第2列 | 0 | 0 |
Z = X Aᵀ;ΔY = (α/r) Z Bᵀ
Z₁0.5
Z₂0.5
ΔY[0, 0]
链式法则得到的梯度
∂L/∂B₁₁0.4
∂L/∂B₂₁-0.2
∂L/∂A(第一步)[0, 0; 0, 0]
原因B=0
B 全零让初始 ΔY=0,但 ∂L/∂B 非零;optimizer.step() 后第二步 A 才会收到梯度。
Q/K/V 和因果注意力
用 4 个 Token 的小矩阵展示 `QKᵀ/√d`、上三角因果掩码和每一行 Softmax。
注意力参数
A = softmax((QKᵀ / √d + causal_mask) / temperature)
第 4 个 Token 可以看见前 4 个位置。
注意力矩阵 A
颜色越深,权重越大未来位置被 mask 为 0
为什么 Q/K/V 不能混成一件事
Q Query我要找什么
K Key你用什么特征被找到
V Value找到后取回的内容
去掉投影并令 Q=K=V=X 仍能算点积注意力,但没有独立可学习的匹配空间;去掉注意力模块则不同 Token 之间无法建立这条直接路径。
NF4:4 bit 索引如何恢复成浮点权重
选择一个原始权重,观察它落到哪个非均匀码字,以及 block scale 对反量化值的影响。
量化参数
q = argmin |w/s − cᵢ|;ŵ = s·c_q
归一化 w/s0.775
NF4 index13
反量化 ŵ0.557
NF4 非均匀码本
橙色表示当前最近码字,误差会传递到基础分支的前向结果,但不更新 q 本身。
量化不会改变 LoRA 的训练职责
保存q + scale
基础权重冻结
可训练A、B
计算反量化后 matmul
!教学码本用于说明“索引—scale—反量化”机制。生产 QLoRA 还需要验证 NF4 kernel、双重量化、BF16/FP16 累加、显存边界和 checkpoint 兼容性。