- Published on
改变 LoRA 的 rank 就要跟着改学习率吗 — μA(2026) 划出的两种机制,以及这个测量结果的边界
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 引言 — 把 rank 调高之后,又得重新找学习率
- 问题的本质 — α、初始化、rank、学习率彼此纠缠
- μA — 两种机制分岔的地方
- 为什么「学习率 10 倍」的说法一直流传不衰
- 绕行路线 — 把学习率原样从 LoRA 搬到 FFT
- 实验真正测了什么,又没测什么
- 宽度缩放上,两份结果出现分歧
- 那么,实务中该怎么做
- 结语
- 参考资料
引言 — 把 rank 调高之后,又得重新找学习率
真正跑过 LoRA 的人都遇到过这种事。一份在 rank 16 下跑得好好的配方,把 rank 调到 64 之后,损失开始跳、训练也停了。只能重新扫一遍学习率。可要是问问别的团队,得到的说法正相反 — 「rank 尽管往上调,学习率不用动」。
这两种情况都是真实观测到的现象。这个矛盾,也不是实务者看得不够仔细造成的。2026 年 2 月 5 日挂上 arXiv 的Learning Rate Scaling across LoRA Ranks and Transfer to Full Finetuning(Nan Chen, Soledad Villar, Soufiane Hayou, arXiv:2602.06204)说,这两种说法分别是对不同设置成立的真命题。到底哪一种适用于你,取决于你用的 α 约定和初始化方式。
本文梳理这篇论文究竟推导出了什么、实验测了什么、又没测什么。先说结论:会得出一条有用的规则。但支撑它的证据是单一种子(42)、2 倍间隔的网格,作者自己也明确写出了这些局限。把这些局限一并搬过来,正是本文的目的。
问题的本质 — α、初始化、rank、学习率彼此纠缠
先对齐一下论文的记号。LoRA 是在冻结的预训练权重上加一个低秩项。
W ← W + α·B·A
A ∈ R^(r×n) (down-projection,降维投影)
B ∈ R^(n×r) (up-projection,升维投影)
n = 模型宽度(width), r = LoRA rank, α = LoRA 倍率(multiplier)
这里实务者能动的旋钮有四个 — rank r、倍率 α、学习率 η,以及初始化。为了让适配器一开始就是 no-op,会把其中一个因子设为 0,只让另一个随机填充,论文把这两种选择称为:
- Init[A] — A 随机,B = 0。原版 LoRA 用的方式,也是大多数实现的默认值。
- Init[B] — B 随机,A = 0。反过来的一种。
倍率 α 也不止一种取法。按论文第 2 节的梳理,原版 LoRA(Hu 等,2022)用 α = r 的 -1 次方来压低更新幅度;rsLoRA(Kalajdzievski,2023)为了在大 rank 下保持稳定,提出用 α = r 的 -1/2 次方;而近期的研究越来越多地直接用 α = 1。
这里正是实务者容易搞混的地方。 Hugging Face PEFT 并不直接接收 α。打开 PEFT v0.17.0 的源码(论文实际使用的版本)会看到这样的写法。
# peft/tuners/lora/layer.py — update_layer()
if use_rslora:
self.scaling[adapter_name] = lora_alpha / math.sqrt(r)
else:
self.scaling[adapter_name] = lora_alpha / r
也就是说,当 use_rslora=False 时,实际生效的倍率是 lora_alpha / r。换算成论文里的 α,就是:
lora_alpha = 32 (与 rank 无关的常数) -> 实际生效 α = 32/r ∝ r^(-1)
lora_alpha = r (随 rank 一起放大) -> 实际生效 α = 1 (常数)
lora_alpha = 2r -> 实际生效 α = 2 (常数)
这意味着,教程里常见的固定 lora_alpha=32,和最近常被推荐的「让 lora_alpha 跟 rank 一起放大(或放大 2 倍)」这条建议,其实是两种不同的数学机制。按论文第 1 节的说法,LoRA 的更新对 A 和 B 是双线性(bilinear)的,因此初始化、α、rank、η 彼此纠缠,共同决定了实际生效的更新幅度。这就是为什么超参数调优这么容易失灵。
μA — 两种机制分岔的地方
论文在宽度和 rank 同时趋向无穷大的极限(n, r → ∞)下,计算了 LoRA 单步特征更新的幅度。因为它把预训练阶段的 μP(Maximal-Update Parametrization)搬到了微调阶段,所以叫 μA(Maximal-Update Adaptation)。目标是找到那个既不会让特征更新发散、也不会让它消失(即 Θ(1))的学习率。
得先看清前提假设。 论文第 4 节明确写出了三条。
- 每一步的前向输入和反向梯度都以 Θ(1) 有界(假设 4.1)
- 优化器被近似为无动量的 Adam = SignSGD(假设 4.2)。实验本身实际用的是 AdamW。
- 损失按单个样本计算(沿用 Hayou 等,2024b 的做法)
在这些前提之上,得到了两个结果。
Init[A](推论 4.4)。 设 α = r 的 -γ 次方,γ 取 0 到 1 之间的值,稳定特征学习所需的学习率是
η = Θ( n^(-1/2) · r^(-(1-γ)/2) )
γ=0 (α = 1) -> η ∝ n^(-1/2) · r^(-1/2) 依赖 rank
γ=1/2 (α = r^(-1/2)) -> η ∝ n^(-1/2) · r^(-1/4) 弱依赖 rank
γ=1 (α = r^(-1)) -> η ∝ n^(-1/2) 与 rank 无关
照搬论文自己的解读:当 α = 1 时,rank 放大 4 倍,学习率就得减半;而当 α = r 的 -1 次方时,rank 依赖被吸收进了倍率里,学习率就与 rank 无关了。
Init[B],α = 1(推论 4.6)。
η = Θ( n^(-1) ) 与 rank 无关,只依赖宽度
这里出现了论文的核心观察。在同一个 SignSGD 近似之下,线性层的全量微调(FFT)同样满足 η ∝ n^(-1)(附录 A.6,定理 A.23)。宽度缩放是一致的 — 这正是 LoRA 与 FFT 之间学习率能够迁移的必要条件。
还有一个不太为人知的副产品。在 Init[A] 里,rank 越大,A 的贡献就越消失,学习实质上只通过 B 发生。用论文的话说,适配器逐渐表现得像「A 被冻结在初始值上的一个随机投影」,而这种不均衡在 Init[A] 的任何标准 α 取值下都不会消失。Init[B] 则正相反,当 r 远小于 n 时,B 的更新会变得可以忽略,学习主要通过 A 发生。
为什么「学习率 10 倍」的说法一直流传不衰
到这里,前面那个矛盾就解开了。
去年 9 月 29 日,Thinking Machines 的LoRA Without Regret(John Schulman 等)这样写道 — 他们把 W' = W + (α/r)BA 里的 α 固定为 32,发现「1/r 这个缩放因子,让最优学习率大致与 rank 无关」。训练早期,不同 rank 下的损失曲线完全一致,他们甚至写到自己一开始怀疑是不是 rank 这个因子被某个 bug 忽略掉了。
换算成 μA 的坐标,Schulman 的设置就是实际生效 α = 32/r,也就是 γ=1 — 恰好就是推论 4.4 预测「与 rank 无关」的那一格。两种说法里,「与 rank 无关」这一种是对的 — 但前提是你用的是经典的 1/r 约定。 而一旦你开始让 lora_alpha 跟着 rank 放大,你就移到了 γ=0 那一格,在那里 rank 每放大 4 倍,学习率就得减半。这就是为什么同一个人用同一个库,会得到截然相反的经验。
不过 μA 还留下了一件没有解决的事。Schulman 报告的那条著名规则 — 「在同一应用场景下,LoRA 的最优学习率是 FullFT 的 10 倍」。它的依据是这样的:他们在 Tulu3 数据集上,对 Llama 和 Qwen 系列的14 个模型分别扫了 LoRA 和 FullFT 的学习率,拟合了一个用 hidden size 和模型系列(Llama/Qwen)来预测最优学习率的函数。那次优化找到的 LoRA 倍数是 9.8,而且 LoRA 对 hidden size 的依赖指数与 FullFT 相同(拟合结果里 LoRA pow = 0)。他们还记录了一个初步观察 — 短的训练跑次里倍数更大(约 15 倍,并在脚注里写明「这是轶事性的证据,大致在 100 步以内成立」)。
关于这条规则,Schulman 本人加的一句话很重要 — 「我们目前还没有一个令人满意的理论来解释这个观察」。事实上,那篇博客未解决问题清单的第 2 条,正是「一套更完整的理论,用来解释 LoRA 与 FullFT 学习率之比」。
μA 没有回答这个问题。论文第 2 节只是顺带提了一句 Schulman 的结果,把它称为「一条启发式规则(例如把 LoRA 学习率除以 10 得到 FFT 学习率)」,就带过去了。μA 真正做的事情是绕开它 — 不去解释这个比值,而是找出一个让这个比值等于 1 的设置。
绕行路线 — 把学习率原样从 LoRA 搬到 FFT
Init[B] + α = 1 正是那个设置。论文的逻辑是这样的:这个设置所需的学习率是 η ∝ n^(-1),线性层 FFT 所需的学习率也是 η ∝ n^(-1)。宽度缩放一致,最优学习率就可能对齐,一旦对齐,在 LoRA 上调好的学习率就能原样用在 FFT 上。
实验总体上支持这个预测。照搬论文 5.2 节的原话 — 在大多数模型上,Init[B] (α=1) 的最优学习率与 FFT 的最优学习率对齐得很接近。例外是 RoBERTa-large,FFT 偏好的学习率比 Init[B] 略小一点。论文把这归咎于额外加上的分类头 — 分类头的学习率固定为 10 的 -3 次方,但它和适配器一起训练,可能会把最优点带偏。
作者提出的实务工作流程,正是从这里来的。在用 GRPO 把 Llama-3.1-8B 在 GSM8k 上微调的 RLVR 实验中,FFT 用的 GPU 显存超过 LoRA(r=256)的两倍以上,超出的部分大多花在梯度缓冲区和优化器状态上(同一实验里,两者每步的实际耗时相近)。所以这篇论文卖的东西就是:在相对容易拿到的中端 GPU 上,用 Init[B] (α=1) 扫一遍学习率,再把这个值搬到大硬件上的 FFT,省下重新调参的成本。
这里有两点需要如实指出。
第一,论文第 6 节的局限性说得很明确 — 这项分析立起来的是学习率迁移的必要条件,寻找并证明充分条件被留作未来的工作。宽度缩放一致,意味着「可能对齐」,而不是「一定对齐」。实验展示的是对齐,但实验终究只是实验。
第二,Init[B] 不是 PEFT 的默认设置。 看 v0.17.0 源码里的 reset_lora_parameters,默认路径(init_lora_weights=True)是给 lora_A 用 kaiming_uniform_、给 lora_B 用 zeros_ — 也就是 Init[A]。而且论文披露,它在非零的那一侧因子上用的是 Kaiming normal,让 Init[A] 中 A 分量的方差为 1/n、Init[B] 中 B 分量的方差为 1/r。而 PEFT 的默认是 Kaiming uniform。归纳一下:想复现这篇论文的设置,光靠调几个 LoraConfig 标志位是不够的,得直接动手改初始化代码。
实验真正测了什么,又没测什么
这一部分是本文里最重要的部分。
跑了什么。 五个 SFT 设置 — Llama-3.2-1B / Tulu-3 SFT 混合数据(训练 320k,验证 32k,最长 1024 token),Qwen2.5-3B-Instruct / OpenThoughts-114k(71k / 6k,8192 token 打包),RoBERTa-large / ANLI(163k / 3k),ViT-Huge/14 / ImageNet-1K(1.28M / 50k),Qwen3-VL-2B-Instruct / LLaVA-Instruct-Mix(198k / 17k)。此外还有 RLVR 场景下的 Llama-3.1-8B / GSM8k(GRPO 的 DAPO 变体),以及扩散模型场景下的 Stable Diffusion v1.5 / Naruto-BLIP-Captions(1.2k 对,10,000 步)。硬件是 4 张 H200 的一个节点。语言、视觉、视觉语言、图像生成、强化学习全都覆盖到了,这一点上覆盖面确实很宽。
但统计口径是这样的。
- 论文附录 B.1:「所有实验的随机种子都设为 42。」 只有一个种子。没有置信区间,没有误差棒,也没有报告跨种子的方差。
- 学习率网格用的是 log2 尺度、只取整数指数,也就是相邻点相差 2 倍。报告的「最优点」,是这个离散网格上表现最好的那个值。
- 每种设置只有5 个 rank。Init[A] 用的是 4、16、64、256、1024。Init[B] 在 SFT 里用的是 16、32、64、128、256。RLVR 和扩散模型的 Init[A] 用的是 1、4、16、64、256。
- RLVR 训练从 GSM8k 里只抽了500 道题(测试用 50 道)。
论文自己的第 5.1 节把这个局限写了下来。这条缩放规则是 (n, r) → ∞ 时的领头阶依赖,在有限的宽度和 rank 下,常数项和低阶项都可能把最优点推偏,而且这种影响在小 rank 时更大。而且「如果损失地形在最优点附近很平坦,相邻网格点的表现就会很接近,这时哪个看起来是最优,就可能由训练噪声决定」。所以作者宣布,他们评估的标准是定性趋势,而不是精确的数值吻合 — 预测为与 rank 无关的设置,只要最优点都落在网格的一格(2 倍)之内就算通过;预测为依赖 rank 的设置,只要最优点随 rank 单调移动、并跨越多个网格点,就算通过。
也就是说,这篇论文所说的「与 rank 无关」,实际含义是「在单一种子下,落在 2 倍间隔网格的一格之内」。 这是一个有用的结论,但不是一个精确的结论。而论文并没有把这一点藏起来 — 不藏着掖着,正是这篇论文的可取之处。
论文自己也报告了一些偏差。 Qwen2.5-3B-Instruct 的 Init[A] (α=1) 中,r=16 和 r=64 在同一个学习率上取得了最小损失(按预测二者应该不同)。论文把这归咎于网格离散化。而在 Init[A] (α = r 的 -1 次方) 中,小 rank(r=4)偏好的学习率比大 rank 略小,这与 α=1 时观察到的方向恰好相反。论文用有限尺寸效应来解释。值得指出的是,这两处解释都是事后给出的。
还有这篇论文没有测的东西。 这不是一篇「LoRA 和 FFT 一样好」的论文。测的是最优学习率落在哪里,而不是 LoRA 能不能达到 FFT 的最终损失。它讨论的是学习率扫描那条 U 形曲线谷底的位置,而不是在断言谷底的深度。唯一的例外是 RLVR 附录 D.1,其中观察到「不同 rank 下的最高性能相近」,并写道这与 Schulman 一致 — 但这只是一个附带观察,并非这篇论文本身的主张。LoRA 什么时候会不如 FFT,仍然要看LoRA Learns Less and Forgets Less(Biderman 等,TMLR 2024)这类另外的证据 — 那篇论文报告说,在编程和数学领域,标准低秩设置下的 LoRA 会明显不及全量微调,但在目标领域之外的性能保持得更好。
还有一点。在纯解码器 LM 上,LoRA 只挂在 MLP 上(gate_proj、up_proj、down_proj)。这与其说是缺陷,不如说是和当前的最佳实践对齐了 — Schulman 的博客报告说,只用在注意力层上的 LoRA 明显不如只用在 MLP 上的,而且在 MLP 之上再加注意力层也没有额外收益,并写道 Biderman 等人也得到了相同的结果。但这条缩放规则在其他挂载策略下是否成立,这些实验没有给出答案。
宽度缩放上,两份结果出现分歧
这一节是我把两份出处放在一起读出来的结果,先说明一点:这两篇论文都没有在这个具体的点上讨论过对方。
用 μA 的坐标来看,Schulman 的设置是 Init[A],α ∝ r 的 -1 次方。μA 的表 1 在这一格给出 η ∝ n^(-1/2)。而 μA 的定理 A.23 说 FFT 满足 η ∝ n^(-1)。把两者相除,就得到一个预测:LoRA/FFT 的学习率之比与 n 的 1/2 次方成正比 — 也就是说,模型越宽,这个比值应该越大。
可 Schulman 的拟合结果正相反。对 14 个模型做优化后得到的是 LoRA pow = 0,也就是说LoRA 对 hidden size 的依赖和 FullFT 完全一样,倍数固定在 9.8。
这两者原样放在一起是对不上的。但有几个理由让人不能急着说「其中一个错了」。
- μA 的理论是渐近的。论文第 6 节的局限性直接写道「我们的理论是渐近的,在有限的 (n, r) 下可能对噪声敏感」。
- 算一下账就知道,n 的 1/2 次方意味着hidden size 得放大 4 倍,比值才会变化 2 倍。而 2 倍,在 log2 网格上正好是一格。也就是说,这个被预测出来的差异,其大小可能是这两项研究的测量分辨率都捕捉不到的。
- Schulman 的拟合给 Llama 和 Qwen 两个系列分别设了独立的指数,所以也很难说它是一次纯粹的宽度缩放检验。
诚实的结论是这样 — 能把这个分歧理清楚的数字,目前还没有发表出来。 μA 没有解释那条 10 倍规则,Schulman 的拟合也不是为了检验 μA 的宽度指数而设计的。得有人把这两套坐标系对齐,再用多个种子、在很宽的 hidden size 范围内扫一遍,才能得到答案。据我所知,这样的实验还不存在。
那么,实务中该怎么做
1. 先确认你的 α 约定。 这是本文里最便宜、也最靠得住的一条收益。
固定 lora_alpha(比如 32) + use_rslora=False -> 实际生效 α ∝ r^(-1)
=> 改变 rank 时保持学习率不变。(Schulman 看到的那种情况)
lora_alpha = r 或 2r -> 实际生效 α = 常数
=> μA 的预测:rank 每放大 4 倍,学习率减半。
论文在附录 C.1 里确认了,当 α 取 2 和 4 时,同样的缩放规律依然成立。也就是说,一旦你听从「让 lora_alpha 跟 rank 一起放大」这条建议,就有一条配套的学习率规则本该一起跟上 — 而这条建议里通常恰恰漏掉了它。
2. 如果你想低成本地找到 FFT 的学习率, Init[B] + α=1 是个候选方案。但(a)它只是必要条件,(b)它不是 PEFT 的默认设置,得自己写初始化代码,(c)证据只来自单一种子。在带分类头的模型上,论文自己也报告了偏差。可以拿它当起点,但要自己验证。
3. 在强化学习里,学习率选错的代价是双重的。 论文第 5.3 节观察到的就是这个 — 在 SFT 里,学习率太小只是让收敛变慢;但在 RLVR 里,无论太大还是太小,训练奖励都会遭到严重破坏。而且还得搭上实际耗时。附录 D.2 的案例研究显示,在最优学习率(2 的 -18 次方)下,模型大约在第 100 步左右走出初期的探索阶段(此时完成长度会顶到 1024 token 的上限),转向大约 200 token 左右的简洁解法,每步耗时 4~5 秒。而在次优学习率(2 的 -16 次方)下,模型会卡在探索阶段出不来,持续输出最大长度,每步耗时 15~22 秒 — 是前者的 3~5 倍。奖励则崩溃到接近 0。作者还记录了一个反方向的失败案例:给 Init[B]、α=1 一个更高的学习率(2 的 -15 次方),模型只生成大约 2 个 token 就停止生成,这同样会让每步变快。意思是,步子变快了,不代表这是件好事。
什么时候用不上这些。 如果你根本不打算改 rank,现在这套配方也跑得好好的,这篇论文对你没有任何帮助。如果模型和任务已经固定下来,一次已经跑过的扫描,比 n, r → ∞ 的渐近规则更靠谱。而且这里所有的规则都是 Θ(·) 形式的 — 只告诉你指数,不告诉你常数。 不管怎样,跑一次基准扫描来定锚点,依然是你自己的活儿。μA 能帮你省下的,是这个扫描要重复几次,而不是扫描本身。
结语
归纳一下。对「改变 LoRA 的 rank,是不是就得重新找学习率」这个问题,截至 2026 年 2 月的答案是「取决于你用的 α 约定」。用经典的 1/r 约定,不用改;用最近越来越常见的、让 lora_alpha 跟 rank 一起放大的做法,rank 每放大 4 倍,学习率就得减半。而在 Init[B] + α = 1 这个较少被使用的设置里,最优学习率与全量微调有着相同的宽度缩放,因此从原理上讲,把在 LoRA 上调好的学习率搬到 FFT 上是可行的。
与此同时,也需要精确了解这些证据的分量。单一种子 42、2 倍间隔的网格、每种设置 5 个 rank、渐近理论,以及作者自己明确写下的「这只是必要条件」这条注脚。作者自己宣布,他们的评估标准是定性趋势,而不是精确的数值吻合,而这篇论文也确实通过了这个标准。不应该从这篇论文里读出比这更多的东西。
而且还有一件事,至今没人知道答案。Schulman 观察到的「LoRA 的学习率是 FullFT 的 10 倍」,依然没有得到解释。μA 没有去解释这个比值,而是转移到了一个让这个比值变成 1 的坐标系里。这在实用层面上是个足够聪明的绕行方案,但 Schulman 那个未解决的问题,依然原封不动地悬在那里。LoRA 从 2021 年起就是我们每天都在用的工具,可它的学习率为什么必须是那个值,到了 2026 年年中,依然没有被完全解释清楚。
参考资料
- Learning Rate Scaling across LoRA Ranks and Transfer to Full Finetuning (Chen, Villar, Hayou, arXiv:2602.06204, 2026-02-05) — 本文的主要出处。μA 框架、推论 4.4 / 4.6、实验及局限性
- LoRA Without Regret (John Schulman 等,Thinking Machines Lab, 2025-09-29) — 10 倍规则(拟合值 9.8)、1/r 缩放下的 rank 无关性、LoRA 挂载层实验、未解决问题清单
- LoRA Learns Less and Forgets Less (Biderman 等,TMLR 2024, arXiv:2405.09673) — 标准低秩设置下 LoRA 不及全量微调、但域外性能保持更好的证据
- A Rank Stabilization Scaling Factor for Fine-Tuning with LoRA (Kalajdzievski, arXiv:2312.03732) — rsLoRA,提出 α = r 的 -1/2 次方
- LoRA vs Full Fine-tuning: An Illusion of Equivalence (Shuttleworth 等,arXiv:2410.21228) — μA 作为相关工作引用的、LoRA 与 FFT 在谱结构上的差异
- Function-Space Learning Rates (Milsom 等,ICML 2025, arXiv:2502.17405) — μA 评价为「只给出规则、没有解释」的一项前人经验性研究
- huggingface/peft v0.17.0 — lora/layer.py (scaling 计算与默认初始化)