Transformers documentation

Experts 后端

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Experts 后端

所有 Mixture-of-Experts (MoE) 实现都执行相同的高层计算。对于每个 token,路由器会选择 k 个专家。随后,token 的隐藏状态会通过所选专家的参数进行投影,并根据路由权重进行聚合。不同专家后端之间的区别在于这些专家矩阵乘法是如何执行的。

ExpertsInterface 提供了经过优化的专家后端。它将专家的实现与模型代码解耦,从而简化了对不同函数的实验。通过同一接口添加新的后端。

experts 后端描述GPUCPU
"eager"参考实现,遍历选定的专家,并对它们的 token 应用投影。无需编译即可实现合理的基线性能。比 grouped_mm 慢,但比 batched_mm 快。
"batched_mm"为每个 token 复制所选的专家参数,并使用 torch.bmm 在单个批量 GEMM 中投影所有 token。对于小型输入,尤其是启用编译时,速度最快。由于参数复制,会占用更多内存。不推荐(比其他后端显著更慢)。
"grouped_mm"按选定的专家对 token 进行排序,并使用 torch.nn.functional.grouped_mm 通过单次分组 GEMM 投影所有 token(需要 PyTorch 2.9+)。适用于较大的输入,并且由于避免了重复专家参数,因此内存效率更高。配合编译使用时速度很快。适用于所有输入尺寸的最高效后端。
"deepgemm"按所选专家对 token 进行排序,并使用来自 kernels-community/deep-gemm 的 DeepGEMM 内核,通过单次 TMA 对齐的分组 GEMM 投影所有 token。DeepSeek 模型在 Hopper (SM90+) 和 Blackwell (SM100+) 上的原生后端;支持 bfloat16 以及 FP8/FP4 量化专家。不支持(仅限 CUDA)。
"deepgemm_megamoe"将专家并行分发、门控 MLP(上投影、SwiGLU、下投影)以及 EP 合并融合为单个 DeepGEMM Mega MoE 内核,使 NVLink 传输与张量核心计算相互重叠。仅适用于 Blackwell(SM100+),用于以专家并行方式运行的 FP4 量化专家。不支持(仅限 CUDA)。
"sonicmoe"将路由的 bfloat16 MoE 前向传播(路由器分发、门控上投影、激活、下投影)融合为来自 kernels-community/sonic-moe 的 CuteDSL 分组 GEMM 内核(源自 quack 库)。在 Hopper(SM90+)上,针对采用门控激活函数(SwiGLU/GeGLU/ReGLU)的 bfloat16 专家,实现了最先进的吞吐量,尤其适用于训练场景。不支持(仅限 CUDA)。

"batched_mm" 和 "grouped_mm" 后端同样通过 Triton finegrained-fp8 内核运行 FP8 和 FP4(int8 打包)量化专家,读取 float32 或 UE8M0 缩放因子。当 "deepgemm" 后端不可用时,它们作为量化检查点的回退方案。

解码阶段切换

在 GPU 上,使用 experts_implementation="grouped_mm" 加载的模型会在生成过程的解码阶段自动切换到 "batched_mm",这在处理较少 token 时速度显著提升。生成结束后,系统会恢复为原始后端。在 CPU 上,grouped_mm 在整个生成过程中保持激活状态,因为它在任何输入规模下都更高效。

该开关会作用于顶层模型以及任意子配置主干中的 MoE 层,例如视觉-语言模型的 text_config。只有 grouped_mm 条目会切换为 batched_mm。运行其他后端的专家将保持原样。

设置 experts 后端

使用 from_pretrained() 中的 experts_implementation 参数,可以实例化一个使用特定 experts 后端的模型。

from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen1.5-MoE-A2.7B",
    dtype="bfloat16",
    experts_implementation="batched_mm",
)

使用 set_experts_implementation() 可在运行时切换专家后端,而无需重新加载模型。

model.set_experts_implementation("eager")

使用 get_experts_implementation() 读取当前正在运行的后端。它返回一个 dict,其中包含一个针对模型的条目,以及每个子配置各一个条目。

model.get_experts_implementation()
# {"": "grouped_mm", "text_config": "grouped_mm", "vision_config": "eager"}

特定骨干的专家后端

多模态模型可以拥有多个子配置(例如,不同的骨干网络)。在加载时,通过向 experts_implementation 传入一个 dict,可以为每个子配置设置不同的专家后端。

映射中的键必须与子配置名称匹配。

from transformers import AutoModelForImageTextToText

experts_implementation_per_backbone = {
    "text_config": "grouped_mm",
    "vision_config": "eager",
}

model = AutoModelForImageTextToText.from_pretrained(
    "Qwen/Qwen3-VL-Moe",
    experts_implementation=experts_implementation_per_backbone,
)

使用空键全局设置 experts 后端。

model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen1.5-MoE-A2.7B",
    experts_implementation={"": "batched_mm"},
)

DeepGEMM

"deepgemm" 后端通过 kernels-community/deep-gemm 分发的 DeepGEMM 内核来路由专家矩阵乘法。它支持未量化的 bfloat16 专家,以及通过 Fine-grained FP8 加载的 FP8/FP4 量化专家。

"deepgemm" 后端需要:

  • 计算能力 ≥ 9.0 的 CUDA GPU(Hopper 或更新架构)。
  • 完整的 CUDA 工具包,包含用于内核 JIT 编译的 nvcc,在 Hopper 上版本需为 12.3 或更高,在 Blackwell 上需为 12.9 或更高。仅包含运行时的安装没有 nvcc,会被拒绝。Transformers 通过 CUDA_HOME、CUDA_PATH、PATH 上的 nvcc,然后 /usr/local/cuda 来定位工具包。
  • kernels 包。
from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained(
    "deepseek-ai/DeepSeek-V3",
    dtype="bfloat16",
    experts_implementation="deepgemm",
)

内核会在第一次前向传播时延迟加载。

FP8 和 FP4 量化专家

DeepSeek 风格的检查点通常已预先量化,并自带量化配置,因此无需传入 FineGrainedFP8Config。"deepgemm" 后端会自动选择 FP8(或在 Blackwell 上选择 FP4)分组 GEMM 内核。DeepGEMM 要求使用动态逐行激活缩放(activation_scheme="dynamic"),并拒绝静态(逐张量)激活量化。

from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained(
    "deepseek-ai/DeepSeek-V3",
    experts_implementation="deepgemm",
)

对于 FP4 打包的专家权重(DeepSeek V4 风格),GPU 必须是 SM100+(Blackwell)。检查点配置通常设置为 expert_dtype="fp4" 和 scale_fmt="ue8m0"。

在 Blackwell(SM100+)上,"deepgemm" 和 "deepgemm_megamoe" 专家内核要求使用 2 的幂次 UE8M0 专家缩放因子。使用普通 float32 缩放因子(scale_fmt="float")量化的检查点,在首次前向传播时会抛出 ValueError,而不是静默地损坏输出。请加载使用 scale_fmt="ue8m0" 量化的检查点,或改用 grouped_mm 或 batched_mm,它们可以直接使用 float32 块缩放因子。Hopper(SM90+)在 DeepGEMM 路径上直接使用 float32 缩放因子,无需转换。

为预量化检查点传入 FineGrainedFP8Config 的主要目的是将其反量化回 bfloat16,在这种情况下,专家模块将以 bfloat16 运行,而不是走 FP8/FP4 DeepGEMM 路径。

from transformers import AutoModelForCausalLM, FineGrainedFP8Config

model = AutoModelForCausalLM.from_pretrained(
    "deepseek-ai/DeepSeek-V3",
    quantization_config=FineGrainedFP8Config(dequantize=True),
    experts_implementation="deepgemm",
)

Blackwell 上的融合 Mega MoE

在 Blackwell(SM100+)上,设置 experts_implementation="deepgemm_megamoe" 以运行一个融合内核,该内核将专家并行分发、上投影、SwiGLU、下投影以及 EP 合并组合在一起,并将 NVLink 传输与张量核心计算重叠执行。

此后端需要:

  • 配备 CUDA 工具包(nvcc)12.9 或更高版本的 Blackwell GPU(计算能力 ≥ 10.0)。
  • FP4 打包的专家权重,搭配 UE8M0 权重缩放因子(预量化检查点通常在其配置中声明 expert_dtype="fp4" 和 scale_fmt="ue8m0")。
  • torch.distributed 进程组,用于专家并行组。当 ep_size > 1 时,专家并行封装会自动提供该进程组。
import os

from transformers import AutoModelForCausalLM, DistributedConfig

distributed_config = DistributedConfig(
    tp_size=int(os.environ["WORLD_SIZE"]),
    ep_size=int(os.environ["WORLD_SIZE"]),
)
model = AutoModelForCausalLM.from_pretrained(
    "deepseek-ai/DeepSeek-V4",
    experts_implementation="deepgemm_megamoe",
    distributed_config=distributed_config,
)

SonicMoE

"sonicmoe" 后端将路由式 MoE 的前向传播(dispatch、gated up projection、activation、down projection)融合为一组高度优化的 CuteDSL grouped-GEMM 内核,该内核基于 quack 库构建,并由 kernels-community/sonic-moe 分发。

"sonicmoe" 后端需要:

  • 计算能力 ≥ 9.0 的 CUDA GPU(Hopper 或更新架构)。
  • kernels 包和 nvidia-cutlass-dsl 包。
  • 采用门控激活(silu、gelu 或 relu,分别映射为 SwiGLU/GeGLU/ReGLU)的专家。
from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen1.5-MoE-A2.7B",
    dtype="bfloat16",
    experts_implementation="sonicmoe",
)

如果未满足要求,forward 会抛出 ImportError,此时应选择一个不同的 experts_implementation。

torch.compile

"eager"、"batched_mm" 和 "grouped_mm" 后端在某种程度上与 torch.compile 兼容。下表总结了它们的兼容性。"deepgemm"、"deepgemm_megamoe" 和 "sonicmoe" 后端通过外部 CUDA 内核进行路由,因此不在本表的覆盖范围内。

实现编译模式数据类型fullgraph=True
grouped_mmNone, max-autotune-no-cudagraphsbfloat16是的
grouped_mm(回退)None, max-autotune-no-cudagraphsbfloat16, float16, float32是的
batched_mm全部bfloat16, float16, float32是的
eager全部bfloat16, float16, float32No

注意事项:

  • grouped_mm 专家后端目前仅在通过 torch.compile 编译时支持 bfloat16。此外,它与 CUDA graphs 不兼容,因此编译时必须使用 mode=None 或 mode="max-autotune-no-cudagraphs"。
  • eager 专家后端使用数据依赖操作来确定前向传播中使用了哪些专家。该操作与完整图编译(fullgraph=True)不兼容。
import torch
from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen1.5-MoE-A2.7B",
    dtype="bfloat16",
    experts_implementation="grouped_mm",
    device_map="auto",
).eval()

# Works for grouped_mm (no CUDA graphs)
model.forward = torch.compile(model.forward, mode="max-autotune-no-cudagraphs")

基准测试

此基准测试比较了不同输入大小和专家实现,包括使用和不使用torch.compile的情况。

Update on GitHub