💎使用 Unsloth 将 MoE 模型微调速度提升 12 倍
使用 Unsloth 在本地训练 MoE LLMs 的指南。
我们引入了约 12 倍更快的专家混合(MoE)大语言模型训练,配合 减少 >35% 的显存 以及 约 6 倍更长的上下文 通过我们新的 MoE Triton 内核和新的数学优化,且准确性无损。
gpt-oss-20b 在 12.8 GB 显存中进行微调。Qwen3-30B-A3B(16-bit LoRA)使用 63GB。
我们的内核适用于数据中心(B200、H100)、 消费级 和更旧的 GPU(例如 RTX 3090),以及 FFT、LoRA 和 QLoRA。
我们与 🤗Hugging Face 合作,使所有 MoE 训练运行标准化为 PyTorch 的新 torch._grouped_mm 函数。Transformers v5 最近对 MoE 做了约 6 倍的加速优化,Unsloth 通过自定义 Triton 分组‑GEMM + LoRA 内核将在此基础上进一步提升,带来 额外的 约 2 倍的速度提升、>35% 的显存减少和 >6 倍更长的上下文(相较 v4 整体加速 12-30 倍)。
试用我们的 Unsloth 笔记本以实现快速 MoE 训练:

🦥 Unsloth MoE Triton 内核
除了 torch._grouped_mm (参见 Faster MoE Training),我们创建了自定义的 Triton MoE 内核,在某些情况下甚至更快。它们也 向后兼容 旧硬件如 A100 和较旧的 PyTorch 版本。
在 A100 上,我们的 Triton 内核约快 2.5 倍 相比于 torch._grouped_mm。这些内核还有一次性自动调优步骤来选择最佳内核配置。
自动调优在训练开始时大约需要 ~2 分钟,但与 _grouped_mm相比可以使完整运行在 A100 上加速 35%,对于较长训练非常值得。

模型越大、使用的上下文越多, 我们的 Unsloth 内核带来的内存节省就越明显 (效率将呈指数级扩展)。
🧭 自动后端选择
我们主要的创新是我们的 Split LoRA 方法 用于高效 MoE,与 Transformers v5 + 相比可节省约 35% 内存并在训练时快 2 倍。 torch._grouped_mm自定义 torch._grouped_mm + 我们的 Triton 内核比 Transformers v4 快约 12-30 倍。

在以下情形下训练 MoE 模型 4-bit 目前不建议使用 QLoRA,因为 BitsandBytes 尚不支持。这并非 Unsloth 特有。现在请对 LoRA 使用 bf16 或进行完整微调。
Unsloth 将根据你的硬件自动选择以下后端之一:
grouped_mm
torch._grouped_mm — 在 T4 到 B200 上可用,但为 H100 及以上进行了优化。
unsloth_triton
Unsloth Triton 内核 — 在 A100 和较旧的 PyTorch 版本上会自动启用。
native_torch
原生 PyTorch。它慢 12 倍,但我们的显存减少仍然有效!
你也可以自己切换:
要启用更快的 MoE 训练,通过以下方式更新 Unsloth: pip install --upgrade unsloth unsloth_zoo
❓什么是 torch._grouped_mm?
此前,专家混合(MoE)的权重被存储为一个 ModuleList 由每个专家的线性层组成。运行前向传递的唯一实际方法是对专家进行 for 循环,这既昂贵又非最优。
PyTorch 最近引入了 grouped_mm 以解决这个确切的瓶颈。与此同时,我们提供了自己的针对 MoE 优化的 Triton 内核。这也与 Transformers 的一个关键变化一致:从 Transformers v5 起,专家权重被存储为一个 单一的 nn.Parameter,使得 grouped_mm 成为更适合更快 MoE 训练和推理的形式。
因此 transformers 4.57.6 更改为:
变为 transformers 5.0.0 风格:
torch._grouped_mm 可在从 NVIDIA T4 开始的 GPU 上运行,我们已在 H100、A100、B200 和 RTX 6000 Pro 上验证,因而支持范围广泛。
我们还此前为 gpt-oss 推出了 Unsloth Flex Attention ,这些优化应当使其更高效。
📊 内核结果与基准测试
下面是与使用 MoE 的 Transformers v5(已使用 torch._grouped_mm 的 MoE)相比,在不同序列长度下训练速度和内存使用的对比。对于 gpt-oss BF16 MoE 训练,我们在 NVIDIA B200 上观察到 7 倍更快的训练和 36% 的显存减少 。对于 Qwen3-30B-A3B,则约 1.8 倍加速,且 GLM 4.7 Flash 在 RTX PRO 6000 上速度提升 2.1 倍。所有基准均使用 LoRA 秩 = 64 且所有 MoE 层(gate、up、down)均启用 LoRA 模块。
gpt-oss 基准
我们对 unsloth/gpt-oss-20b-BF16 进行了微调以做基准测试。Unsloth 在 16K 上下文长度下快 7 倍且显存减少 36%。Transformers v5 + TRL 会内存溢出,而 Unsloth 不会。且在此情况下,随着序列长度的增加,速度提升还会增加,这要归功于我们的 Long Context gpt-oss,以及我们的 MoE 内核。


1024
275.35
376.99
40.91
43.88
1.4 倍
6.76%
2048
292.88
696.57
41.83
44.93
2.4 倍
6.89%
4096
370.30
1785.89
43.68
49.86
4.8 倍
12.39%
8192
712.33
5226.86
47.43
73.80
7.3 倍
35.73%
16384
1775.80
内存溢出(OOM)
55.13
内存溢出(OOM)
不适用
不适用
Qwen3 基准
在一块 NVIDIA B200上,我们看到 对 Qwen3-30B-A3B LoRA 有约 ~1.7 倍的加速和约 ~35% 的更好内存效率,且在更长序列长度下内存节省进一步增加。
Qwen3-Next 和 Coder 在 bf16 LoRA 下令人惊讶地能够在单个 B200 GPU 上运行。

在 H100 GPU 上,我们的表现显著优于基线,在训练中达到 1.77 倍的加速 ,在 4K 上下文长度的微调中同时节省约 5.3GB。我们可以无缝扩展到 8192 的上下文长度,而 Transformers v5 + TRL 在 8K 时会 OOM。注意我们在 8K 时使用的显存比基线在 4K 时还少,因此我们可以继续推动更长的上下文长度。
1024
366.3
628.3
80.88
104.80
1.7 倍
2.06%
2048
467.0
745.3
80.88
104.81
1.6 倍
2.57%
4096
711.6
975.5
80.89
104.80
1.4 倍
5.08%
8192
1376.6
1633.5
80.90
104.81
1.2 倍
9.17%
16384
3182.2
3407.9
85.53
116.61
1.1 倍
15.26%
GLM 4.7 基准
Unsloth 实现了 2.6 倍更高的吞吐量并且显存减少 >15% 在所有批次大小下针对 GLM 4.7 Flash。GLM 4.7 Flash 是一个 30B 的 MoE(3B 活跃参数)代理与编码模型,采用类似 DeepSeek MoE 风格的配置,具有 64 个路由专家和 1 个共享专家。我们将 Unsloth MoE 训练与新优化的 Transformers v5 进行了基准比较。
使用下面我们的新 Colab 笔记本来试用 GLM 4.7 Flash:

512
1145.0
2992.1
57.81
60.89
2.6 倍
6.51%
1024
1298.9
3323.3
58.76
62.55
2.6 倍
6.22%
2048
1831.9
4119.3
60.09
67.32
2.3 倍
9.46%
4096
2883.9
5646.1
63.34
76.78
2 倍
14.83%
⚡更快的 LoRA MoE 训练
在 Transformers/PEFT 中,通常的方法是 将 LoRA 适配器合并到基权重中 然后再运行 MoE 计算(尤其是因为 MoE 常常使用 nn.Parameter 而不是 nn.Linear)。问题在于这种合并实际上会 物化 LoRA 的增量(针对所有专家) lora_B @ lora_A.t,这 非常耗内存.
Unsloth 避免了这一点。我们此前使用相同的思路来优化通用的 LoRA 训练和推理,现在我们也将其应用于 MoE + LoRA 。数学等式相同,因此损失、梯度和输出保持不变。唯一的变化是 运算顺序,这由矩阵乘法的结合律得以实现。通过这种重排,我们获得了显著的加速和内存减少。
在以下情形下训练 MoE 模型 4-bit 目前不建议使用 QLoRA,因为 BitsandBytes 尚不支持。这并非 Unsloth 特有。现在请对 LoRA 使用 bf16 或进行完整微调。
这些优化在使用 Unsloth 训练 MoE 模型时 默认启用 (尤其是 Qwen-3 MoE、gpt-oss 以及上文提到的模型)。你可以通过 UNSLOTH_MOE_BACKEND 环境变量切换实现:要么使用 torch._grouped_mm Triton 内核 要么使用 基本的 PyTorch for 循环,取决于兼容性和偏好。我们默认使用 grouped_mm 以获得最佳性能和广泛支持。
📚 实现细节
LoRA 是一种参数高效的微调方法:你不是更新完整的权重矩阵,而是训练一个低秩的“适配器”,参数少得多,从而大幅减少优化器的内存需求。
如果原始权重的形状为 (m,n),LoRA 添加了两个可训练矩阵,形状为 (m,r) 以及 (r,n)。它们的乘积是 (m,n),但你只为以下内容跟踪优化器状态和梯度:
m*r + r*n参数(LoRA)而不是m*n参数(全部微调)
在对 MoE 进行微调时——微调路由器层并不是一个好主意,因此我们默认将其禁用。
对于典型的 MLP 层, m ≈ 4096,n ≈ 12k,且 r ≈ 64,大约是 ~1M LoRA 参数 vs ~48M 完整参数 - 大约 ~2%, 通常几乎没有或没有精度损失。
MoE 中的 LoRA 改变了情况
MoE 层不同,因为你有 E 个并行的专家 MLP,所以任何每专家的变化(例如添加 LoRA)会在所有专家间扩展。
以 Qwen3‑30B‑A3B为例:隐藏尺寸 m=2048,中间尺寸 n=768, E=128 个专家, k=8 个在每个 token 上被激活。每个专家:
gate_proj以及up_proj:(m,n) =(2048,768)down_proj:(n,m) =(768,2048)
使用 LoRA 秩 r=64,每个投影增加 r*(m+n)=64*(2048+768)=180,224 每个专家的参数(≈ 11% 一个 2048×768 矩阵)。核心问题是 r/n = 64/768 相对于典型的 MLP 配置来说很大,例如, r/n = 64/25600 在 Qwen3-32B 中具有类似大小的模型里。
如果你将其在 所有 专家上物化,内存很快就会累积。而且由于 gate_proj 以及 up_proj 通常被融合为 gate_up_proj,你通常会将两者一起物化,大致使开销/峰值内存翻倍。
在内存方面,对于序列长度 s、E 个专家且 k 被选择,我们对两种方法都有以下常见项
这就是差异开始出现的地方。对于 peft 的方法我们有
对于 Unsloth 的分割 LoRA 方法,我们执行以下操作
现在我们以 Qwen3-30B-A3B 为例。
E = 128,k = 8,m = 2048,n = 768。 将这些代入,我们得到 s < 32K。
在计算方面,对于序列长度 s, E 个专家和前 k 被选择,我们正在进行:
在我们提到的 Unsloth 分裂 LoRA 的情况下,我们有
从分析角度看,Split LoRA 更好的一点是当 s > Emn/k(m+n) 时成立,数量级大约为 16K 标记(tokens),针对 Qwen3-30B-A3B 风格的模型。
最后,一些加速来自于 减少的内存传输:现代 GPU 通常是 带宽受限的,因此传输更少的数据可能比 FLOPs 更重要。一个粗略的加速估计是 Emn / [k·s·(m+n)],因此它强烈依赖于 s、E、k,以及矩阵形状。
🔮 模型支持
Unsloth 支持 Qwen、gpt-oss、DeepSeek 和 GLM 模型的更快 MoE 训练:
Qwen3 (Thinking and Instruct):VL • 2507 • Coder
gpt-oss:20B • 120B • safeguard
GLM:4.5 • 4.6 • 4.6-Air • 4.7 • 4.7-Flash
DeepSeek:V3 • R1 • V3.1 • V3.2
我们可能还未上传某些 MoE 模型,但 Unsloth 仍应支持它们。
📈 更多基准测试
gpt-oss BF16 基准
训练速度(包括 vs Transformers v4)
1024
275.35
376.99
2111.18
1.37x
2048
292.88
696.57
2626.80
2.38x
4096
370.30
1785.89
4027.93
4.82x
8192
712.33
5226.86
8513.52
7.34x
16384
1775.80
内存溢出(OOM)
内存溢出(OOM)
不适用
内存 VRAM 使用量
1024
40.91
43.88
89.75
6.76%
2048
41.83
44.93
90.47
6.89%
4096
43.68
49.86
92.72
12.39%
8192
47.43
73.80
100.3
35.73%
16384
55.13
内存溢出(OOM)
内存溢出(OOM)
不适用
🎉 重要的 Unsloth 更新
作为我们 MoE 发布的一部分,我们还做了 Gemma-3 现在默认使用 Flex-Attention ,并且这在 float16 设置下也可用(之前存在的无穷值问题我们已解决)。 Gemma-3 现在使用 O(N) 内存而不是 O(N^2) 内存,训练速度提高 >3 倍 (随上下文长度扩展表现更好)。之前的 Unsloth 版本会 OOM(内存溢出)。

1K
20.1 GB
20.1 GB
0 GB(0%)
2K
21.5 GB
21.1 GB
0.3 GB(2%)
4K
27.7 GB
23.3 GB
4.5 GB(16%)
8K
52.3 GB
27.5 GB
24.8 GB(47%)
16K
内存溢出(OOM)
36.0 GB
--
24K
内存溢出(OOM)
44.6 GB
--
32K
内存溢出(OOM)
53.1 GB
--
48K
内存溢出(OOM)
38.4 GB
--
64K
内存溢出(OOM)
44.7 GB
--
视觉微调现在接受仅图像和文本混合的数据!
trl==0.27.1以及transformers==5.1.0得到了良好支持——此前覆盖了我们 120 个笔记本中的 30%,但现在我们有 >80% 的覆盖率——我们计划在接下来的几天内将其做到 100%。许多错误修复和其他更新 - 参见 https://github.com/unslothai/unsloth/releases/tag/February-2026
要启用更快的 MoE 训练,通过以下方式更新 Unsloth: pip install --upgrade unsloth unsloth_zoo
致谢
我们感谢 Hugging Face 团队与我们合作,为社区改进 MoE 训练。
我们还由衷感谢 torchao 团队,特别是 Vasily Kuznetsov(vkuzo)帮助我们使 float16 的 grouped_mm 支持在 T4 上可用并与 A100 保持向后兼容。
最后更新于
这有帮助吗?

