Transformers documentation
Uzman paralelliği
Uzman paralelliği
Uzman paralelliği, mixture-of-experts (MoE) modelleri için bir paralellik stratejisidir. Her uzmanın ileri besleme katmanı farklı bir donanım hızlandırıcısında bulunur. Bir yönlendirici, token'ları uygun uzmanlara yönlendirir ve sonuçları toplar. Her token yalnızca birkaç uzmanı etkinleştirdiği için bu yaklaşım, hesaplama maliyetini artırmadan modelleri çok daha büyük parametre sayılarına ölçeklendirir.
DistributedConfig
DistributedConfig sınıfını ve ep_size argümanını kullanarak uzman paralelliğini etkinleştirin. Çoğu MoE modeli varsayılan olarak token dispatch kullanır, bu nedenle ep_size, tp_size'dan bağımsız olarak ayarlanabilir. Llama 4 ve Gemma 4 gibi birkaç model ise hâlâ varsayılan olarak maskeleme ve all-reduce kullanır (model.ep_plan içinde "ep_router" ve "moe_tp_experts"). Maskeleme, bir ep_plan geçersiz kılmasına sahip herhangi bir modelde de kullanılabilir ve bir uzman grubundaki her rank'ın aynı token'ları alabilmesi için ep_size=tp_size gerektirir.
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,
)Her MoE modeli, config dosyasında iki plan tanımlar: yoğun modüller için base_model_tp_plan ve uzmanlar için base_model_ep_plan. Bunlar yüklenen modelde model.tp_plan ve model.ep_plan olarak erişilebilir. tp_size > 1 ve ep_size > 1 olduğunda her ikisi de geçerlidir: tensor parallel planı dikkat (attention) ve yoğun MLP'leri parçalar (shard), uzman paralel planı ise uzmanları parçalar. Aynı modüller için EP kuralları TP kurallarına önceliklidir, bu nedenle uzman ağırlıkları yalnızca EP planı tarafından bir kez parçalanır. EP planında, GroupedGemmParallel stili uzman ağırlıklarını uzman boyutu boyunca böler, böylece her rank yalnızca yerel uzmanlarını yükler ve ep_router, all-reduce işlemi uzman çıktıları birleştirilmeden önce diğer ranklarda bulunan uzmanları maskele (mask) işlemini uygular.
tp_plan yalnızca tp_size > 1 olduğunda, ep_plan ise yalnızca ep_size > 1 olduğunda uygulanır. TP etkin ve EP devre dışı olduğunda, uzman kuralları dahil olmak üzere tam TP planı uygulanır.
ep_plan içindeki uzman ileri kuralı, jetonların uzmanlara nasıl ulaştığını seçer:
| kural | mekanizma | yerleşim |
|---|---|---|
Router üzerinde "moe_tp_experts" ile "ep_router" | maskleme ve all-reduce: her rank, tüm batch üzerinde yerel uzmanlarını çalıştırır, router diğerlerini maskelemeye alır ve bir all-reduce çıktıları birleştirir | ep_size=tp_size |
"ep_dispatch_experts" | token dağıtımı: her rank kendi token'larını tutar ve yalnızca yönlendirilen (token, expert) çiftlerini iki all-to-all kolektifiyle değiştirir | ep_size, fsdp_size * tp_size değerini bölen ve tp_size'in bir katı olan |
enable_expert_parallel=True,ep_sizeolmadan kullanıldığında artık desteklenmemektedir ve birFutureWarningüretir. Bu ayar, yalnızca uzmanları parçalar; tıpkıep_size=tp_size, tp_plan={}yapılandırmasında olduğu gibi.
Çıkarım betiğinizi torchrun ile başlatın. İşlem sayısı tp_size * fsdp_size * pp_size değerine eşit olmalı ve ep_size, uzman sayısını tam olarak bölmelidir.
torchrun --nproc-per-node 8 your_script.py
Planların üzerine yazılması
tp_plan={...} veya ep_plan={...} değerlerini DistributedConfig sınıfına geçirerek önceden tanımlanmış planların bireysel kurallarını geçersiz kılabilirsiniz. Belirtilmeyen kurallar korunur ve birleştirilen planlar modele kaydedilir. Her anahtar, bir modül, bir parametre veya mevcut bir plan girdisiyle eşleşmelidir; aksi takdirde herhangi bir şey bölümlenmeden önce yükleme işlemi ValueError hatası verir. Tam yolu, yüklü modelin gördüğü şekilde kullanın; bu nedenle bir nedensel LM için model.layers.*, temel modeli için ise layers.* kullanın.
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"},
)Bir plan sağlanmak, paralel boyutları çıkarım yapmaz: tp_size ve ep_size değerlerini açıkça belirleyin.
Çoğu MoE modeli varsayılan olarak "ep_dispatch_experts" kullanır. Bunun yerine maskeleme ve all-reduce kullanmak için ep_size=tp_size değerini ayarlayın ve hem router hem de uzman ileri (forward) kurallarını geçersiz kılın (router modül adı modele göre değişir, örneğin gpt-oss'te mlp.router):
distributed_config = DistributedConfig(
tp_size=4,
ep_size=4,
ep_plan={
"model.layers.*.mlp.gate": "ep_router",
"model.layers.*.mlp.experts": "moe_tp_experts",
},
)Buna karşılık, planı maskeleme kullanan bir modelin uzman ileri yönlü kuralını, token dağıtımı kullanmak için "ep_dispatch_experts" ile geçersiz kılın. Dağıtım, her uzmanın sahibini bulmak için küresel uzman kimliklerine ihtiyaç duyduğundan, yönlendirme kuralı bu durumda yok sayılır.
Token dağıtımı
Token dispatch ile her rank, batch'in kendi payına düşen kısmında eğitim yapar. Her MoE katmanında, bir rank token'larını yönlendirir, her (token, uzman) çiftini, o uzmanın sahibi olduğu rank'a all-to-all ile gönderir, yerel uzmanlarını aldıkları üzerinde çalıştırır, sonuçları ikinci bir all-to-all ile geri alır ve yönlendirme ağırlıklarıyla birleştirir. Yalnızca yönlendirilen aktivasyonlar ve uzman çıktıları taşınır ve hiçbir rank, sahip olmadığı token'lar için uzman hesaplama yapmaz.
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)tp_size=1 durumunda, ep_size hem fsdp_size'in hem de uzman sayısının tam bölünmesini sağlamalıdır ve dikkat mekanizması num_key_value_heads ile sınırlı değildir. Modelin geri kalanı için:
- Uzmanların dışındaki parametreler,
fsdpüzerinde FSDP2 ile parçalanır ve bu da onların gradyanlarını azaltır. - Uzmanlar
epüzerinde parçalanır veefsdp_size = fsdp_size * tp_size // ep_sizebirinden büyük olduğunda, ayrıcaefsdpüzerinde FSDP ile parçalanır. Her zaman FSDP ile sarılı olduklarından,fsdp_mixed_precisionvefsdp_cpu_offloadonlara da uygulanır ve save_pretrained() onları diğer herhangi bir parametre gibi toplar. - Uzman paralel bir grup
ep_size / tp_sizeparti tutar, bu nedenle bir uzmanın gradyanı bu kadar partinin toplamıdır.efsdpindirgeme işlemi, grup boyutu yerinefsdp_sizedeğerine böler; bu da FSDP2'nin yoğun modüller için kullandığı parti başına ortalama ile aynı sonucu verir. - Her yerel uzman, katman başına bir sıfır dolgu satırını da işler. Uzmanları tarafından hiçbir token alınmayan bir sıralama, yine de reverse all-to-all ve uzman gradyan indirgeme işlemlerine katılır.
Boyutların nasıl birleştiği
tp_size * fsdp_size, işlem sayısıdır.ep_sizehiçbir şey eklemez: yalnızca uzman ağırlıkları için aynı sıraları yeniden gruplar.ep_size, uzman listesiniep_sizebloğa böler. Her ranknum_experts / ep_sizeuzman hesaplar veep_sizeardışık rank bir tam seti barındırır. Bu rank grubu, all-to-all'ın çalıştığı gruptur.efsdp_size = fsdp_size * tp_size / ep_size, uzman kümesinin kaç tam kopyasının var olduğunu belirtir. Farklı kopyalarda aynı konumdaki rank'lar, FSDP'nin yoğun modüller için yaptığı gibi, bu uzmanları bellek için parçalara ayırır ve gradyanlarını ortalama alır.- Bir rank'ın tuttuğu batch yalnızca
fsdp'ye bağlıdır. Ardışık rank'lar bir TP grubu oluşturur ve aynı batch'i alır;fsdp_sizegrupları farklı batch'ler alır.
Sekiz süreç, tp_size=2, fsdp_size=4, sekiz uzman:
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
Şekilden iki sonuç çıkar:
- Bir EP grubunun içinde, her token, kendi batch'ini tutan çiftin rank'ı başına bir kez olmak üzere
tp_sizekez var olur. Bu,ep_size'dan bağımsızdır. - Bir EP grubu
ep_size / tp_sizefarklı batch tutar. Bu, bir uzmanın gradyanlarının üzerinde toplandığı sayıdır.
Tensor paralelliği ile
Yoğun modülleri TP planıyla parçalara ayırmak için tp_size > 1 değerini ayarlayın; uzmanlar ise dispatch kullanır. Sekiz işlemde:
distributed_config = DistributedConfig(
tp_size=2,
fsdp_size=4,
ep_size=4,
)Her TP rank çifti aynı batch’i alır, çünkü tensor paralelliği çiftin içindeki aktivasyonları kopyalar. Her iki rank da tüm token’larını dağıttıysa, bir uzmanı (expert) barındıran rank her token’ı iki kez alır, iki kez hesaplar ve ağırlık gradyanı ikiye katlanır. Uzmanlar tek bir rank üzerinde bütündür, bu nedenle kopya ağırlıklar üzerinden bölünemez ve sahibi genellikle başka bir rank olduğu için, masking’de olduğu gibi sahiplik üzerinden de çözülemez. Çift bu nedenle satırları böler: her TP rank, token’ların ayrık 1 / tp_size’ını dağıtır, sonuçlar gönderen rank’a geri döner ve sıfır dolgulu yarıların çift üzerinde all-reduce’ı, bir sonraki katmanın beklediği kopyalanmış çıktıyı geri getirir. Bölme tp_size üzerinden yapılır, ep_size üzerinden değil, çünkü yalnızca bir batch tutan rank’lar onu gönderebilir. Uzman grupları dört rank’ı kapsar ve her uzman, efsdp_size = 2 rank arasında FSDP ile bölünürken, gövdenin (trunk) FSDP grubu dört rank’ı kapsar. Modelin olağan TP kısıtlamaları, örneğin dikkat başlarının bölünebilirliği, yoğun (dense) modüller için hâlâ geçerlidir. Token dilimleri eşitsiz veya boş olabilir, tek token çözümlendirme sırasında da dahil.
Token dispatch henüz pipeline paralelliğiyle birleştirilemez; pp_size=1 kullanın (henüz test edilmedi)
Bu yapılandırmaların her biri sekiz GPU kullanır:
| Yapılandırma | Sonuç |
|---|---|
DistributedConfig(tp_size=4, fsdp_size=2, ep_size=4) | Dört TP grubuyla dağıtın, her biri kendi batch'ini dört parçaya bölsün (varsayılan plan); aksi takdirde, eski masked EP'yi kullanmak için bir ep_plan belirtin |
DistributedConfig(tp_size=1, fsdp_size=8, ep_size=4) | Her rank üzerinde bağımsız bir batch ile dispatch, dilimleme olmadan ve uzmanların rank çiftleri arasında FSDP ile paylaştırılması. |
DistributedConfig(tp_size=2, fsdp_size=4, ep_size=4) | Her batch için bir TP çiftiyle dağıtın; her çift kendi batch'ini ikiye bölsün; her uzman grubu için iki batch. |
DistributedConfig(tp_size=8, ep_size=8) | Her rank'in tek bir batch'i paylaşarak sekize bölündüğü dispatch veya maskeli bir plan için masking ve all-reduce. |
Trainer henüz token dağıtımını hesaba katmıyor: batch ve token sayımı, bir TP grubundaki rank'lerin bir batch'i paylaşması ve
fsdp_sizeadet veri paralel diliminin var olduğu all-reduce yerleşimini varsayar. Trainer'ın dağıtıma desteği bir sonraki aşamada eklenecek.
FSDP2 ile birleştirme
Tensor ve uzman paralelliği ağırlıkları tp üzerinde parçalara ayırır, ancak optimizör durumu ve bir kuralı olmayan modüller, grubun her sıralamasında (rank) hâlâ kopyalanır; bu da eğitebileceğiniz modelin boyutunu sınırlar. fsdp_size ile ikinci bir mesh boyutunda FSDP2 ekleyin. Masking ve all-reduce ile ep_size=tp_size değerini koruyun ve `ep_plan={“layers..mlp.gate”: “ep_router”, “layers..mlp.experts”: “moe_tp_experts”}“` parametresini iletin.
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)Modeli normal şekilde yükleyin, ardından Trainer ile eğitim yapın. Gradyan normunu her iki mesh üzerinden alır ve her mesh'e kendi optimizer param grubunu verir. save_model(), parçalı ağırlıkları düzenli bir checkpoint'e toplar. Bunun için Trainer'ın tp_size ve fsdp_size değerlerini ~Accelerate.ParallelismConfig'e yansıtabilmesi gerektirdiğinden accelerate>=1.12 sürümü gereklidir.
Aşağıdaki tablo, 8xH100 GPU'larda yalnızca EP ile eğitimi, 2B EP+FSDP2 ile karşılaştırır. İş yükü, 2048 dizi uzunluğunda bf16'da Qwen3-30B-A3B'nin tam ince ayarıdır. Daha fazla FSDP parçası tepe belleği keser ve FSDP2 uzmanları fsdp üzerinden all-gather ve reduce-scatter yaptığı için token/s biraz düşer.
| yapılandırma | tokens/s/GPU | tepe bellek/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 |
Yükleme sırasında parçalanan modeller için kontrol noktasından devam etme henüz desteklenmediğinden, Trainer bu modeller için yalnızca
save_only_model=Trueveyasave_strategy="no"değerlerini kabul eder.
API referansı
sınıf 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 = 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 )
Parametreler
- tp_size (
int, isteğe bağlı) — Tensor paralelliği için cihaz sayısı.Nonevetp_planayarlanmışsa, varsayılan olarakWORLD_SIZE // (other_parallel_size)değerini alır.Nonevetp_planayarlanmamışsa, varsayılan olarak 1 değerini alır. - tp_plan (
dict[str, str]veya"auto", isteğe bağlı) — Tensor paralel parçalama planı.tp_sizeayarlandığında"auto"geçirin veyaNoneolarak bırakın, böylece modelin önceden tanımlıbase_model_tp_plankullanılır. Bu plandaki bireysel kuralları geçersiz kılmak için bir sözlük geçirin; belirtilmeyen kurallar korunur. Boş bir sözlük hiçbir tensor paralel kuralı uygulamaz. - enable_sequence_parallel (
bool, isteğe bağlı, varsayılanFalse) — Sıralı paralellik için ayrılmıştır. Henüz bağlanmamıştır. - enable_expert_parallel (
bool, isteğe bağlı, varsayılanFalse) — Kullanımdan kaldırıldı, v5.21'de kaldırıldı.ep_sizeolmadan,ep_size=tp_size, tp_plan={}ile aynıdır: sadece uzman paralel planı,tp_sizesıraları arasında. Açıkça belirtilenep_sizeönceliklidir. Bu bayraktp_sizeveyafsdp_sizedeğerlerini değiştirmez. - fsdp_size (
int, isteğe bağlı) — FSDP (veri paralelliği) için cihaz sayısı.Noneise vetp_sizeayarlanmışsa, varsayılan olarak 1'dir. - fsdp_plan (
dict[str, str], isteğe bağlı) — FSDP2 parçalama planı. Modelin önceden tanımlıbase_model_fsdp_planve sınıf düzeyindeki_fsdp_plandeğerlerini kullanmak içinNoneolarak bırakın. Bireysel kuralları geçersiz kılmak için bir sözlük iletin; belirtilmeyen kurallar korunur. Yalnızcafsdp_size > 1olduğunda uygulanır. - fsdp_cpu_offload (
bool, isteğe bağlı, varsayılanFalse) — FSDP2 için CPU offloading'in etkinleştirilip etkinleştirilmeyeceği. - fsdp_mixed_precision (
bool, isteğe bağlı, varsayılanFalse) — FSDP2 için karma hassasiyetin etkinleştirilip etkinleştirilmeyeceğini belirtir. - pp_size (
int, isteğe bağlı) — Hattın paralel çalışması için kullanılan cihaz sayısı.Noneise ve başka bir paralel mod ayarlanmışsa, varsayılan olarak 1 değerini alır. - ep_size (
int, isteğe bağlı) — Farklı uzman dilimlerine sahip cihaz sayısı. Varsayılan değeri 1'dir. EP'yi etkinleştirmek için açıkça ayarlayın.tp_size'in katı olmalı vefsdp_size * tp_size'i tam bölmelidir. Uzman planları için all-reduce,ep_size=tp_sizegerektirir; token dağıtımı ("ep_dispatch_experts") ayrıcaep_size > tp_sizedeğerlerine de izin verir. - ep_plan (
dict[str, str], isteğe bağlı) — Uzman paralel parçalama planı. Modelin önceden tanımlıbase_model_ep_plan'ini kullanmak içinNoneolarak bırakın. Bu plandaki bireysel kuralları geçersiz kılmak için bir sözlük iletin; belirtilmeyen kurallar korunur. Yalnızcaep_size > 1olduğunda uygulanır ve aynı modüller içintp_plankurallarına göre önceliklidir."ep_dispatch_experts"kuralı, yönlendirici maskeleme ve tümünü indirgeme yerine tümüne-tümüne (all-to-all) token dağıtımını seçer.
Tensor, pipeline veya FSDP2 paralelliği ile yerel dağıtık çıkarım ve eğitim için yapılandırma.