🧠 第八章 神经网络训练
📄 一句话概括

64×64 的权重矩阵配秩 4 的旁路,alpha 取 4 时 ΔW 只有 W 的 0.68%。 scale 从 0 扫到 2.0,输出相对偏离从 0.00% 线性涨到 1.36%。 合并公式就一句:W 新值 = W + (alpha / r) × B × A。

📝 本节和前面几节的关系

上一节把参数填好了。这一节是最后一步:训出来的东西到底能不能用,怎么判断。

一、合并就一句话

推理时有两种走法:不合并(每次前向都多算一遍 B×A 再加回去)和合并(把 ΔW 直接加进 W, 之后就是一个普通模型)。 合并公式:W 新值 = W + (alpha / r) × B × A。算这一行就完事。 Demo 里 W 是 64×64 随机矩阵,A 是 4×64、B 是 64×4,alpha 取 4。 ΔW 的范数 0.0537,W 的范数 7.9398,相对改动 0.68%。 合并之后推理不再有额外开销,但 scale 就固定了,想换力度只能重新合并。 不合并则能实时调 scale,代价是每次前向多算一次矩阵乘。 测试阶段一律不合并——你要扫 scale,合并了就没法扫。

二、scale 扫一遍:线性放大

scale 是推理时乘在 ΔW 上的额外系数。0 等于完全不用 LoRA(就是底座),1 是标准强度,2 是加倍。 Demo 扫 0、0.5、0.8、1.0、1.5、2.0,输出相对偏离分别是 0.00%、0.34%、0.54%、 0.68%、1.02%、1.36%。 严格线性,因为定义就是这样——scale 只是把 ΔW 乘个系数。这不是「测出来」的规律,是「算出来」的。 注意这里的 A、B 是随机初始化的量级,ΔW 只有 W 的 0.68%。 真正训练过的 LoRA 会大得多,具体多大取决于训练强度和 alpha,没有固定值。 所以别把 0.68% 当成「LoRA 的正常改动量」记。

三、测试要做三件事

  1. 对照组。同种子、同提示词、scale 设 0 跑一遍。这是「底座本来什么样」。 没有对照组,你无法判断出图里的变化是 LoRA 带来的还是随机种子带来的。
  2. scale 扫描。0.6、0.8、1.0 各跑一批,看「风格强度」和「画面崩坏程度」的平衡点在哪。 经验上 0.7 到 0.9 是多数 LoRA 的甜区,1.0 往往已经偏硬。
  3. 换提示词。用几个训练集里没出现过的提示词跑,看它是不是只会背训练集。 第三件事最重要。只会在训练集提示词上出效果的,不叫学会画风,叫记住了那几张图。 这一步能筛掉大部分「过拟合但曲线好看」的 LoRA。

四、还有一件事:分层看

真实模型里有上百个矩阵,每层都偏不到 1%。 单看一层微不足道,但串联起来、经过非线性之后,最后一层的输出完全不是同一张图。 这也是为什么很多人发现「只训注意力层的 LoRA 改风格, 训全部层的 LoRA 改结构」——不同层负责的东西不一样。 调试时可以分层关掉一部分:先只保留后面几层看效果,再往前加。这比盲目调 r 和 scale 有效得多。 这一节没做分层实验(Demo 只有一个矩阵),但这是真实调试里最常用的一招,值得记下来。

五、动手 Demo:合并与 scale:偏离随强度线性增长

造一个 64×64 的权重矩阵和秩 4 的旁路(A 是 4×64、B 是 64×4),alpha 取 4;算 ΔW 和它的相对改动量; 再对一个随机输入,扫 scale 从 0 到 2.0,比输出相对底座偏离多少。

dW = B @ A * (alpha / r)                # ΔW
W_new = W + dW                          # 合并

for sc in (0.0, 0.5, 0.8, 1.0, 1.5, 2.0):
    y = W @ x + sc * (dW @ x)           # 不合并,实时调 scale
    print(sc, float(np.linalg.norm(y - W @ x)))

实跑输出:

--------------------------------------------------------------------
测试模型:把 LoRA 合进原权重,看 scale 的影响
--------------------------------------------------------------------
  原权重 W                 64 × 64,标准差 0.1241
  旁路 A / B               4 × 64 与 64 × 4
  alpha                    4,缩放系数 alpha / r = 1.0
  ΔW 的范数                0.0537
  W 的范数                 7.9398
  相对改动量               0.68%

  合并公式就一句:W' = W + (alpha / r) × B × A。推理时把这一行算完,LoRA 就「变成」原权重的一部分,不再多占一次前向。
  scale   输出偏离原模型   相对偏离
  --------------------------------
    0.0           0.0000      0.00%
    0.5           0.0292      0.34%
    0.8           0.0466      0.54%
    1.0           0.0583      0.68%
    1.5           0.0875      1.02%
    2.0           0.1166      1.36%

  表里的偏离随 scale 严格线性增长,这是定义决定的——scale 只是把 ΔW 乘个系数。注意这里的 A、B 是随机初始化的量级,ΔW 只有 W 的 0.68%;真正训练过的 LoRA 会大得多,具体多大取决于训练强度和 alpha,没有固定值。
  测试的时候要做三件事:一是同种子同提示词跑 scale = 0,确认底座本身的出图(这是对照组);二是 0.6 / 0.8 / 1.0 各跑一批,看风格强度和画面崩坏程度的平衡点;三是换几个没在训练集里出现过的提示词,看它是不是只会背训练集。
  第三件事最重要——只会在训练集提示词上出效果的,不叫学会画风,叫记住了那几张图。
  顺带说清「合并」和「不合并」的取舍:合并之后推理不再有额外开销,但 scale 就固定了,只能靠重新合并来换;不合并则能实时调 scale,代价是每次前向都要多算一遍 B × A 和一次加法。测试阶段一律不合并。

ΔW 相对改动 0.68%,很小。 但注意这是随机初始化的 A、B——训练过的 LoRA 会大一个量级,这个数不能当参考值。 scale 那一列严格线性:0.5 是 0.34%、1.0 是 0.68%、2.0 是 1.36%。 因为 y = Wx + scale × ΔWx 这个式子本身对 scale 就是线性的。 「相对偏离」这一列才是该看的:它告诉你「这个力度改了多少」。 绝对偏离 0.0583 这个数没有意义,换个输入尺度就变了。 这个 Demo 只有一个矩阵。 真实模型上百个矩阵串联,单层偏 1% 传到最后会放大很多——所以 scale 调到 2.0 时画面往往已经崩了, 不是「风格更强」而是「结构散了」。

30 秒实验

  1. 把秩从 4 改成 16,看 ΔW 的相对改动量变成多少。
  2. 把 alpha 从 4 改成 8,看重算什么——它和把 scale 乘 2 有区别吗?
  3. 想一想:为什么测试阶段不建议先合并再调 scale?

常见误区

  1. 「scale 越大风格越强」——超过 1.0 之后崩坏的速度比风格增强快得多。
  2. 「没有对照组也能看出效果」——分不清是 LoRA 的效果还是种子本身的差别。
  3. 「训练集提示词效果好就是成功」——那可能只是记住了训练图,换个提示词就露馅。
自测三问(点开对答案) 1. LoRA 的合并公式是什么? —— W 新值等于 W 加上 (alpha / r) 乘 B 乘 A。 2. scale 对输出的影响是什么形状? —— 严格线性,因为 scale 只是乘在 ΔW 上的一个系数。 3. 测试 LoRA 必做的三件事是什么? —— 同种子的 scale=0 对照组、多档 scale 扫描、换训练集外的提示词验证泛化。

第八章到此结束。下一章换到训练完之后的事:怎么用指标客观评估模型好坏,怎么优化到能用。

相关笔记