perf-parallelism-strategies

Par nvidia · skills

Guide opérationnel pour choisir et combiner les stratégies de parallélisme dans Megatron Bridge, incluant les règles de dimensionnement, le mappage de topologie matérielle et la configuration du parallélisme combiné.

npx skills add https://github.com/nvidia/skills --skill perf-parallelism-strategies

Compétence Sélection de Stratégie de Parallélisme

Pour un arrière-plan stable sur chaque type de parallélisme, voir :

  • @docs/parallelisms.md
  • @skills/perf-parallelism-strategies/card.yaml

Décision par Taille de Modèle

Modèles denses

Taille du modèle GPUs Point de départ recommandé
< 1B 1-8 DP uniquement
1-10B 8-16 TP=2-4 + DP
10-70B 16-64 TP=4-8 + PP=2-4 + DP
70-175B 64-256 TP=8 + PP=4-8 + DP
175-500B 256-1024 TP=8 + PP=8-16 + CP=2 + DP

Modèles MoE

Le parallélisme MoE diffère des modèles denses. Puisque seule une fraction des paramètres est active par token, TP peut souvent rester à 1 ou 2 — le fragment de paramètre actif tient déjà sur un seul GPU. EP est la dimension d'échelle primaire, avec PP gérant la distribution des couches entre nœuds.

Modèle (total / actif) TP PP EP Notes
OLMoE 7B / 1B 1 1 8 EP uniquement, tient sur un nœud
Moonlight 16B / 3B 2 1 8 petit TP pour couches partagées
DeepSeek-V2 236B / 21B 1 4 32 pas de TP du tout
GLM-4.5 Air 106B / 12B 1 4 8 pas de TP du tout
Qwen3 30B-A3B 4 2 4
GLM-4.5 355B / 32B 2 8 16
Qwen3 235B-A22B 4 16 8 CP=2 pour préentraînement
DeepSeek-V3 671B / 37B 2 16 64 TP=2, pas 8
Kimi-K2 1T 2 16 32

Motifs clés :

  • TP est dimensionné par paramètres actifs, pas paramètres totaux. Une MoE 671B avec 37B actifs nécessite beaucoup moins de TP qu'un modèle dense 70B.
  • EP s'échelle avec le nombre d'experts. Courant : EP = num_experts ou num_experts / experts_per_gpu.
  • PP gère la profondeur. Les grands modèles MoE utilisent PP=8-16 entre nœuds.
  • ETP (expert tensor parallelism) est rarement utilisé. Llama 4 est une exception (ETP=4).

Ce sont des points de départ, pas des règles strictes. Toujours profiler la première itération pour vérifier la mémoire et la communication.

Décision par Topologie du Matériel

Nœud unique avec NVLink :

cfg.model.tensor_model_parallel_size = 8

Plusieurs nœuds avec InfiniBand :

cfg.model.tensor_model_parallel_size = 8
cfg.model.pipeline_model_parallel_size = N

Réseau limité (Ethernet) :

cfg.model.tensor_model_parallel_size = 4
cfg.model.pipeline_model_parallel_size = M

La règle stable est : garder TP dans un seul domaine NVLink. Utiliser PP ou DP pour l'échelle entre nœuds. TP entre nœuds est presque toujours une perte de performance.

Décision par Longueur de Séquence

Longueur de séquence Recommandation
< 2K TP + PP + DP standard
2K-8K ajouter SP (sequence_parallel=True)
8K-32K ajouter CP=2
32K+ ajouter CP=4-8, considérer a2a+p2p pour grand CP

Activation de Parallélisme Combiné

Parallélisme 3D (TP + PP + DP) :

cfg.model.tensor_model_parallel_size = 4
cfg.model.pipeline_model_parallel_size = 4
cfg.model.sequence_parallel = True

Parallélisme 4D (TP + PP + CP + DP) :

cfg.model.tensor_model_parallel_size = 8
cfg.model.pipeline_model_parallel_size = 8
cfg.model.context_parallel_size = 2
cfg.model.sequence_parallel = True

MoE avec EP + PP (par ex. DeepSeek-V2 236B sur 128 GPUs) :

cfg.model.tensor_model_parallel_size = 1
cfg.model.pipeline_model_parallel_size = 4
cfg.model.expert_model_parallel_size = 32
cfg.model.sequence_parallel = False

MoE avec petit TP + PP + EP (par ex. DeepSeek-V3 671B sur 256 GPUs) :

cfg.model.tensor_model_parallel_size = 2
cfg.model.pipeline_model_parallel_size = 16
cfg.model.expert_model_parallel_size = 64
cfg.model.sequence_parallel = True

La taille DP est toujours implicite :

data_parallel_size = world_size / (TP * PP * CP)        # dense path
expert_data_parallel_size = world_size / (PP * EP * ETP) # MoE path

Nombre Minimum de GPUs

Le nombre minimum de GPUs nécessaires pour exécuter une config (c.-à-d. avec DP=1, EDP=1) n'est pas le produit de toutes les dimensions de parallélisme. Le chemin dense utilise une maille TP*CP et le chemin MoE utilise une maille EP*ETP, et dans chaque étage PP ces deux mailles partagent le même ensemble de GPUs — elles se chevauchent, elles ne se multiplient pas. Seuls les étages PP se multiplient (ce sont des tranches disjointes du modèle). Donc :

min_gpus = PP * max(TP * CP, EP * ETP)

Simplification courante (FAUSSE) : PP * TP * CP * EP * ETP. Cela sur-alloue les GPUs et apparaît dans de nombreux READMEs et tables de dimensionnement slurm. Ne la propagez pas.

Le découplage du parallélisme attention et MoE (formes de maille différentes pour les chemins dense et expert partageant les mêmes GPUs d'étage PP) est détaillé dans Pangu Ultra MoE (arXiv:2504.14960).

Exemples

Config Faux (PP·TP·CP·EP·ETP) Correct (PP·max(TP·CP, EP·ETP))
PP=1, TP=2, CP=1, EP=8, ETP=1 16 8 (1 nœud)
PP=1, TP=4, CP=1, EP=8, ETP=1 32 8 (max(4, 8))
PP=1, TP=2, CP=2, EP=8, ETP=1 32 8 (max(4, 8))
PP=1, TP=2, CP=4, EP=8, ETP=1 64 8 (max(8, 8))
PP=2, TP=2, CP=1, EP=8, ETP=1 32 16 (2 · max(2, 8))
PP=1, TP=2, CP=1, EP=4, ETP=2 16 8 (max(2, 8))

Échelle au-delà du minimum

Ajouter des GPUs met à l'échelle DP et/ou EDP (le world_size doit satisfaire les deux équations simultanément). À min_gpus le côté maille plus grande a DP (ou EDP) = 1 et le côté plus petit absorbe le jeu.

Exemple — TP=2, CP=1, EP=8, ETP=1, PP=1 :

  • 8 GPUs (min_gpus) : dense DP = 8/2 = 4, MoE EDP = 8/8 = 1
  • 16 GPUs : dense DP = 8, MoE EDP = 2 → 2× batch global
  • 32 GPUs : dense DP = 16, MoE EDP = 4 → 4× batch global

Lors du dimensionnement des scripts slurm, calculer --nodes à partir de min_gpus (ou un multiple pour plus de débit via DP/EDP).

Estimation de Mémoire

Sans parallélisme (modèle 70B, FP16) :

paramètres :      140 GB
gradients :       140 GB
états optimizer : 280 GB (Adam)
activations :      48 GB (batch=1, seq=4K)
total :           608 GB

Avec TP=4, PP=4, DP=4 (64 GPUs) :

paramètres :       8,75 GB par GPU
gradients :        8,75 GB par GPU
états optimizer : 17,50 GB par GPU
activations :      3,00 GB par GPU
total :           ~38    GB par GPU

Ancrages de Code

Dimensions de parallélisme définies dans le fournisseur de modèle :

model_config = GPTModelProvider(
    tensor_model_parallel_size=2,
    # ... other model parameters
)

Calcul de la taille DP :

data_parallel_size = world_size / (tensor_model_parallel_size × pipeline_model_parallel_size × context_parallel_size)

L'initialisation Bridge câble le parallélisme dans les groupes de processus :

parallel_state.initialize_model_parallel(
    tensor_model_parallel_size=model_config.tensor_model_parallel_size,
    pipeline_model_parallel_size=model_config.pipeline_model_parallel_size,
    ...
    context_parallel_size=model_config.context_parallel_size,
    hierarchical_context_parallel_sizes=model_config.hierarchical_context_parallel_sizes,
    expert_model_parallel_size=model_config.expert_model_parallel_size,
    ...
)

Pièges

  1. TP entre nœuds détruit le débit. Toujours garder TP dans un seul domaine NVLink.

  2. PP sans entrelacement a de grandes bulles pipeline. Utiliser virtual_pipeline_model_parallel_size quand possible.

  3. SP requiert tensor_model_parallel_size > 1. Activer SP seul sans TP est une erreur de config.

  4. CP requiert seq_length % (2 * context_parallel_size) == 0.

  5. EP est uniquement pour modèles MoE. Définir expert_model_parallel_size sur un modèle dense est un no-op ou erreur.

  6. La table taille-de-modèle-à-parallélisme ci-dessus est une heuristique de démarrage. Toujours profiler la première itération pour vérifier mémoire et communication.

  7. CUDA_DEVICE_MAX_CONNECTIONS et les variables env connexes interagissent avec les paramètres d'overlap. Voir @skills/perf-tp-dp-comm-overlap/SKILL.md.

  8. Le nombre minimum de GPUs pour une config MoE est PP * max(TP*CP, EP*ETP), pas le produit de toutes les dimensions. La maille dense TP*CP et MoE EP*ETP partagent les mêmes GPUs dans chaque étage PP. Voir section « Nombre Minimum de GPUs » ci-dessus.

Vérification

Vérification rapide que le parallélisme combiné initialise correctement en utilisant la plus petite recette disponible avec parallélisme remplacé :

CUDA_VISIBLE_DEVICES=0,1,2,3 uv run python -m torch.distributed.run --nproc_per_node=4 \
  scripts/training/run_recipe.py \
  --recipe llama32_1b_pretrain_config \
  model.tensor_model_parallel_size=2 \
  model.pipeline_model_parallel_size=2 \
  model.sequence_parallel=True \
  train.train_iters=3 train.global_batch_size=8 train.micro_batch_size=1 \
  scheduler.lr_warmup_iters=0 \
  validation.eval_iters=0 validation.eval_interval=0 \
  checkpoint.save_interval=0 \
  logger.log_interval=1

Critères de succès :

  • code de sortie 0
  • perte finie à l'itération 3 (par ex. lm loss: 1.003808E+01)
  • log affiche layout TP=2 PP=2 DP=1 avec 4 rangs

Skills similaires