Transformers documentation

Paralelisme pakar

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

Paralelisme pakar

Expert parallelism adalah strategi paralelisasi untuk model mixture-of-experts (MoE). Lapisan feedforward dari setiap expert berada di akselerator perangkat keras yang berbeda. Router meneruskan token ke expert yang sesuai dan mengumpulkan hasilnya. Pendekatan ini memungkinkan model diskalakan ke jumlah parameter yang jauh lebih besar tanpa meningkatkan biaya komputasi, karena setiap token hanya mengaktifkan beberapa expert.

DistributedConfig

Aktifkan paralelisme pakar dengan kelas DistributedConfig dan argumen ep_size. Sebagian besar model MoE secara default menggunakan token dispatch, sehingga ep_size dapat diatur secara independen dari tp_size. Beberapa model, seperti Llama 4 dan Gemma 4, masih secara default menggunakan masking dan all-reduce ("ep_router" dan "moe_tp_experts" di model.ep_plan). Masking juga tersedia pada model apa pun dengan override ep_plan, dan memerlukan ep_size=tp_size agar setiap rank dalam grup pakar menerima token yang sama.

import os

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.distributed.configuration_utils import DistributedConfig

distributed_config = DistributedConfig(
    tp_size=int(os.environ["WORLD_SIZE"]),
    ep_size=int(os.environ["WORLD_SIZE"]),
)

model = AutoModelForCausalLM.from_pretrained(
    "openai/gpt-oss-120b",
    distributed_config=distributed_config,
)

Setiap model MoE mendefinisikan dua rencana dalam konfigurasinya: base_model_tp_plan untuk modul padat dan base_model_ep_plan untuk para ahli. Keduanya dipaparkan pada model yang dimuat sebagai model.tp_plan dan model.ep_plan. Dengan tp_size > 1 dan ep_size > 1, keduanya berlaku: rencana paralel tensor memecah perhatian dan MLP padat, sedangkan rencana paralel ahli memecah para ahli. Aturan EP memiliki prioritas lebih tinggi daripada aturan TP untuk modul yang sama, sehingga bobot ahli hanya dipecah sekali, oleh rencana EP. Dalam rencana EP, gaya GroupedGemmParallel membagi bobot ahli sepanjang dimensi ahli sehingga setiap rank hanya memuat ahli lokalnya, dan ep_router memfilter ahli yang berada di rank lain sebelum all-reduce menggabungkan keluaran para ahli.

tp_plan hanya diterapkan ketika tp_size > 1, dan ep_plan hanya ketika ep_size > 1. Dengan TP diaktifkan dan EP dinonaktifkan, rencana TP penuh diterapkan, termasuk aturan expert.

Aturan forward ahli dalam ep_plan memilih cara token mencapai para ahli:

aturanmekanismelayout
"moe_tp_experts" dengan "ep_router" pada routermasking dan all-reduce: setiap rank menjalankan expert lokalnya pada seluruh batch, router mem-mask yang lainnya, dan all-reduce menggabungkan outputep_size=tp_size
"ep_dispatch_experts"token dispatch: setiap rank mempertahankan tokennya sendiri dan hanya bertukar pasangan (token, expert) yang di-rutekan melalui dua kolektif all-to-allep_size adalah kelipatan dari tp_size yang membagi fsdp_size * tp_size

enable_expert_parallel=True tanpa ep_size sudah tidak didukung dan mengeluarkan FutureWarning. Ini hanya memecah para ahli, seperti ep_size=tp_size, tp_plan={}.

Jalankan skrip inferensi Anda dengan torchrun. Jumlah proses harus sama dengan tp_size * fsdp_size * pp_size, dan ep_size harus membagi jumlah pakar secara merata.

torchrun --nproc-per-node 8 your_script.py

Mengganti rencana

Lewati tp_plan={...} atau ep_plan={...} ke DistributedConfig untuk menimpa aturan individual dari rencana yang telah ditentukan sebelumnya. Aturan yang tidak ditentukan akan dipertahankan, dan rencana yang digabungkan disimpan pada model. Setiap kunci harus cocok dengan modul, parameter, atau entri rencana yang ada; jika tidak, pemuatan akan memicu ValueError sebelum apa pun dipecah. Gunakan jalur lengkap sebagaimana dilihat dari model yang dimuat, sehingga model.layers.* untuk LM kausal dan layers.* untuk model dasarnya.

distributed_config = DistributedConfig(
    tp_size=4,
    ep_size=4,
    tp_plan={"model.layers.*.self_attn.q_proj": "colwise_rep"},
    ep_plan={"model.layers.*.mlp.experts.down_proj": "grouped_gemm"},
)

Menyediakan rencana tidak menyimpulkan ukuran paralel: atur tp_size dan ep_size secara eksplisit.

Sebagian besar model MoE secara default menggunakan "ep_dispatch_experts". Untuk menggunakan masking dan all-reduce sebagai gantinya, atur ep_size=tp_size dan timpa aturan forward untuk router maupun expert (nama modul router bergantung pada model, misalnya mlp.router pada gpt-oss):

distributed_config = DistributedConfig(
    tp_size=4,
    ep_size=4,
    ep_plan={
        "model.layers.*.mlp.gate": "ep_router",
        "model.layers.*.mlp.experts": "moe_tp_experts",
    },
)

Sebaliknya, timpa aturan forward expert dari model yang rencananya menggunakan masking dengan "ep_dispatch_experts" untuk menggunakan token dispatch. Aturan router kemudian diabaikan, karena dispatch membutuhkan id expert global untuk menemukan pemilik masing-masing expert.

Token dispatch

Dengan token dispatch, setiap rank melatih pada bagian batch-nya sendiri. Pada setiap lapisan MoE, sebuah rank merutekan token-nya, mengirim setiap pasangan (token, expert) ke rank yang memiliki expert tersebut melalui all-to-all, menjalankan expert lokalnya pada apa yang diterimanya, menerima hasilnya kembali melalui all-to-all kedua, dan menggabungkannya dengan bobot routing. Hanya aktivasi yang dirutekan dan output expert yang berpindah, dan tidak ada rank yang menghitung expert untuk token yang tidak dimilikinya.

from transformers import AutoModelForCausalLM
from transformers.distributed import DistributedConfig

distributed_config = DistributedConfig(
    tp_size=1,
    fsdp_size=8,
    ep_size=4,
)
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-30B-A3B", distributed_config=distributed_config)

Dengan tp_size=1, ep_size harus membagi habis fsdp_size dan jumlah pakar, dan perhatian tidak dibatasi oleh num_key_value_heads. Untuk sisa model:

  • Parameter di luar para ahli dipecah dengan FSDP2 di sepanjang fsdp, yang mengurangi gradien mereka.
  • Para ahli di-shard di ep dan, ketika efsdp_size = fsdp_size * tp_size // ep_size lebih besar dari satu, juga di-shard FSDP di efsdp. Mereka selalu dibungkus FSDP, sehingga fsdp_mixed_precision dan fsdp_cpu_offload juga berlaku untuk mereka dan save_pretrained() mengumpulkannya seperti parameter lainnya.
  • Grup paralel ahli memegang ep_size / tp_size batch, sehingga gradien dari sebuah ahli adalah jumlah dari sebanyak itu batch. Reduksi efsdp membagi dengan fsdp_size alih-alih ukuran grupnya, yang menghasilkan rata-rata per-batch yang sama dengan yang diambil FSDP2 untuk modul padat.
  • Setiap pakar lokal juga memproses satu baris nol pad per lapisan. Rank yang pakarnya tidak menerima token apa pun tetap bergabung dalam reverse all-to-all dan pengurangan gradien pakar.

Bagaimana ukuran-ukuran tersebut digabungkan

  • tp_size * fsdp_size adalah jumlah proses. ep_size tidak menambah apa pun: ia hanya mengelompokkan ulang rank yang sama untuk bobot pakar saja.
  • ep_size memotong daftar expert menjadi ep_size blok. Setiap rank menghitung num_experts / ep_size expert, dan ep_size rank berurutan memegang satu set lengkap. Set rank tersebut adalah grup tempat all-to-all dijalankan.
  • efsdp_size = fsdp_size * tp_size / ep_size adalah jumlah salinan lengkap dari set expert. Rank pada posisi yang sama di salinan yang berbeda melakukan sharding terhadap expert tersebut untuk memori dan merata-ratakan gradien mereka, seperti yang dilakukan FSDP untuk modul dense.
  • Batch yang dipegang oleh sebuah rank hanya bergantung pada fsdp. Rank-rank yang berurutan membentuk grup TP dan menerima batch yang sama; grup-grup fsdp_size menerima batch yang berbeda.

Delapan proses, tp_size=2, fsdp_size=4, delapan ahli:

rank         0      1       2      3       4      5       6      7
batch       [====B0====]   [====B1====]   [====B2====]   [====B3====]     one batch per TP pair
tp           0      1       0      1       0      1       0      1

ep_size=2   E0-3   E4-7    E0-3   E4-7    E0-3   E4-7    E0-3   E4-7     group = a TP pair,   efsdp_size=4
ep_size=4   E0E1   E2E3    E4E5   E6E7    E0E1   E2E3    E4E5   E6E7     group = two pairs,   efsdp_size=2
ep_size=8   E0     E1      E2     E3      E4     E5      E6     E7       group = all ranks,   efsdp_size=1

Dua angka dapat disimpulkan dari gambar:

  • Di dalam grup EP, setiap token ada tp_size kali, satu kali per rank dari pasangan yang memegang batch-nya. Hal ini tidak bergantung pada ep_size.
  • Grup EP memegang ep_size / tp_size batch yang berbeda. Ini adalah jumlah yang dijumlahkan oleh gradien seorang expert.

Dengan paralelisme tensor

Setel tp_size > 1 untuk memecah modul padat dengan rencana TP, sementara para ahli menggunakan dispatch. Pada delapan proses:

distributed_config = DistributedConfig(
    tp_size=2,
    fsdp_size=4,
    ep_size=4,
)

Setiap pasangan rank TP menerima batch yang sama, karena paralelisme tensor mereplikasi aktivasi di dalam pasangan tersebut. Jika kedua rank mendispatch semua token mereka, rank yang memiliki sebuah expert akan menerima setiap token dua kali, menghitungnya dua kali, dan gradien bobotnya akan menjadi dua kali lipat. Expert utuh berada di satu rank, sehingga duplikat tidak dapat dipecah berdasarkan bobot, dan pemiliknya biasanya adalah rank lain, sehingga tidak dapat diselesaikan berdasarkan kepemilikan seperti yang dilakukan masking. Oleh karena itu, pasangan tersebut membagi baris: setiap rank TP mendispatch 1 / tp_size token yang tidak tumpang tindih, hasil kembali ke rank yang mengirimkannya, dan all-reduce di atas pasangan dari separuh yang di-nolkan memulihkan output yang direplikasi yang diharapkan oleh lapisan berikutnya. Pembagian dilakukan berdasarkan tp_size, bukan ep_size, karena hanya rank yang memegang batch yang dapat mengirimkannya. Grup expert membentang di empat rank dan setiap expert di-shard FSDP di efsdp_size = 2 rank, sementara grup FSDP trunk membentang di empat rank. Kendala TP biasa dari model, seperti keterbagian kepala perhatian, masih berlaku untuk modul padat. Irisan token mungkin tidak rata atau kosong, termasuk selama decoding token tunggal.

Token dispatch belum dapat dikombinasikan dengan pipeline parallelism; gunakan pp_size=1 (belum diuji) Konfigurasi ini masing-masing menggunakan delapan GPU:

KonfigurasiHasil
DistributedConfig(tp_size=4, fsdp_size=2, ep_size=4)Dispatch dengan grup TP berukuran empat, di mana masing-masing memotong batch-nya menjadi empat (rencana default); kecuali Anda menentukan ep_plan untuk menggunakan EP bermasker lama
DistributedConfig(tp_size=1, fsdp_size=8, ep_size=4)Dispatch dengan batch independen di setiap rank, tanpa slicing, dan para ahli yang di-shard FSDP di antara pasangan rank.
DistributedConfig(tp_size=2, fsdp_size=4, ep_size=4)Dispatch dengan satu pasangan TP per batch, di mana setiap pasangan memotong batch-nya menjadi dua; dua batch per grup ahli.
DistributedConfig(tp_size=8, ep_size=8)Dispatch dengan setiap rank berbagi satu batch, dipotong menjadi delapan, atau masking dan all-reduce untuk rencana yang dimasking.

Trainer belum memperhitungkan dispatch token: penghitungan batch dan token mengasumsikan tata letak all-reduce, di mana rank dari grup TP berbagi satu batch dan terdapat fsdp_size shard data-parallel. Dukungan Trainer untuk dispatch akan hadir pada pembaruan berikutnya.

Menggabungkan dengan FSDP2

Tensor dan expert parallelism memecah bobot di sepanjang tp, tetapi state optimizer dan modul tanpa aturan masih direplikasi di setiap rank dalam grup, yang membatasi seberapa besar model yang dapat dilatih. Tambahkan FSDP2 pada dimensi mesh kedua dengan fsdp_size. Dengan masking dan all-reduce, pertahankan ep_size=tp_size dan lewati `ep_plan={“layers..mlp.gate”: “ep_router”, “layers..mlp.experts”: “moe_tp_experts”}“.

from transformers import AutoModelForCausalLM
from transformers.distributed import DistributedConfig

distributed_config = DistributedConfig(
    tp_size=4,
    ep_size=4,  # expert parallel size, must match tp_size with masking and all-reduce
    fsdp_size=2,  # data parallel shards
    ep_plan={
        "model.layers.*.mlp.gate": "ep_router",
        "model.layers.*.mlp.experts": "moe_tp_experts",
    },
)
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-30B-A3B", distributed_config=distributed_config)

Muat model seperti biasa, lalu latih dengan Trainer. Proses ini mengambil norma gradien di kedua mesh dan memberikan grup parameter optimizer yang terpisah untuk masing-masing mesh. save_model() mengumpulkan bobot yang di-shard menjadi checkpoint reguler. Hal ini memerlukan accelerate>=1.12 agar Trainer dapat mencerminkan tp_size dan fsdp_size ke dalam ~Accelerate.ParallelismConfig.

Tabel di bawah ini membandingkan pelatihan EP-only dengan 2D EP+FSDP2 pada 8xH100 GPU. Beban kerja adalah fine-tuning penuh Qwen3-30B-A3B dalam bf16 pada panjang sekuens 2048. Semakin banyak shard FSDP, semakin rendah memori puncak, dan tokens/s turun sedikit karena FSDP2 melakukan all-gathers dan reduce-scatters para ahli di seluruh fsdp.

konfigurasitokens/s/GPUmemori puncak/GPU
tp_size=8348538,6 GB
tp_size=4, fsdp_size=2290034,2 GB
tp_size=2, fsdp_size=4283032,3 GB

Melanjutkan dari checkpoint belum didukung untuk model yang di-shard saat dimuat, sehingga Trainer hanya menerima save_only_model=True atau save_strategy="no" untuk model tersebut.

Referensi API

kelas transformers.DistributedConfig

< >

( tp_size: int | None = Nonetp_plan: typing.Union[dict[str, str], typing.Literal['auto'], NoneType] = Noneenable_sequence_parallel: bool = Falseenable_expert_parallel: bool = Falsefsdp_size: int | None = Nonefsdp_plan: dict[str, str] | None = Nonefsdp_cpu_offload: bool = Falsefsdp_mixed_precision: bool = Falsepp_size: int | None = Noneep_size: int | None = Noneep_plan: dict[str, str] | None = None )

Parameter

  • tp_size (int, opsional) — Jumlah perangkat untuk tensor parallelism. Jika None dan tp_plan diset, defaultnya adalah WORLD_SIZE // (other_parallel_size). Jika None dan tidak ada tp_plan yang diset, defaultnya adalah 1.
  • tp_plan (dict[str, str] atau "auto", opsional) — Rencana sharding paralel tensor. Berikan "auto", atau biarkan sebagai None ketika tp_size disetel, untuk menggunakan base_model_tp_plan yang telah didefinisikan sebelumnya pada model. Berikan kamus untuk menimpa aturan individual dari rencana tersebut; aturan yang tidak ditentukan akan dipertahankan. Kamus kosong tidak menerapkan aturan paralel tensor apa pun.
  • enable_sequence_parallel (bool, opsional, default False) — Ditentukan untuk sequence parallelism. Belum diintegrasikan.
  • enable_expert_parallel (bool, opsional, default False) — Tidak lagi didukung, dihapus di v5.21. Tanpa ep_size, sama dengan ep_size=tp_size, tp_plan={}: rencana expert-parallel saja di seluruh tp_size rank. Nilai ep_size yang eksplisit memiliki prioritas. Flag ini tidak mengubah tp_size atau fsdp_size.
  • fsdp_size (int, opsional) — Jumlah perangkat untuk FSDP (paralelisme data). Jika None dan tp_size diatur, defaultnya adalah 1.
  • fsdp_plan (dict[str, str], opsional) — Rencana sharding FSDP2. Biarkan sebagai None untuk menggunakan base_model_fsdp_plan yang telah ditentukan sebelumnya pada model dan _fsdp_plan pada level kelas. Lewatkan sebuah kamus untuk menimpa aturan individual; aturan yang tidak ditentukan akan dipertahankan. Hanya diterapkan ketika fsdp_size > 1.
  • fsdp_cpu_offload (bool, opsional, default False) — Apakah akan mengaktifkan CPU offloading untuk FSDP2.
  • fsdp_mixed_precision (bool, opsional, default False) — Apakah akan mengaktifkan presisi campuran untuk FSDP2.
  • pp_size (int, opsional) — Jumlah perangkat untuk pipeline parallelism. Jika None dan mode paralel lain diatur, defaultnya adalah 1.
  • ep_size (int, opsional) — Jumlah perangkat yang memiliki shard expert yang berbeda. Nilainya secara default adalah 1. Tetapkan secara eksplisit untuk mengaktifkan EP. Harus menjadi kelipatan dari tp_size dan membagi fsdp_size * tp_size. Rencana all-reduce expert membutuhkan ep_size=tp_size; token dispatch ("ep_dispatch_experts") juga mengizinkan ep_size > tp_size.
  • ep_plan (dict[str, str], opsional) — Rencana sharding paralelisme pakar. Biarkan sebagai None untuk menggunakan base_model_ep_plan yang telah didefinisikan sebelumnya pada model. Teruskan kamus untuk menimpa aturan individual dari rencana tersebut; aturan yang tidak ditentukan akan dipertahankan. Diterapkan hanya ketika ep_size > 1, dan aturannya memiliki prioritas lebih tinggi daripada aturan tp_plan untuk modul yang sama. Aturan "ep_dispatch_experts" memilih dispatch token all-to-all alih-alih masking router dan all-reduce.

Konfigurasi untuk inferensi dan pelatihan terdistribusi native dengan paralelisme tensor, pipeline, atau FSDP2.

Update on GitHub