Accelerate documentation
DeepSpeed
DeepSpeed
DeepSpeed implémente tout ce qui est décrit dans l'article ZeRO. Parmi les optimisations notables, on trouve :
- Partitionnement de l'état de l'optimiseur (étape 1 de ZeRO)
- Partitionnement des gradients (ZeRO stage 2)
- Partitionnement des paramètres (ZeRO stage 3)
- Gestion personnalisée de l'entraînement en précision mixte
- Une gamme d'optimiseurs rapides basés sur des extensions CUDA
- ZeRO-Offload vers le CPU et le disque/NVMe
- Partitionnement hiérarchique des paramètres du modèle (ZeRO++)
ZeRO-Offload a son propre article dédié : ZeRO-Offload: Democratizing Billion-Scale Model Training. Et la prise en charge de NVMe est décrite dans l’article ZeRO-Infinity: Breaking the GPU Memory Wall for Extreme Scale Deep Learning.
DeepSpeed ZeRO-2 est principalement utilisé uniquement pour l’entraînement, car ses fonctionnalités ne sont pas utiles pour l’inférence.
DeepSpeed ZeRO-3 peut également être utilisé pour l’inférence, car il permet de charger de très grands modèles sur plusieurs GPU, ce qui serait impossible sur un seul GPU.
Accelerate intègre DeepSpeed via 2 options :
- Intégration des fonctionnalités de DeepSpeed via la spécification d'un
deepspeed config filedansaccelerate config. Il vous suffit de fournir votre fichier de configuration personnalisé ou d'utiliser notre modèle. La majeure partie de ce document est consacrée à cette fonctionnalité. Elle prend en charge toutes les fonctionnalités principales de DeepSpeed et offre à l'utilisateur une grande flexibilité. L'utilisateur peut devoir modifier quelques lignes de code en fonction de la configuration. - Intégration via
deepspeed_plugin. Cela prend en charge un sous-ensemble des fonctionnalités de DeepSpeed et utilise les options par défaut pour le reste des configurations. L'utilisateur n'a besoin de modifier aucun code, ce qui convient à ceux qui sont à l'aise avec la plupart des paramètres par défaut de DeepSpeed.
Que comprend l'intégration ?
Entraînement :
- Accelerate intègre toutes les fonctionnalités de DeepSpeed ZeRO. Cela inclut tous les stades ZeRO 1, 2 et 3, ainsi que ZeRO-Offload, ZeRO-Infinity (qui peut décharger sur disque/NVMe) et ZeRO++.
Voici une brève description du parallélisme de données utilisant ZeRO - Zero Redundancy Optimizer, accompagnée d'un diagramme issu de ce article de blog

(Source : lien)
a. Étape 1 : Répartit les états de l'optimiseur entre les travailleurs/GPU parallèles de données
b. Étape 2 : Répartit les états de l'optimiseur et les gradients entre les travailleurs/GPU parallèles de données
c. Étape 3 : Répartit les états de l'optimiseur + les gradients + les paramètres du modèle entre les travailleurs/GPU parallèles de données
d. Optimizer Offload : déplace les gradients et les états de l'optimiseur vers le CPU/le disque, en s'appuyant sur le niveau 2 de ZERO
e. Param Offload : Déplace les paramètres du modèle vers le CPU/le disque, en s'appuyant sur le stade 3 de ZERO
f. Partitionnement hiérarchique : Permet une formation multi-nœuds efficace avec une formation parallèle par données entre les nœuds et un fractionnement ZeRO-3 au sein d'un nœud, construit sur la base de ZeRO Stage 3.
Note: With respect to Disk Offload, the disk should be an NVME for decent speed but it technically works on any DiskInférence :
- DeepSpeed ZeRO Inference prend en charge le ZeRO stage 3 avec ZeRO-Infinity. Il utilise le même protocole ZeRO que l’entraînement, mais n’utilise ni optimiseur ni lr scheduler, et seul le stage 3 est pertinent. Pour plus de détails, voir : ZeRO Inference.
Comment ça fonctionne ?
Prérequis : Installez la version >=0.6.5 de DeepSpeed. Veuillez consulter les détails d'installation de DeepSpeed pour plus d'informations.
Nous examinerons d’abord l’intégration simple à utiliser via accelerate config.
Sera ensuite présentée l’intégration plus flexible et riche en fonctionnalités de deepspeed config file.
Plugin DeepSpeed d'Accelerate
Sur votre machine (ou vos machines), exécutez simplement :
accelerate config
et de répondre aux questions posées. Il vous demandera si vous souhaitez utiliser un fichier de configuration pour DeepSpeed, auquel vous devez répondre non. Répondez ensuite aux questions suivantes pour générer une configuration de base de DeepSpeed. Cela génère un fichier de configuration qui sera utilisé automatiquement pour définir correctement les options par défaut lors de
accelerate launch my_script.py --args_to_my_script
Par exemple, voici comment exécuter l’exemple NLP examples/nlp_example.py (depuis la racine du dépôt) avec DeepSpeed Plugin :
Exemple de plugin DeepSpeed ZeRO Stage-2
compute_environment: LOCAL_MACHINE
deepspeed_config:
gradient_accumulation_steps: 1
gradient_clipping: 1.0
offload_optimizer_device: none
offload_param_device: none
zero3_init_flag: true
zero_stage: 2
distributed_type: DEEPSPEED
fsdp_config: {}
machine_rank: 0
main_process_ip: null
main_process_port: null
main_training_function: main
mixed_precision: fp16
num_machines: 1
num_processes: 2
use_cpu: falseaccelerate launch examples/nlp_example.py --mixed_precision fp16
Exemple de plugin DeepSpeed ZeRO Stage-3 avec offload CPU
compute_environment: LOCAL_MACHINE
deepspeed_config:
gradient_accumulation_steps: 1
gradient_clipping: 1.0
offload_optimizer_device: cpu
offload_param_device: cpu
zero3_init_flag: true
zero3_save_16bit_model: true
zero_stage: 3
distributed_type: DEEPSPEED
fsdp_config: {}
machine_rank: 0
main_process_ip: null
main_process_port: null
main_training_function: main
mixed_precision: fp16
num_machines: 1
num_processes: 2
use_cpu: falseaccelerate launch examples/nlp_example.py --mixed_precision fp16
Actuellement, Accelerate prend en charge la configuration suivante via l'interface en ligne de commande :
`zero_stage`: [0] Disabled, [1] optimizer state partitioning, [2] optimizer+gradient state partitioning and [3] optimizer+gradient+parameter partitioning
`gradient_accumulation_steps`: Number of training steps to accumulate gradients before averaging and applying them.
`gradient_clipping`: Enable gradient clipping with value.
`offload_optimizer_device`: [none] Disable optimizer offloading, [cpu] offload optimizer to CPU, [nvme] offload optimizer to NVMe SSD. Only applicable with ZeRO >= Stage-2.
`offload_optimizer_nvme_path`: Decides Nvme Path to offload optimizer states. If unspecified, will default to 'none'.
`offload_param_device`: [none] Disable parameter offloading, [cpu] offload parameters to CPU, [nvme] offload parameters to NVMe SSD. Only applicable with ZeRO Stage-3.
`offload_param_nvme_path`: Decides Nvme Path to offload parameters. If unspecified, will default to 'none'.
`zero3_init_flag`: Decides whether to enable `deepspeed.zero.Init` for constructing massive models. Only applicable with ZeRO Stage-3.
`zero3_save_16bit_model`: Decides whether to save 16-bit model weights when using ZeRO Stage-3.
`mixed_precision`: `no` for FP32 training, `fp16` for FP16 mixed-precision training and `bf16` for BF16 mixed-precision training.
`deepspeed_moe_layer_cls_names`: Comma-separated list of transformer Mixture-of-Experts (MoE) layer class names (case-sensitive) to wrap ,e.g, `MixtralSparseMoeBlock`, `Qwen2MoeSparseMoeBlock`, `JetMoEAttention,JetMoEBlock` ...
`deepspeed_hostfile`: DeepSpeed hostfile for configuring multi-node compute resources.
`deepspeed_exclusion_filter`: DeepSpeed exclusion filter string when using mutli-node setup.
`deepspeed_inclusion_filter`: DeepSpeed inclusion filter string when using mutli-node setup.
`deepspeed_multinode_launcher`: DeepSpeed multi-node launcher to use, e.g. `pdsh`, `standard`, `openmpi`, `mvapich`, `mpich`, `slurm`, `nossh` (requires DeepSpeed >= 0.14.5). If unspecified, will default to `pdsh`.
`deepspeed_config_file`: path to the DeepSpeed config file in `json` format. See the next section for more details on this.Pour pouvoir ajuster davantage d'options, vous devrez utiliser un fichier de configuration DeepSpeed.
Fichier de configuration DeepSpeed
Sur votre machine (ou vos machines), exécutez simplement :
accelerate config
et de répondre aux questions posées. Il vous demandera si vous souhaitez utiliser un fichier de configuration pour deepspeed, auquel vous répondez oui et fournissez le chemin vers le fichier de configuration deepspeed. Cela génère un fichier de configuration qui sera utilisé automatiquement pour définir correctement les options par défaut lors de
accelerate launch my_script.py --args_to_my_script
Par exemple, voici comment exécuter l’exemple NLP examples/by_feature/deepspeed_with_config_support.py (depuis la racine du dépôt) avec un fichier de configuration DeepSpeed :
Exemple de fichier de configuration DeepSpeed ZeRO Stage-2
compute_environment: LOCAL_MACHINE
deepspeed_config:
deepspeed_config_file: /home/ubuntu/accelerate/examples/deepspeed_config_templates/zero_stage2_config.json
zero3_init_flag: true
distributed_type: DEEPSPEED
fsdp_config: {}
machine_rank: 0
main_process_ip: null
main_process_port: null
main_training_function: main
mixed_precision: fp16
num_machines: 1
num_processes: 2
use_cpu: falsedont le contenu de zero_stage2_config.json est le suivant :
{
"fp16": {
"enabled": true,
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
},
"optimizer": {
"type": "AdamW",
"params": {
"lr": "auto",
"weight_decay": "auto",
"torch_adam": true,
"adam_w_mode": true
}
},
"scheduler": {
"type": "WarmupDecayLR",
"params": {
"warmup_min_lr": "auto",
"warmup_max_lr": "auto",
"warmup_num_steps": "auto",
"total_num_steps": "auto"
}
},
"zero_optimization": {
"stage": 2,
"allgather_partitions": true,
"allgather_bucket_size": 2e8,
"overlap_comm": true,
"reduce_scatter": true,
"reduce_bucket_size": "auto",
"contiguous_gradients": true
},
"gradient_accumulation_steps": 1,
"gradient_clipping": "auto",
"steps_per_print": 2000,
"train_batch_size": "auto",
"train_micro_batch_size_per_gpu": "auto",
"wall_clock_breakdown": false
}accelerate launch examples/by_feature/deepspeed_with_config_support.py \
--config_name "gpt2-large" \
--tokenizer_name "gpt2-large" \
--dataset_name "wikitext" \
--dataset_config_name "wikitext-2-raw-v1" \
--block_size 128 \
--output_dir "./clm/clm_deepspeed_stage2_accelerate" \
--learning_rate 5e-4 \
--per_device_train_batch_size 24 \
--per_device_eval_batch_size 24 \
--num_train_epochs 3 \
--with_tracking \
--report_to "wandb"\Exemple de fichier de configuration DeepSpeed pour ZeRO Stage-3 avec offload CPU
compute_environment: LOCAL_MACHINE
deepspeed_config:
deepspeed_config_file: /home/ubuntu/accelerate/examples/deepspeed_config_templates/zero_stage3_offload_config.json
zero3_init_flag: true
distributed_type: DEEPSPEED
fsdp_config: {}
machine_rank: 0
main_process_ip: null
main_process_port: null
main_training_function: main
mixed_precision: fp16
num_machines: 1
num_processes: 2
use_cpu: falsedont le contenu de zero_stage3_offload_config.json est le suivant :
{
"fp16": {
"enabled": true,
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
},
"optimizer": {
"type": "AdamW",
"params": {
"lr": "auto",
"weight_decay": "auto"
}
},
"scheduler": {
"type": "WarmupDecayLR",
"params": {
"warmup_min_lr": "auto",
"warmup_max_lr": "auto",
"warmup_num_steps": "auto",
"total_num_steps": "auto"
}
},
"zero_optimization": {
"stage": 3,
"offload_optimizer": {
"device": "cpu",
"pin_memory": true
},
"offload_param": {
"device": "cpu",
"pin_memory": true
},
"overlap_comm": true,
"contiguous_gradients": true,
"reduce_bucket_size": "auto",
"stage3_prefetch_bucket_size": "auto",
"stage3_param_persistence_threshold": "auto",
"sub_group_size": 1e9,
"stage3_max_live_parameters": 1e9,
"stage3_max_reuse_distance": 1e9,
"stage3_gather_16bit_weights_on_model_save": "auto"
},
"gradient_accumulation_steps": 1,
"gradient_clipping": "auto",
"steps_per_print": 2000,
"train_batch_size": "auto",
"train_micro_batch_size_per_gpu": "auto",
"wall_clock_breakdown": false
}accelerate launch examples/by_feature/deepspeed_with_config_support.py \
--config_name "gpt2-large" \
--tokenizer_name "gpt2-large" \
--dataset_name "wikitext" \
--dataset_config_name "wikitext-2-raw-v1" \
--block_size 128 \
--output_dir "./clm/clm_deepspeed_stage3_offload_accelerate" \
--learning_rate 5e-4 \
--per_device_train_batch_size 32 \
--per_device_eval_batch_size 32 \
--num_train_epochs 3 \
--with_tracking \
--report_to "wandb"\Exemple de configuration ZeRO++ Vous pouvez utiliser les fonctionnalités de ZeRO++ en utilisant les paramètres de configuration appropriés. Notez que ZeRO++ est une extension de ZeRO Stage 3. Voici comment le fichier de configuration peut être modifié, d'après le tutoriel ZeRO++ de DeepSpeed :
{
"zero_optimization": {
"stage": 3,
"reduce_bucket_size": "auto",
"zero_quantized_weights": true,
"zero_hpz_partition_size": 8,
"zero_quantized_gradients": true,
"contiguous_gradients": true,
"overlap_comm": true
}
}Pour le partitionnement hiérarchique, la taille du partitionnement zero_hpz_partition_size doit idéalement être définie sur le nombre de GPU par nœud. (Par exemple, le fichier de configuration ci-dessus suppose 8 GPU par nœud)
Modifications importantes du code lors de l'utilisation d'un fichier de configuration DeepSpeed
Optimiseurs et planificateurs DeepSpeed. Pour plus d'informations à ce sujet, consultez la documentation des Optimiseurs DeepSpeed et des Planificateurs DeepSpeed. Nous examinerons les modifications nécessaires dans le code lors de l'utilisation de ces éléments.
a. DS Optim + DS Scheduler : le cas où les clés
optimizeretschedulersont présentes dans le fichier de configuration DeepSpeed. Dans cette situation, celles-ci seront utilisées et l'utilisateur doit utiliseraccelerate.utils.DummyOptimetaccelerate.utils.DummySchedulerpour remplacer les optimiseurs et planificateurs PyTorch/personnalisés dans son code. Voici l'extrait deexamples/by_feature/deepspeed_with_config_support.pyqui montre cela :# Creates Dummy Optimizer if `optimizer` was specified in the config file else creates Adam Optimizer optimizer_cls = ( torch.optim.AdamW if accelerator.state.deepspeed_plugin is None or "optimizer" not in accelerator.state.deepspeed_plugin.deepspeed_config else DummyOptim ) optimizer = optimizer_cls(optimizer_grouped_parameters, lr=args.learning_rate) # Creates Dummy Scheduler if `scheduler` was specified in the config file else creates `args.lr_scheduler_type` Scheduler if ( accelerator.state.deepspeed_plugin is None or "scheduler" not in accelerator.state.deepspeed_plugin.deepspeed_config ): lr_scheduler = get_scheduler( name=args.lr_scheduler_type, optimizer=optimizer, num_warmup_steps=args.num_warmup_steps, num_training_steps=args.max_train_steps, ) else: lr_scheduler = DummyScheduler( optimizer, total_num_steps=args.max_train_steps, warmup_num_steps=args.num_warmup_steps )b. Optimiseur personnalisé + Planificateur personnalisé : le cas où les clés
optimizeretschedulersont absentes du fichier de configuration DeepSpeed. Dans cette situation, aucune modification de code n'est nécessaire de la part de l'utilisateur et c'est le cas lors de l'utilisation de l'intégration via le plugin DeepSpeed. Dans l'exemple ci-dessus, on peut voir que le code reste inchangé si les clésoptimizeretschedulersont absentes du fichier de configuration DeepSpeed.c. Optimiseur personnalisé + planificateur DS : le cas où seule la clé
schedulerest présente dans le fichier de configuration DeepSpeed. Dans cette situation, l'utilisateur doit utiliseraccelerate.utils.DummySchedulerpour remplacer le planificateur PyTorch/personnalisé dans son code.d. DS Optim + planificateur personnalisé : le cas où seule la clé
optimizerest présente dans le fichier de configuration DeepSpeed. Cela entraînera une erreur, car vous ne pouvez utiliser DS Scheduler que lorsque vous utilisez DS Optim.Remarquez les valeurs
autodans les fichiers de configuration DeepSpeed de l’exemple ci-dessus. Elles sont gérées automatiquement par la méthodeprepareen fonction du modèle, des chargeurs de données, de l’optimiseur factice et des planificateurs factices fournis à la méthodeprepare. Seuls les champsautospécifiés dans les exemples ci-dessus sont gérés par la méthodeprepare; les autres doivent être explicitement définis par l’utilisateur.
Les valeurs auto sont calculées comme suit :
reduce_bucket_size:hidden_size * hidden_sizestage3_prefetch_bucket_size:int(0.9 * hidden_size * hidden_size)stage3_param_persistence_threshold:10 * hidden_size
Pour que la fonctionnalité auto fonctionne pour ces 3 entrées de configuration, Accelerate utilisera model.config.hidden_size ou max(model.config.hidden_sizes) comme hidden_size. Si aucune de ces valeurs n’est disponible, le lancement échouera et vous devrez définir manuellement ces 3 entrées de configuration. N’oubliez pas que les deux premières entrées de configuration sont les tampons de communication : plus ils sont grands, plus les communications seront efficaces, mais plus ils consommeront de mémoire GPU, ce qui constitue donc un compromis de performance à régler.
Points à noter lors de l'utilisation du fichier de configuration DeepSpeed
Voici un exemple de script utilisant deepspeed_config_file dans différents scénarios.
Code test.py :
from accelerate import Accelerator
from accelerate.state import AcceleratorState
def main():
accelerator = Accelerator()
accelerator.print(f"{AcceleratorState()}")
if __name__ == "__main__":
main()Scénario 1 : Fichier de configuration accelerate modifié manuellement, contenant deepspeed_config_file ainsi que d'autres entrées.
- Contenu de la configuration
accelerate:
command_file: null
commands: null
compute_environment: LOCAL_MACHINE
deepspeed_config:
gradient_accumulation_steps: 1
gradient_clipping: 1.0
offload_optimizer_device: 'cpu'
offload_param_device: 'cpu'
zero3_init_flag: true
zero3_save_16bit_model: true
zero_stage: 3
deepspeed_config_file: 'ds_config.json'
distributed_type: DEEPSPEED
downcast_bf16: 'no'
dynamo_backend: 'NO'
fsdp_config: {}
gpu_ids: null
machine_rank: 0
main_process_ip: null
main_process_port: null
main_training_function: main
megatron_lm_config: {}
num_machines: 1
num_processes: 2
rdzv_backend: static
same_network: true
tpu_name: null
tpu_zone: null
use_cpu: falseds_config.json:
{
"bf16": {
"enabled": true
},
"zero_optimization": {
"stage": 3,
"stage3_gather_16bit_weights_on_model_save": false,
"offload_optimizer": {
"device": "none"
},
"offload_param": {
"device": "none"
}
},
"gradient_clipping": 1.0,
"train_batch_size": "auto",
"train_micro_batch_size_per_gpu": "auto",
"gradient_accumulation_steps": 10,
"steps_per_print": 2000000
}- Sortie de
accelerate launch test.py:
ValueError: When using `deepspeed_config_file`, the following accelerate config variables will be ignored:
['gradient_accumulation_steps', 'gradient_clipping', 'zero_stage', 'offload_optimizer_device', 'offload_param_device',
'zero3_save_16bit_model', 'mixed_precision'].
Please specify them appropriately in the DeepSpeed config file.
If you are using an accelerate config file, remove other config variables mentioned in the above specified list.
The easiest method is to create a new config following the questionnaire via `accelerate config`.
It will only ask for the necessary config variables when using `deepspeed_config_file`.Scénario 2 : utilisez la solution de l'erreur pour créer une nouvelle configuration accelerate et vérifiez qu'aucune erreur d'ambiguïté n'est désormais levée.
- Exécuter
accelerate config:
$ accelerate config
-------------------------------------------------------------------------------------------------------------------------------
In which compute environment are you running?
This machine
-------------------------------------------------------------------------------------------------------------------------------
Which type of machine are you using?
multi-GPU
How many different machines will you use (use more than 1 for multi-node training)? [1]:
Do you wish to optimize your script with torch dynamo?[yes/NO]:
Do you want to use DeepSpeed? [yes/NO]: yes
Do you want to specify a json file to a DeepSpeed config? [yes/NO]: yes
Please enter the path to the json DeepSpeed config file: ds_config.json
Do you want to enable `deepspeed.zero.Init` when using ZeRO Stage-3 for constructing massive models? [yes/NO]: yes
How many GPU(s) should be used for distributed training? [1]:4
accelerate configuration saved at ds_config_sample.yaml- Contenu de la configuration
accelerate:
compute_environment: LOCAL_MACHINE
deepspeed_config:
deepspeed_config_file: ds_config.json
zero3_init_flag: true
distributed_type: DEEPSPEED
downcast_bf16: 'no'
dynamo_backend: 'NO'
fsdp_config: {}
machine_rank: 0
main_training_function: main
megatron_lm_config: {}
num_machines: 1
num_processes: 4
rdzv_backend: static
same_network: true
use_cpu: false- Sortie de
accelerate launch test.py:
Distributed environment: DEEPSPEED Backend: nccl
Num processes: 4
Process index: 0
Local process index: 0
Device: cuda:0
Mixed precision type: bf16
ds_config: {'bf16': {'enabled': True}, 'zero_optimization': {'stage': 3, 'stage3_gather_16bit_weights_on_model_save': False, 'offload_optimizer': {'device': 'none'}, 'offload_param': {'device': 'none'}}, 'gradient_clipping': 1.0, 'train_batch_size': 'auto', 'train_micro_batch_size_per_gpu': 'auto', 'gradient_accumulation_steps': 10, 'steps_per_print': inf, 'fp16': {'enabled': False}}Scénario 3 : définir les arguments de la commande accelerate launch liés à DeepSpeed sur "auto" dans le fichier de configuration DeepSpeed et vérifier que tout fonctionne comme prévu.
- Nouveau
ds_config.jsonavec"auto"pour les arguments de la commandeaccelerate launchDeepSpeed :
{
"bf16": {
"enabled": "auto"
},
"zero_optimization": {
"stage": "auto",
"stage3_gather_16bit_weights_on_model_save": "auto",
"offload_optimizer": {
"device": "auto"
},
"offload_param": {
"device": "auto"
}
},
"gradient_clipping": "auto",
"train_batch_size": "auto",
"train_micro_batch_size_per_gpu": "auto",
"gradient_accumulation_steps": "auto",
"steps_per_print": 2000000
}- Sortie de
accelerate launch --mixed_precision="fp16" --zero_stage=3 --gradient_accumulation_steps=5 --gradient_clipping=1.0 --offload_param_device="cpu" --offload_optimizer_device="nvme" --zero3_save_16bit_model="true" test.py:
Distributed environment: DEEPSPEED Backend: nccl
Num processes: 4
Process index: 0
Local process index: 0
Device: cuda:0
Mixed precision type: fp16
ds_config: {'bf16': {'enabled': False}, 'zero_optimization': {'stage': 3, 'stage3_gather_16bit_weights_on_model_save': True, 'offload_optimizer': {'device': 'nvme'}, 'offload_param': {'device': 'cpu'}}, 'gradient_clipping': 1.0, 'train_batch_size': 'auto', 'train_micro_batch_size_per_gpu': 'auto', 'gradient_accumulation_steps': 5, 'steps_per_print': inf, 'fp16': {'enabled': True, 'auto_cast': True}}Remarque :
- Les valeurs
"auto"restantes sont gérées dans l'appelaccelerator.prepare(), comme expliqué au point 2 deImportant code changes when using DeepSpeed Config File. - La valeur transmise lors de la création de l'objet
AcceleratorviaAccelerator(gradient_accumulation_steps=k)n'est utilisée que lorsquegradient_accumulation_stepsestauto. Lors de l'utilisation du plugin DeepSpeed, la valeur qui en provient est utilisée et elle écrase la valeur transmise lors de la création de l'objet Accelerator.
Enregistrer et charger
La sauvegarde et le chargement des modèles restent inchangés pour ZeRO Stage-1 et Stage-2.
Sous ZeRO Stage-3,
state_dictne contient que des espaces réservés, car les poids du modèle sont partitionnés sur plusieurs GPU. ZeRO Stage-3 propose 2 options :a. Enregistrer l’ensemble des poids du modèle en 16 bits pour les charger directement plus tard à l’aide de
model.load_state_dict(torch.load(pytorch_model.bin)). Pour cela, définissez soitzero_optimization.stage3_gather_16bit_weights_on_model_savesur True dans le fichier de configuration DeepSpeed, soitzero3_save_16bit_modelsur True dans le plugin DeepSpeed. Notez que cette option nécessite la consolidation des poids sur une seule GPU, ce qui peut être lent et gourmand en mémoire ; n’utilisez donc cette fonctionnalité que si nécessaire. Voici un extrait deexamples/by_feature/deepspeed_with_config_support.pyqui illustre cela :unwrapped_model = accelerator.unwrap_model(model) # New Code # # Saves the whole/unpartitioned fp16 model when in ZeRO Stage-3 to the output directory if # `stage3_gather_16bit_weights_on_model_save` is True in DeepSpeed Config file or # `zero3_save_16bit_model` is True in DeepSpeed Plugin. # For Zero Stages 1 and 2, models are saved as usual in the output directory. # The model name saved is `pytorch_model.bin` unwrapped_model.save_pretrained( args.output_dir, is_main_process=accelerator.is_main_process, save_function=accelerator.save, state_dict=accelerator.get_state_dict(model), )b. Pour obtenir des poids en 32 bits, enregistrez d'abord le modèle à l'aide de
model.save_checkpoint(). Voici l'extrait deexamples/by_feature/deepspeed_with_config_support.pyqui montre cela :success = model.save_checkpoint(PATH, ckpt_id, checkpoint_state_dict) status_msg = f"checkpointing: PATH={PATH}, ckpt_id={ckpt_id}" if success: logging.info(f"Success {status_msg}") else: logging.warning(f"Failure {status_msg}")Cela créera les partitions du modèle et de l'optimiseur ZeRO ainsi que le script
zero_to_fp32.pydans le répertoire de point de contrôle. Vous pouvez utiliser ce script pour effectuer une consolidation hors ligne. Il ne nécessite aucun fichier de configuration ni GPU. Voici un exemple de son utilisation :$ cd /path/to/checkpoint_dir $ ./zero_to_fp32.py . pytorch_model.bin Processing zero checkpoint at global_step1 Detected checkpoint of type zero stage 3, world_size: 2 Saving fp32 state dict to pytorch_model.bin (total_numel=60506624)Pour obtenir un modèle 32 bits pour la sauvegarde/l'inférence, vous pouvez effectuer :
from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint unwrapped_model = accelerator.unwrap_model(model) fp32_model = load_state_dict_from_zero_checkpoint(unwrapped_model, checkpoint_dir)Si vous n'êtes intéressé que par le
state_dict, vous pouvez procéder comme suit :from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir)Notez que toutes ces fonctions nécessitent environ 2 fois la mémoire (RAM générale) de la taille du point de contrôle final.
Inférence ZeRO
DeepSpeed ZeRO Inference prend en charge le ZeRO stage 3 avec ZeRO-Infinity. Il utilise le même protocole ZeRO que l'entraînement, mais n'utilise ni optimiseur ni lr scheduler, et seul le stage 3 est pertinent. Avec l'intégration accelerate, il suffit de préparer le modèle et le dataloader comme indiqué ci-dessous :
model, eval_dataloader = accelerator.prepare(model, eval_dataloader)
Quelques mises en garde à connaître
- L'intégration actuelle ne prend pas en charge le Pipeline Parallelism de DeepSpeed.
- L'intégration actuelle ne prend pas en charge
mpu, ce qui limite le parallélisme de tenseurs pris en charge dans Megatron-LM. - L'intégration actuelle ne prend pas en charge plusieurs modèles.
DeepSpeed multi-nœuds
DeepSpeed prend en charge l’inférence et l’entraînement multi-nœuds via divers lanceurs. Vous pouvez spécifier un lanceur différent en définissant la configuration deepspeed_multinode_launcher dans l’interface en ligne de commande ou dans le fichier de configuration DeepSpeed.
Actuellement, Accelerate prend en charge la transmission de la configuration pour les lanceurs multi-nœuds DeepSpeed suivants : pdsh (par défaut), standard, openmpi, mvapich, mpich, slurm, nossh (nécessite DeepSpeed >= 0.14.5).
Veuillez consulter la documentation DeepSpeed pour plus d’informations sur les différents lanceurs. Par défaut, DeepSpeed tente d’utiliser SSH sans mot de passe depuis le nœud principal vers les autres nœuds pour exécuter la commande du lanceur. Dans cette configuration, la commande accelerate launch n’a besoin d’être exécutée que sur le nœud principal. Si vous utilisez le lanceur nossh, vous devrez exécuter la commande accelerate launch sur chaque nœud en utilisant une configuration copiée.
Ressources DeepSpeed
La documentation relative aux éléments internes de deepspeed peut être consultée ici.
Articles :
- ZeRO : Optimisations de la mémoire pour l’entraînement de modèles à un billion de paramètres
- ZeRO-Offload : démocratiser l’entraînement de modèles à l’échelle du milliard de paramètres
- ZeRO-Infinity : Briser la barrière de la mémoire GPU pour l'apprentissage profond à l'échelle extrême
- ZeRO++ : communication collective extrêmement efficace pour l’entraînement de modèles géants
Enfin, n’oubliez pas que Accelerate intègre uniquement DeepSpeed. Par conséquent, si vous rencontrez des problèmes ou avez des questions concernant l’utilisation de DeepSpeed, veuillez ouvrir un ticket sur GitHub DeepSpeed.
Update on GitHubPour ceux qui s'intéressent aux similitudes et aux différences entre FSDP et DeepSpeed, consultez le guide des concepts ici !