Transformers documentation
Paralelisme pakar
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. Model MoE memecah pakarnya dengan "ep_dispatch_experts". Implementasinya menentukan bagaimana token mencapai para pakar. Token dispatch memungkinkan ep_size berbeda dari tp_size. Beberapa implementasi EP mengharuskan ep_size=tp_size, misalnya "all_reduce" dan "deepgemm_megamoe", sehingga setiap rank dalam grup pakar memegang token yang sama.
Llama 4 tidak memiliki rencana EP: para ekspertnya mengambil setiap token yang sudah diskalakan oleh skor router-nya, sehingga tidak ada yang perlu didispatch. Pecah mereka dengan tensor parallelism (tp_size) sebagai gantinya.
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 tensor parallel memecah perhatian dan MLP padat, sedangkan rencana expert parallel 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 aturan "ep_dispatch_experts" pada modul ahli menentukan bagaimana token mencapai mereka.
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.
"ep_dispatch_experts" membagi seluruh ahli per rank (ep_size adalah kelipatan dari tp_size yang membagi fsdp_size * tp_size) dan mengaksesnya melalui implementasi yang dinamakan oleh ep_implementation, lihat Memilih implementasi.
Memilih implementasi
"ep_dispatch_experts" memecah para ahli sekali dan memilih cara token mencapai mereka dari implementasi yang terdaftar di EPImplementationInterface, yang dipilih dengan ep_implementation di DistributedConfig:
ep_implementation | keuntungan | kekurangan |
|---|---|---|
"all_to_all", lihat penyaluran token | Berfungsi untuk tata letak apa pun, termasuk ep_size > tp_size. Hanya token yang di-rutekan yang berpindah. | Dua kolektif all-to-all dan satu sinkronisasi host per lapisan, sehingga tidak dapat ditangkap dalam grafik CUDA. |
"all_reduce" | Tidak ada token yang berpindah dan tidak ada sinkronisasi host, sehingga decode dapat ditangkap dalam grafik CUDA. | Memerlukan ep_size=tp_size. Setiap rank menjalankan expert-nya di seluruh batch, sehingga biayanya meningkat seiring dengan batch. |
"deepgemm_megamoe" | DeepGEMM Mega MoE menggabungkan dispatch, para expert, dan combine dalam satu kernel. Setiap layer dalam grup EP berbagi buffer memori simetrisnya. | Memerlukan ep_size=tp_size, dan aktivasi FP8 dengan pakar FP4 pada SM100+. Hanya untuk inferensi. |
"auto", nilai default | Menjalankan "all_reduce" saat inferensi ketika rank dari grup ahli berbagi satu batch, dan "all_to_all" selain itu. | Tidak selalu menjadi pilihan tercepat: beban kerja dapat diuntungkan dari implementasi kustom, lihat Menambahkan implementasi. |
ep_implementationhanya memilih di antara ukuran paralel yang diatur dalam DistributedConfig. Ketika rank dari sebuah grup ahli memegang batch yang berbeda, misalnyatp_size=1denganfsdp_size=ep_size,"all_to_all"adalah satu-satunya implementasi yang berlaku.
Menambahkan implementasi
Implementasi mewarisi EPImplementation dan terdaftar di bawah nama yang dipilih oleh ep_implementation. Ia dibangun sekali per modul pakar, sehingga dapat menyimpan state seperti buffer komunikasi. Memanggilnya dengan batch yang dipegang oleh rank ini, beserta id pakar global, mengembalikan output pakar berbobot untuk masing-masing tokennya. Ia menjalankan pakar milik rank ini dengan experts_forward, pada baris, id pakar lokal, dan bobot yang dibawanya.
from transformers.distributed.expert_parallel import EPImplementation, EPImplementationInterface
class MyEP(EPImplementation):
def __call__(self, hidden_states, top_k_index, top_k_weights):
tokens, expert_ids, weights = ... # bring this rank's experts the rows routed to them
expert_output = self.experts_forward(tokens, expert_ids, weights)
return ... # the weighted expert output for each token of the batch this rank holds
EPImplementationInterface.register("my_ep", MyEP)
distributed_config = DistributedConfig(tp_size=1, fsdp_size=8, ep_size=8, ep_implementation="my_ep")Gradien harus mencapai setiap rank yang memegang token, termasuk bobot routing, sehingga bungkus kolektif yang tidak didiferensiasi oleh autograd dalam
torch.autograd.Function.
enable_expert_parallel=Truetanpaep_sizesudah tidak didukung dan mengeluarkanFutureWarning. Ini hanya memecah para ahli, sepertiep_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.
Dengan ep_size=tp_size, implementasi default "auto" menjalankan "all_reduce" saat inferensi dan mendistribusikan token saat pelatihan. Untuk melakukan masking dan all-reduce juga saat pelatihan, atur ep_implementation="all_reduce":
distributed_config = DistributedConfig(tp_size=4, ep_size=4, ep_implementation="all_reduce")Token dispatch
Token dispatch adalah implementasi "all_to_all": setiap rank melatih pada bagian batch-nya sendiri. Di setiap lapisan MoE, sebuah rank merutekan tokennya, mengirim setiap pasangan (token, expert) ke rank yang memiliki expert tersebut dengan all-to-all, menjalankan expert lokalnya pada apa yang diterimanya, mendapatkan hasilnya kembali dengan 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
epdan, ketikaefsdp_size = fsdp_size * tp_size // ep_sizelebih besar dari satu, juga di-shard FSDP diefsdp. Mereka selalu dibungkus FSDP, sehinggafsdp_mixed_precisiondanfsdp_cpu_offloadjuga berlaku untuk mereka dan save_pretrained() mengumpulkannya seperti parameter lainnya. - Grup paralel ahli memegang
ep_size / tp_sizebatch, sehingga gradien dari sebuah ahli adalah jumlah dari sebanyak itu batch. Reduksiefsdpmembagi denganfsdp_sizealih-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_sizeadalah jumlah proses.ep_sizetidak menambah apa pun: ia hanya mengelompokkan ulang rank yang sama untuk bobot pakar saja.ep_sizememotong daftar expert menjadiep_sizeblok. Setiap rank menghitungnum_experts / ep_sizeexpert, danep_sizerank berurutan memegang satu set lengkap. Set rank tersebut adalah grup tempat all-to-all dijalankan.efsdp_size = fsdp_size * tp_size / ep_sizeadalah 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-grupfsdp_sizemenerima 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_sizekali, satu kali per rank dari pasangan yang memegang batch-nya. Hal ini tidak bergantung padaep_size. - Grup EP memegang
ep_size / tp_sizebatch 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:
| Konfigurasi | Hasil |
|---|---|
DistributedConfig(tp_size=4, fsdp_size=2, ep_size=4) | Setiap grup TP berisi empat rank berbagi satu batch. Pelatihan mendistribusikan token, di mana setiap rank mengambil seperempat dari batch; inferensi menggunakan "all_reduce"; pengaturan ep_implementation="all_reduce" menggunakannya di seluruh proses. |
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) | Setiap rank berbagi satu batch. Pelatihan mendistribusikan token, di mana setiap rank mengambil seperdelapan dari batch; inferensi menggunakan "all_reduce"; pengaturan ep_implementation="all_reduce" menggunakannya di seluruh proses. |
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_sizeshard data-parallel. Dukungan Trainer untuk dispatch akan hadir pada pembaruan berikutnya.
Menggabungkan dengan FSDP2
Tensor dan expert parallelism membagi (shard) bobot di atas mesh mereka sendiri, tp dan ep, tetapi state optimizer dan modul tanpa aturan masih direplikasi di setiap rank dari grup tersebut, yang membatasi seberapa besar model yang dapat dilatih. Tambahkan FSDP2 pada dimensi mesh lain dengan fsdp_size. Dengan masking dan all-reduce, pertahankan ep_size=tp_size dan lewati ep_implementation="all_reduce".
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_implementation="all_reduce", # "auto" would dispatch tokens in training, which the Trainer does not support yet
)
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.
| konfigurasi | tokens/s/GPU | memori puncak/GPU |
|---|---|---|
tp_size=8 | 3485 | 38,6 GB |
tp_size=4, fsdp_size=2 | 2900 | 34,2 GB |
tp_size=2, fsdp_size=4 | 2830 | 32,3 GB |
Melanjutkan dari checkpoint belum didukung untuk model yang di-shard saat dimuat, sehingga Trainer hanya menerima
save_only_model=Trueatausave_strategy="no"untuk model tersebut.
Referensi API
kelas transformers.DistributedConfig
< source >( 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 = Nonedp_replicate_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 = Noneep_implementation: str = 'auto' )
Parameter
- tp_size (
int, opsional) — Jumlah perangkat untuk tensor parallelism. JikaNonedantp_plandiset, defaultnya adalahWORLD_SIZE // (other_parallel_size). JikaNonedan tidak adatp_planyang diset, defaultnya adalah 1. - tp_plan (
dict[str, str]atau"auto", opsional) — Rencana sharding paralel tensor. Berikan"auto", atau biarkan sebagaiNoneketikatp_sizedisetel, untuk menggunakanbase_model_tp_planyang 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, defaultFalse) — Ditentukan untuk sequence parallelism. Belum diintegrasikan. - enable_expert_parallel (
bool, opsional, defaultFalse) — Tidak lagi didukung, dihapus di v5.21. Tanpaep_size, sama denganep_size=tp_size, tp_plan={}: rencana expert-parallel saja di seluruhtp_sizerank. Nilaiep_sizeyang eksplisit memiliki prioritas. Flag ini tidak mengubahtp_sizeataufsdp_size. - fsdp_size (
int, opsional) — Jumlah perangkat untuk FSDP (paralelisme data). JikaNonedantp_sizediatur, defaultnya adalah 1. - dp_replicate_size (
int, opsional) — Jumlah replika FSDP (HSDP). Parameter di-shard di antarafsdp_sizeperangkat dan direplikasidp_replicate_sizekali: gradien di-reduce-scatter di dalam sebuah replika, kemudian di-all-reduce di antara replika. Nilai default adalah 1. Kami menyarankan ini untuk pelatihan multi-node: FSDP biasa melakukan all-gather parameter dan reduce-scatter gradien di antara semua perangkat pada setiap langkah, sehingga lalu lintas ini melewati link inter-node yang lebih lambat. Aturdp_replicate_sizeke jumlah node danfsdp_size * tp_sizeke jumlah perangkat per node: lalu lintas sharding kemudian tetap berada di link intra-node yang cepat, dan hanya all-reduce gradien yang menyeberangi antar node. Biayanya adalah lebih banyak memori per perangkat, karena parameter di-shard di dalam sebuah node. - fsdp_plan (
dict[str, str], opsional) — Rencana sharding FSDP2. Biarkan sebagaiNoneuntuk menggunakanbase_model_fsdp_planyang telah ditentukan sebelumnya pada model dan_fsdp_planpada level kelas. Teruskan sebuah kamus untuk menimpa aturan individual; aturan yang tidak ditentukan akan dipertahankan. Diterapkan hanya ketikadp_replicate_size * fsdp_size > 1. - fsdp_cpu_offload (
bool, opsional, defaultFalse) — Apakah akan mengaktifkan CPU offloading untuk FSDP2. - fsdp_mixed_precision (
bool, opsional, defaultFalse) — Apakah akan mengaktifkan presisi campuran untuk FSDP2. - pp_size (
int, opsional) — Jumlah perangkat untuk pipeline parallelism. JikaNonedan mode paralel lain diatur, defaultnya adalah 1. - ep_size (
int, opsional) — Jumlah perangkat yang memiliki shard expert yang berbeda. Defaultnya adalah 1. Tetapkan secara eksplisit untuk mengaktifkan EP. Harus menjadi kelipatan daritp_sizedan membagifsdp_size * tp_size.ep_size > tp_sizememerlukan aturan"ep_dispatch_experts"denganep_implementationyang menukar token, seperti"all_to_all". - ep_plan (
dict[str, str], opsional) — Rencana sharding paralelisme ahli. Biarkan sebagaiNoneuntuk menggunakanbase_model_ep_planyang telah didefinisikan sebelumnya pada model. Teruskan kamus untuk menimpa aturan individual dari rencana tersebut; aturan yang tidak ditentukan akan dipertahankan. Diterapkan hanya ketikaep_size > 1, dan aturannya memiliki prioritas lebih tinggi daripada aturantp_planuntuk modul yang sama. Aturan"ep_dispatch_experts"memungkinkanep_implementationmemilih bagaimana token mencapai para ahli. - ep_implementation (
str, opsional, default ke"auto") — Bagaimana aturan"ep_dispatch_experts"mengirimkan token ke para expert. Ini menamai sebuahEPImplementationyang terdaftar diEPImplementationInterface:"all_to_all"menukar token yang di-rutekan dengan kolektif all-to-all."all_reduce"menjalankan para ahli dari setiap rank pada batch yang dibagikan oleh grup EP, lalu menjumlahkan outputnya. Ini memerlukanep_size == tp_size."deepgemm_megamoe"menyerahkan batch tersebut ke DeepGEMM Mega MoE, yang kernel-nya menukar token secara mandiri. Memuat denganexperts_implementation="deepgemm_megamoe"memilihnya."auto"menjalankan"all_reduce"saat inferensi jika grup EP berbagi satu batch, dan"all_to_all"jika tidak.
Konfigurasi untuk inferensi dan pelatihan terdistribusi native dengan paralelisme tensor, pipeline, atau FSDP2.