# Backend para ahli

Semua implementasi Mixture-of-Experts (MoE) melakukan komputasi tingkat tinggi yang sama. Untuk setiap token, router memilih *k* ahli. State tersembunyi token kemudian diproyeksikan melalui parameter ahli yang dipilih dan diagregasi dengan bobot routing. Perbedaan antara backend ahli adalah *bagaimana* perkalian matriks ahli tersebut dieksekusi.

`ExpertsInterface` menyediakan backend pakar yang dioptimalkan. Antarmuka ini memisahkan implementasi pakar dari kode model untuk menyederhanakan eksperimen dengan fungsi yang berbeda. Tambahkan backend baru melalui antarmuka yang sama.

| backend pakar | deskripsi | GPU | CPU |
| --- | --- | --- | --- |
| `"eager"` | Implementasi referensi yang melakukan perulangan pada pakar yang dipilih dan menerapkan proyeksi pada token mereka. | Kinerja baseline yang wajar tanpa memerlukan kompilasi. | Lebih lambat daripada `grouped_mm` tetapi lebih cepat daripada `batched_mm`. |
| `"batched_mm"` | Duplikasi parameter ahli yang dipilih untuk setiap token dan memproyeksikan semua token dalam satu GEMM batched menggunakan [torch.bmm](https://docs.pytorch.org/docs/stable/generated/torch.bmm.html). | Paling cepat untuk input kecil, terutama dengan kompilasi. Menggunakan lebih banyak memori karena duplikasi parameter. | Tidak disarankan (jauh lebih lambat daripada backend lainnya). |
| `"grouped_mm"` | Mengurutkan token berdasarkan pakar yang dipilih dan menggunakan [torch.nn.functional.grouped_mm](https://docs.pytorch.org/docs/stable/generated/torch.nn.functional.grouped_mm.html) untuk memproyeksikan semua token dalam satu GEMM berkelompok (memerlukan PyTorch 2.9+). | Paling cocok untuk input yang lebih besar dan lebih hemat memori karena menghindari duplikasi parameter ahli. Cepat dengan kompilasi. | Backend paling efisien untuk semua ukuran input. |
| `"deepgemm"` | Mengurutkan token berdasarkan ahli yang dipilih dan memproyeksikan semua token dalam satu GEMM berkelompok yang selaras TMA menggunakan kernel [DeepGEMM](https://github.com/deepseek-ai/DeepGEMM) dari [kernels-community/deep-gemm](https://huggingface.co/kernels-community/deep-gemm). | Backend native untuk model DeepSeek pada Hopper (SM90+) dan Blackwell (SM100+); mendukung `bfloat16` dan ahli yang dikuantisasi FP8/FP4. | Tidak didukung (hanya CUDA). |
| `"deepgemm_megamoe"` | Fuses dispatch expert-parallel, gated MLP (up projection, SwiGLU, down projection), dan EP combine menjadi satu kernel DeepGEMM Mega MoE, dengan menumpuk transfer NVLink dengan komputasi tensor-core. | Hanya untuk Blackwell (SM100+), untuk ahli yang dikuantisasi FP4 yang dijalankan dengan paralelisme ahli. | Tidak didukung (hanya CUDA). |
| `"sonicmoe"` | Menggabungkan MoE forward `bfloat16` yang di-rutekan (router dispatch, gated up projection, activation, down projection) menjadi kernel grouped-GEMM CuteDSL (dari pustaka [quack](https://github.com/Dao-AILab/quack)) dari [kernels-community/sonic-moe](https://huggingface.co/kernels-community/sonic-moe). | Throughput state-of-the-art pada Hopper (SM90+) untuk `bfloat16` experts dengan gated activation (SwiGLU/GeGLU/ReGLU), terutama untuk training. | Tidak didukung (hanya CUDA). |

Backend `"batched_mm"` dan `"grouped_mm"` juga menjalankan pakar terkuantisasi FP8 dan FP4 (`int8`-packed) melalui kernel Triton finegrained-fp8, dengan membaca skala `float32` atau UE8M0. Keduanya berfungsi sebagai fallback untuk checkpoint terkuantisasi ketika backend `"deepgemm"` tidak tersedia.

## Peralihan tahap dekode

Pada GPU, model yang dimuat dengan `experts_implementation="grouped_mm"` secara otomatis beralih ke `"batched_mm"` untuk tahap decode dari proses generasi, yang jauh lebih cepat pada jumlah token yang lebih rendah. Backend asli dipulihkan setelah generasi selesai. Pada CPU, `grouped_mm` tetap aktif selama proses generasi karena lebih efisien pada setiap ukuran input.

Switch mencapai lapisan MoE di model tingkat atas dan di backbone sub-config mana pun, seperti `text_config` dari model vision-language. Hanya entri `grouped_mm` yang beralih ke `batched_mm`. Ekspert yang menjalankan backend lain tetap mempertahankannya.

## Atur backend pakar

Gunakan argumen `experts_implementation` di [from_pretrained()](/docs/transformers/v5.23.0/id/main_classes/model#transformers.PreTrainedModel.from_pretrained) untuk membuat model dengan backend experts tertentu.

```py
from transformers import AutoModelForCausalLM

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

Beralih antara backend pakar pada waktu runtime tanpa memuat ulang model menggunakan [set_experts_implementation()](/docs/transformers/v5.23.0/id/main_classes/model#transformers.PreTrainedModel.set_experts_implementation).

```py
model.set_experts_implementation("eager")
```

Baca backend yang sedang berjalan dengan [get_experts_implementation()](/docs/transformers/v5.23.0/id/main_classes/model#transformers.PreTrainedModel.get_experts_implementation). Fungsi ini mengembalikan `dict` dengan satu entri untuk model, dan satu entri untuk setiap sub-config.

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

## Backend pakar spesifik backbone

Model multimodal dapat memiliki beberapa sub-konfigurasi (misalnya, backbone yang berbeda). Anda dapat mengatur backend pakar yang berbeda untuk setiap sub-konfigurasi dengan meneruskan `dict` ke `experts_implementation` saat pemuatan.

Kunci dalam pemetaan harus cocok dengan nama sub-konfigurasi.

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

Atur backend pakar secara global dengan kunci kosong.

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

## DeepGEMM

Backend `"deepgemm"` merutekan matmul pakar melalui kernel [DeepGEMM](https://github.com/deepseek-ai/DeepGEMM) yang didistribusikan oleh [kernels-community/deep-gemm](https://huggingface.co/kernels-community/deep-gemm). Backend ini berfungsi dengan pakar `bfloat16` yang tidak dikuantisasi dan dengan pakar yang dikuantisasi FP8/FP4 yang dimuat melalui [Fine-grained FP8](./quantization/finegrained_fp8).

Backend `"deepgemm"` membutuhkan:

- GPU CUDA dengan kemampuan komputasi ≥ 9.0 (Hopper atau lebih baru).
- Toolkit CUDA lengkap dengan `nvcc` untuk kompilasi JIT kernel, versi 12.3 atau lebih baru di Hopper dan 12.9 atau lebih baru di Blackwell. Instalasi hanya runtime tidak memiliki `nvcc` dan akan ditolak. Transformers menemukan toolkit melalui `CUDA_HOME`, `CUDA_PATH`, `nvcc` di `PATH`, lalu `/usr/local/cuda`.
- Paket [kernels](https://github.com/huggingface/kernels).

```py
from transformers import AutoModelForCausalLM

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

Kernel dimuat secara lambat (lazy) pada forward pertama.

### Ekspert terkuantisasi FP8 dan FP4

Checkpoint bergaya DeepSeek biasanya sudah terkuantisasi sebelumnya dan membawa konfigurasi kuantisasi mereka sendiri, sehingga Anda tidak perlu meneruskan [FineGrainedFP8Config](/docs/transformers/v5.23.0/id/main_classes/quantization#transformers.FineGrainedFP8Config). Backend `"deepgemm"` secara otomatis memilih kernel grouped-GEMM FP8 (atau FP4 pada Blackwell). DeepGEMM mensyaratkan skala aktivasi dinamis per baris (`activation_scheme="dynamic"`) dan menolak kuantisasi aktivasi statis (per tensor).

```py
from transformers import AutoModelForCausalLM

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

Untuk bobot pakar yang dikemas FP4 (gaya DeepSeek V4), GPU harus SM100+ (Blackwell). Konfigurasi checkpoint biasanya mengatur `expert_dtype="fp4"` dan `scale_fmt="ue8m0"`.

> [!NOTE]
> Pada Blackwell (SM100+), kernel pakar `"deepgemm"` dan `"deepgemm_megamoe"` memerlukan skala pakar UE8M0 yang merupakan pangkat dua. Checkpoint yang dikuantisasi dengan skala `float32` biasa (`scale_fmt="float"`) akan memicu `ValueError` pada forward pertama, alih-alih merusak output secara diam-diam. Muat checkpoint yang dikuantisasi dengan `scale_fmt="ue8m0"`, atau beralih ke `grouped_mm` atau `batched_mm`, yang mengonsumsi skala blok `float32` secara langsung. Hopper (SM90+) mengonsumsi skala `float32` pada jalur DeepGEMM tanpa konversi.

Alasan utama untuk meneruskan [FineGrainedFP8Config](/docs/transformers/v5.23.0/id/main_classes/quantization#transformers.FineGrainedFP8Config) untuk checkpoint yang sudah dikuantisasi sebelumnya adalah untuk mendekuantisasinya kembali ke `bfloat16`, di mana para ahli (experts) berjalan dalam `bfloat16` alih-alih pada jalur DeepGEMM FP8/FP4.

```py
from transformers import AutoModelForCausalLM, FineGrainedFP8Config

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

### Fused Mega MoE di Blackwell

Pada Blackwell (SM100+), atur `experts_implementation="deepgemm_megamoe"` untuk menjalankan satu kernel terpadu yang menggabungkan dispatch paralel ahli, proyeksi up, SwiGLU, proyeksi down, dan combine EP, dengan menumpuk transfer NVLink dengan komputasi tensor-core.

Backend ini membutuhkan:

- GPU Blackwell (kemampuan komputasi ≥ 10.0) dengan toolkit CUDA (`nvcc`) 12.9 atau lebih baru.
- Bobot pakar yang dikemas FP4 yang dipasangkan dengan skala bobot UE8M0 (checkpoint pra-kuantisasi biasanya menyatakan `expert_dtype="fp4"` dan `scale_fmt="ue8m0"` di konfigurasinya).
- Grup proses `torch.distributed` untuk grup paralel ahli, yang disediakan secara otomatis oleh pembungkus paralel ahli ketika `ep_size > 1`.

```py
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

Backend `"sonicmoe"` menggabungkan forward MoE yang di-rutekan (dispatch, gated up projection, activation, down projection) menjadi serangkaian kernel grouped-GEMM CuteDSL yang sangat dioptimalkan, dibangun di atas pustaka [quack](https://github.com/Dao-AILab/quack) dan didistribusikan oleh [kernels-community/sonic-moe](https://huggingface.co/kernels-community/sonic-moe).

Backend `"sonicmoe"` membutuhkan:

- GPU CUDA dengan kemampuan komputasi ≥ 9.0 (Hopper atau lebih baru).
- Paket [kernels](https://github.com/huggingface/kernels) dan paket `nvidia-cutlass-dsl`.
- Para ahli dengan aktivasi bergerbang (`silu`, `gelu`, atau `relu`, dipetakan ke SwiGLU/GeGLU/ReGLU).

```py
from transformers import AutoModelForCausalLM

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

Jika persyaratan tidak terpenuhi, forward akan memicu `ImportError` dan Anda harus memilih `experts_implementation` yang berbeda.

## torch.compile

Backend `"eager"`, `"batched_mm"`, dan `"grouped_mm"` kompatibel dengan `torch.compile` dalam berbagai tingkat. Tabel berikut merangkum kompatibilitas mereka. Backend `"deepgemm"`, `"deepgemm_megamoe"`, dan `"sonicmoe"` diarahkan melalui kernel CUDA eksternal dan tidak dicakup oleh tabel ini.

| Implementasi          | mode kompilasi                    | dtypes                           | `fullgraph=True` |
| ----------------------- | ------------------------------------ | -------------------------------- | ---------------- |
| `grouped_mm`            | `None`, `max-autotune-no-cudagraphs` | `bfloat16`                       | Ya              |
| `grouped_mm` (cadangan) | `None`, `max-autotune-no-cudagraphs` | `bfloat16`, `float16`, `float32` | Ya              |
| `batched_mm`            | semua                                  | `bfloat16`, `float16`, `float32` | Ya              |
| `eager`                 | semua                                  | `bfloat16`, `float16`, `float32` | Tidak               |

Catatan:

- Backend pakar `grouped_mm` saat ini hanya mendukung `bfloat16` saat dikompilasi dengan `torch.compile`. Selain itu, backend ini tidak kompatibel dengan CUDA graphs, sehingga Anda harus menggunakan `mode=None` atau `mode="max-autotune-no-cudagraphs"` saat melakukan kompilasi.
- Backend pakar `eager` menggunakan operasi yang bergantung pada data untuk menemukan pakar mana yang digunakan dalam langkah maju. Operasi ini tidak kompatibel dengan kompilasi grafik penuh (`fullgraph=True`).

```py
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

[Benchmark](https://github.com/user-attachments/files/24125816/bench.py) ini membandingkan berbagai ukuran input dan implementasi pakar dengan dan tanpa `torch.compile`.

