LoRA
LoRA (Low-Rank Adaptation): 保留原来的权重, 只学习一个由两个小矩阵表示的更新量.
令 y=W0x. Fine-tuning (FT) 时, 将权重 W0 更新为 W0+ΔW, 其中:
ΔW=sBA.
各矩阵的维度为:
W0∈Rdout×din,B∈Rdout×r,A∈Rr×din.
r≪dout,din, 因而大大减少需要更新的参数量.
y2=(W0+ΔW)x=W0x+sB(Ax).
其中 W0 固定, FT 时实际更新的参数是 A,B.
对于序列输入 x∈Rdin×dseq:
Ax∈Rr×dseq.
rank 的证明
rank(BA)≤min{rank(A),rank(B)}≤r.
把 A 的列向量记为 a1,a2,…,an, 则:
BA=[Ba1,Ba2,…,Ban].
BA 的每一列都是 B 的列向量的线性组合, 因而:
rank(BA)≤rank(B).
对应地, 从行空间也可得到 rank(BA)≤rank(A).
例子: LoRA 生图模型
冻结 Foundation Model 的 W0, 用特定画风的 dataset 训练一组 A,B:
Y=W0X+sB(AX).
这样可以用较低成本适配不同画风. 示意图见下方手写原稿.
类似思路: DeepSeek 的 MLA.
QLoRA
1. NF4
4-bit weightdequantBF16 approximate weightGEMMoutput.
4-bit 可以表示 24=16 个数据点. 如何分布这 16 个点? 如果零附近数据多, 两端数据少, 就可以考虑 Quantile Quantization (QQ).
Gaussian 假设与分位数
假设权重分布为:
W∼N(0,σ2).
令 Z∼N(0,1), 则分位数满足:
QW(p)=σQZ(p).
QZ(⋅) 表示标准正态分布的分位数函数: 给定分位 p, 返回对应的随机变量取值.
在 CDF 的概率轴上等分, 映射到数值轴后, 零附近的区间更窄, 两端的区间更宽. 原稿中的 CDF 图画的就是这个关系.
分位数采样与端点问题
一个直观的构造是:
qi=QZ(2ki).
但要避开两个端点:
QZ(0)=−∞,QZ(1)=+∞.
因此, 对单个分位数样点, 可以考虑用 2k+1 作分母, 取 i=1,…,16.
原文中的形式则是:
qi=21[QZ(2k+1i)+QZ(2k+1i+1)].
这里仍有一个疑问: 如果采样包含 i=0, 或包含使 (i+1)/(2k+1)=1 的端点, 仍然会遇到无穷值. 原文的采样索引与端点该怎样处理?
这个式子是在用区间端点的均值代替区间内的值, 而且均值取在随机变量的数值空间, 并非分位数的概率空间.
量化还有一个要求: 0→0, 即必须有 exact-zero. 这与零值和 sparsity 有关, 同时也要考虑对称性问题.
归一化与匹配
令:
a=max∣W∣.
把权重归一化到 [−1,1], 再与归一化后的分位数匹配:
aW∈[−1,1]⟷maxiQZ(pi)QZ(pi).
2. Double Quantization (DQ)
每个权重块还需要额外保存一个 32-bit 的量化常数 aj. 如果一个块包含 64 个 weight, 平均位宽就会达到 4.5 bit. 因此, 可以进一步压缩 aj.
对于包含 64 个 weight 的块 Wj, 用量化常数 aj 和量化后的数值 q 表示:
Wj≈ajq,aj=max∣Wj∣.
q 来自前面的 QQ 过程, aj 是 quantization constant.
对所有 aj 再做量化. 先减去均值 μ, 再缩放:
rj=baj−μ.
将 rj 从 32-bit 量化到 8-bit, 得到 rj, 再重建:
aj=μ+brj.
其中 μ 和 b 用 32-bit 保存. 最终得到约 4.127 bit/param.
手写原稿
