Transformers documentation

Backends 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.2).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Backends experts

Toutes les implémentations Mixture-of-Experts (MoE) effectuent le même calcul de haut niveau. Pour chaque jeton, un routeur sélectionne k experts. L’état caché du jeton est ensuite projeté à travers les paramètres des experts sélectionnés et agrégé avec les poids de routage. La différence entre les backends d’experts réside dans la manière dont ces multiplications de matrices d’experts sont exécutées.

ExpertsInterface fournit des backends d’experts optimisés. Il découple l’implémentation des experts du code du modèle afin de simplifier l’expérimentation avec différentes fonctions. Ajoutez de nouveaux backends via la même interface.

experts backenddescriptionGPUCPU
"eager"Implémentation de référence qui itère sur les experts sélectionnés et applique des projections sur leurs jetons.Des performances de référence raisonnables sans nécessiter de compilation.Plus lent que grouped_mm mais plus rapide que batched_mm.
"batched_mm"Duplique les paramètres d’expert sélectionnés pour chaque jeton et projette tous les jetons dans une seule GEMM par lots à l’aide de torch.bmm.Le plus rapide pour les petites entrées, en particulier avec la compilation. Utilise plus de mémoire en raison de la duplication des paramètres.Non recommandé (nettement plus lent que les autres backends).
"grouped_mm"Trie les jetons par les experts sélectionnés et utilise torch.nn.functional.grouped_mm pour projeter tous les jetons en une seule GEMM groupée (nécessite PyTorch 2.9+).Idéal pour les entrées de grande taille et plus efficace en mémoire car il évite de dupliquer les paramètres des experts. Rapide avec la compilation.Backend le plus efficace pour toutes les tailles d'entrée.
"deepgemm"Trie les jetons par expert sélectionné et projette tous les jetons dans une seule GEMM groupée alignée sur TMA à l'aide des noyaux DeepGEMM de kernels-community/deep-gemm.Backend natif pour les modèles DeepSeek sur Hopper (SM90+) et Blackwell (SM100+) ; prend en charge bfloat16 et les experts quantifiés en FP8/FP4.Non pris en charge (CUDA uniquement).
"deepgemm_megamoe"Fusionne la distribution parallèle d’experts, le MLP à porte (projection ascendante, SwiGLU, projection descendante) et la combinaison EP en un seul noyau DeepGEMM Mega MoE, en superposant les transferts NVLink au calcul des tensor cores.Uniquement sur Blackwell (SM100+), pour les experts quantifiés en FP4 exécutés avec un parallélisme d'experts.Non pris en charge (CUDA uniquement).
"sonicmoe"Fusionne le calcul avant routé bfloat16 MoE (dispatch du routeur, projection montée avec porte, activation, projection descendante) dans des noyaux grouped-GEMM CuteDSL (de la bibliothèque quack) issus de kernels-community/sonic-moe.Débit de pointe sur Hopper (SM90+) pour les experts bfloat16 avec une activation à porte (SwiGLU/GeGLU/ReGLU), en particulier pour l'entraînement.Non pris en charge (CUDA uniquement).

Les backends "batched_mm" et "grouped_mm" exécutent également les experts quantisés en FP8 et FP4 (int8-packed) via le noyau Triton finegrained-fp8, en lisant des échelles float32 ou UE8M0. Ils servent de solution de repli pour les points de contrôle quantisés lorsque le backend "deepgemm" n'est pas disponible.

Bascule de l'étape de décodage

Sur GPU, un modèle chargé avec experts_implementation="grouped_mm" bascule automatiquement sur "batched_mm" pour l’étape de décodage de la génération, ce qui est nettement plus rapide pour de faibles nombres de jetons. L’arrière-plan d’origine est rétabli une fois la génération terminée. Sur CPU, grouped_mm reste actif tout au long de la génération, car il est plus efficace quelle que soit la taille de l’entrée.

Le commutateur atteint les couches MoE du modèle de niveau supérieur et de tout backbone de sous-configuration, tel que le text_config d'un modèle vision-langage. Seules les entrées grouped_mm basculent vers batched_mm. Les experts exécutés sur tout autre backend le conservent.

Définir un backend d'experts

Utilisez l'argument experts_implementation dans from_pretrained() pour instancier un modèle avec un backend d'experts spécifique.

from transformers import AutoModelForCausalLM

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

Basculez entre les backends d'experts à l'exécution sans recharger le modèle à l'aide de set_experts_implementation().

model.set_experts_implementation("eager")

Lisez le backend actuellement en cours d’exécution avec get_experts_implementation(). Il renvoie un dict avec une entrée pour le modèle et une entrée par sous-configuration.

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

Backend d'experts spécifiques au backbone

Les modèles multimodaux peuvent avoir plusieurs sous-configurations (par exemple, différents backbones). Vous pouvez définir un backend d'experts différent pour chaque sous-configuration en passant un dict à experts_implementation au moment du chargement.

Les clés de la correspondance doivent correspondre aux noms des sous-configurations.

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,
)

Définissez le backend des experts globalement avec une clé vide.

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

DeepGEMM

Le backend "deepgemm" achemine les produits matriciels d'experts via les noyaux DeepGEMM distribués par kernels-community/deep-gemm. Il fonctionne avec des experts non quantifiés en bfloat16 et avec des experts quantisés en FP8/FP4 chargés via Fine-grained FP8.

Le backend "deepgemm" nécessite :

  • GPU CUDA avec une capacité de calcul ≥ 9.0 (Hopper ou plus récent).
  • Un kit CUDA complet avec nvcc pour la compilation JIT du noyau, version 12.3 ou ultérieure sur Hopper et 12.9 ou ultérieure sur Blackwell. Une installation runtime-only ne contient pas nvcc et est rejetée. Transformers localise le kit via CUDA_HOME, CUDA_PATH, nvcc sur PATH, puis /usr/local/cuda.
  • Le package kernels.
from transformers import AutoModelForCausalLM

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

Le noyau est chargé de manière paresseuse lors du premier passage avant.

Experts quantisés en FP8 et FP4

Les points de contrôle de type DeepSeek sont généralement pré-quantifiés et incluent leur propre configuration de quantification, il n’est donc pas nécessaire de passer un FineGrainedFP8Config. L’arrière-plan "deepgemm" sélectionne automatiquement le noyau de GEMM groupé FP8 (ou FP4 sur Blackwell). DeepGEMM exige des échelles d’activation dynamiques par ligne (activation_scheme="dynamic") et rejette la quantification d’activation statique (par tenseur).

from transformers import AutoModelForCausalLM

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

Pour les poids d'experts en FP4 (style DeepSeek V4), le GPU doit être SM100+ (Blackwell). La configuration du checkpoint définit généralement expert_dtype="fp4" et scale_fmt="ue8m0".

Sur Blackwell (SM100+), les noyaux d’experts "deepgemm" et "deepgemm_megamoe" exigent des échelles d’experts UE8M0 qui soient des puissances de deux. Un point de contrôle quantisé avec des échelles float32 simples (scale_fmt="float") lève une ValueError lors de la première passe avant plutôt que de corrompre silencieusement la sortie. Chargez un point de contrôle quantisé avec scale_fmt="ue8m0", ou passez à grouped_mm ou batched_mm, qui consomment directement les échelles de bloc float32. Hopper (SM90+) consomme des échelles float32 sur le chemin DeepGEMM sans conversion.

La principale raison de passer un FineGrainedFP8Config pour un point de contrôle pré-quantifié est de le déquantifier en bfloat16, auquel cas les experts s'exécutent en bfloat16 plutôt que sur le chemin DeepGEMM FP8/FP4.

from transformers import AutoModelForCausalLM, FineGrainedFP8Config

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

Mega MoE fusionné sur Blackwell

Sur Blackwell (SM100+), définissez experts_implementation="deepgemm_megamoe" pour exécuter un noyau fusionné unique qui combine la distribution parallèle des experts, la projection ascendante, SwiGLU, la projection descendante et la combinaison EP, en superposant les transferts NVLink au calcul des tensor cores.

Ce backend nécessite :

  • Un GPU Blackwell (capacité de calcul ≥ 10.0) avec un kit CUDA (nvcc) 12.9 ou ultérieur.
  • Poids d'experts en FP4 appariés avec des échelles de poids UE8M0 (le point de contrôle pré-quantifié déclare généralement expert_dtype="fp4" et scale_fmt="ue8m0" dans sa configuration).
  • Un groupe de processus torch.distributed pour le groupe parallèle d'experts, fourni automatiquement par l'habillage parallèle d'experts lorsque 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

Le backend "sonicmoe" fusionne le calcul avant routé MoE (dispatch, projection gated up, activation, projection down) dans un ensemble de noyaux CuteDSL grouped-GEMM hautement optimisés, construits sur la bibliothèque quack et distribués par kernels-community/sonic-moe.

Le backend "sonicmoe" nécessite :

  • GPU CUDA avec une capacité de calcul ≥ 9.0 (Hopper ou plus récent).
  • Le package kernels et le package nvidia-cutlass-dsl.
  • Experts avec une activation à porte (silu, gelu ou relu, mappée sur SwiGLU/GeGLU/ReGLU).
from transformers import AutoModelForCausalLM

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

Si les exigences ne sont pas remplies, la méthode forward lève ImportError et vous devez choisir une autre valeur pour experts_implementation.

torch.compile

Les backends "eager", "batched_mm" et "grouped_mm" sont compatibles avec torch.compile dans des proportions variables. Le tableau suivant résume leur compatibilité. Les backends "deepgemm", "deepgemm_megamoe" et "sonicmoe" passent par des noyaux CUDA externes et ne sont pas couverts par ce tableau.

Implémentationmodes de compilationdtypesfullgraph=True
grouped_mmNone, max-autotune-no-cudagraphsbfloat16Oui
grouped_mm (repli)None, max-autotune-no-cudagraphsbfloat16, float16, float32Oui
batched_mmtousbfloat16, float16, float32Oui
eagertousbfloat16, float16, float32Non

Remarques :

  • Le backend d'experts grouped_mm prend actuellement en charge uniquement bfloat16 lors de la compilation avec torch.compile. De plus, il n'est pas compatible avec les graphes CUDA, il faut donc utiliser mode=None ou mode="max-autotune-no-cudagraphs" lors de la compilation.
  • Le backend d'experts eager utilise une opération dépendante des données pour déterminer quels experts sont utilisés lors d'un passage avant. Cette opération n'est pas compatible avec la compilation complète du graphe (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")

Benchmarks

Ce benchmark compare différentes tailles d'entrée et implémentations d'experts, avec et sans torch.compile.

Update on GitHub