Exécuter les tâches de formation NVIDIA NeMo Framework

NVIDIA NeMo Framework Launcher est un outil en nuage natif permettant de lancer des tâches de formation NeMo Framework de bout en bout sur des milliers de GPU pour une formation LLM à grande échelle. Dans cet exemple, nous utilisons le lanceur de cadre NeMo pour exécuter le modèle de langage gpt3_5b large, la préparation des données et les étapes d'entraînement.

Pour plus de détails sur NeMo et le lanceur de cadre NeMo, consultez la documentation NVIDIA :

Exécuter une charge de travail de formation LLM

Installez python et exécutez une charge de travail d'entraînement.

  1. Installez python 3.8 et faites-en le python par défaut pour l'utilisateur opc.

    Pour cette commande Python3 est requise, plus les modules python répertoriés dans requirements.txt. Oracle Linux 7 (et d'autres versions du système d'exploitation) est toujours python2.

    $ sudo yum install -y oracle-softwarecollection-release-el7
    $ sudo yum -y install scl-utils rh-python38
    $ scl enable rh-python38 bash
    $ cat <<EOF >> ~/.bashrc
    [ -f /opt/rh/rh-python38/enable ] && source /opt/rh/rh-python38/enable
    EOF
  2. Utilisez les commandes Installation dans https://github.com/NVIDIA/NeMo-Megatron-Launcher.
    $ cd /nfs/scratch
    $ git clone https://github.com/NVIDIA/NeMo-Megatron-Launcher.git
    Cloning into 'NeMo-Megatron-Launcher'...
    remote: Enumerating objects: 29018, done.
    remote: Counting objects: 100% (1062/1062), done.
    remote: Compressing objects: 100% (452/452), done.
    remote: Total 29018 (delta 665), reused 898 (delta 564), pack-reused 27956
    Receiving objects: 100% (29018/29018), 27.66 MiB | 14.16 MiB/s, done.
    Resolving deltas: 100% (18124/18124), done.
    
    $ cd NeMo-Megatron-Launcher
    $ pip install -r requirements.txt --user
    $ pip install --upgrade requests --user

    Note :

    Si des utilisateurs autres que opc partageront la grappe, vous devrez installer les modules python pour tous les utilisateurs avec : sudo pip install -r requirements.txt.

Préparation des données

L'étape de préparation des données effectue trois tâches : télécharger le jeu de données non protégé par les droits d'auteur " la pile ", extraire (décompresser) les données et prétraiter les données.

  1. Modifiez launcher_scripts/conf/config.yaml :
    1. Réglez la tâche stage à data_preparation.
      stages:
        - data_preparation
        #- training
    2. Définissez launcher_scripts_path.
      # Path to NeMo Megatron Launch scripts, should ends with /launcher_scripts
      launcher_scripts_path: /nfs/scratch/NeMo-Megatron-Launcher/launcher_scripts
  2. Dans le répertoire launcher_scripts, exécutez main.py pour soumettre la tâche à Slurm.
    $ cd /nfs/scratch/NeMo-Megatron-Launcher/launcher_scripts
    $ python main.py
    Job nemo-megatron-download_gpt3_pile submission file created at '/nfs/scratch/NeMo-Megatron-Launcher/launcher_scripts/results/download_gpt3_pile/download/nemo-megatron-download_gpt3_pile_submission.sh' 
    . . .
  3. Utilisez la commande squeue de Slurm pour observer le statut de la tâche.
    $ squeue
                 JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
        191_[20-29%30]       gpu nemo-meg      opc PD       0:00      1 (Resources)
            192_[0-29]       gpu nemo-meg      opc PD       0:00      1 (Dependency,Priority)
            193_[0-29]       gpu nemo-meg      opc PD       0:00      1 (Dependency)
                191_19       gpu nemo-meg      opc  R       0:50      1 gpu-permanent-node-517
                191_18       gpu nemo-meg      opc  R       0:56      1 gpu-permanent-node-878
    

    Les tâches ayant le statut (ST) R indiquent que certaines tâches sont en cours d'exécution. Les autres tâches affichées sont en attente de ressources ou d'exécution d'autres tâches en premier (dépendances).

    Consultez results/download_gpt3_pile/download pour voir la sortie des tâches terminées et en cours d'exécution. Vous pouvez également trouver le script bash utilisé pour soumettre les travaux Slurm. Le script et la sortie peuvent être utiles pour dépanner les travaux qui ne s'exécutent pas comme prévu.
Sur un cluster à deux noeuds, les étapes suivantes ont été effectuées :
  • 90 minutes à télécharger
  • 46 minutes à extraire
  • 5 heures 45 minutes pour le prétraitement
Les temps d'exécution seraient nettement inférieurs sur un cluster plus grand où les partitions horizontales de données peuvent être parallèles sur un maximum de 30 noeuds.

Entraînement

Au cours de la phase de formation, vous allez modifier les scripts pour effectuer la formation LLM.

  1. Modifiez launcher_scripts/conf/config.yaml :
    1. Réglez la tâche stage à training.
      stages:
        #- data_preparation
        - training
    2. Ajoutez des variables pour configurer NVIDIA NVLink sur OCI.
      Dans la section env_vars, ajoutez ces variables pour configurer NVIDIA NVLink sur OCI. Laissez les variables existantes en place, mais mettez en commentaire les variables que nous remplaçons par de nouvelles valeurs.
      env_vars:
        TRANSFORMERS_OFFLINE: 0 # (was 1)
        . . .
        RX_QUEUE_LEN: 8192
        IB_RX_QUEUE_LEN: 8192
        UCX_TLS: tcp
        HCOLL_ENABLE_MCAST_ALL: 0
        coll_hcoll_enable: 0
        UCX_NET_DEVICES: ens300
        NCCL_SOCKET_IFNAME: ens300
        NCCL_IB_TIMEOUT: 16
        NCCL_IB_SL: 0
        NCCL_IB_TC: 41
        NCCL_ALGO: Auto  # tree, ring
        NCCL_IB_GID_INDEX: 3
        NCCL_IB_QPS_PER_CONNECTION: 16  # was 4
        NCCL_IB_HCA: \'mlx5_1,mlx5_2,mlx5_3,mlx5_4,mlx5_5,mlx5_6,mlx5_7,mlx5_8,mlx5_9,mlx5_10,mlx5_11,mlx5_12,mlx5_14,mlx5_15,mlx5_16,mlx5_17\'
        NCCL_DEBUG: INFO # Logging level for NCCL. Set to "INFO" for debug information
  2. Modifiez conf/training/gpt3/5b.yaml.
    run:
      time_limit: "6-00:00:00"  # allow the training job to run for 6 days
    
    trainer:
      num_nodes: 2 # (was 16) set to the size of your cluster
    
    model:
      micro_batch_size: 2           # (was 4) change to fit in A100/40GB memory
      tensor_model_parallel_size: 2 # (was 1) change to fit in A100/40GB memory
    
      optim:
        bucket_cap_mb: 200 # (was 400)
  3. À partir du répertoire launcher_scripts, exécutez main.py pour soumettre la tâche à Slurm. Utilisez la commande squeue pour vérifier que la tâche est en cours d'exécution ("R").
    $ cd /nfs/scratch/NeMo-Megatron-Launcher/launcher_scripts
    $ python main.py
    Job nemo-megatron-gpt3_5b submission file created at '/nfs/scratch/NeMo-Megatron-Launcher/launcher_scripts/results/gpt3_5b/nemo-megatron-gpt3_5b_submission.sh'
    Job nemo-megatron-gpt3_5b submitted with Job ID 285
    $ squeue
                 JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                   285       gpu nemo-meg      opc  R       0:06      2 gpu-permanent-node-[517,878]
  4. Consultez les fichiers dans results/gpt3_5b/* pour voir les messages de sortie et d'erreur et surveiller la progression des tâches en cours d'exécution.
    La formation LLM fonctionne si vous voyez des lignes similaires dans gpt3_5b_nnn.out :
    Training:   0%|          | 0/75375 [00:00<?]
    Epoch 0: :   0%|          | 0/75375 [00:00<?]
    Epoch 0: :   0%|          | 1/75375 [00:52<1089:12:32]
    Epoch 0: :   0%|          | 1/75375 [00:52<1089:13:02 ... train_step_timing in s=52.00]
    Epoch 0: :   0%|          | 2/75375 [01:33<980:51:18 ... train_step_timing in s=52.00]
    Epoch 0: :   0%|          | 2/75375 [01:33<980:51:33 ... train_step_timing in s=46.80]
    Epoch 0: :   0%|          | 3/75375 [02:15<945:29:05 ... train_step_timing in s=46.80]
    Epoch 0: :   0%|          | 3/75375 [02:15<945:29:14 ... train_step_timing in s=45.20]
    Epoch 0: :   0%|          | 4/75375 [02:57<926:40:09 ... train_step_timing in s=45.20]
    Epoch 0: :   0%|          | 4/75375 [02:57<926:40:16 ... train_step_timing in s=44.30]
    Epoch 0: :   0%|          | 5/75375 [03:38<915:10:14 ... train_step_timing in s=44.30]
    Epoch 0: :   0%|          | 5/75375 [03:38<915:10:20 ... train_step_timing in s=43.70]
    Epoch 0: :   0%|          | 6/75375 [04:20<907:25:47 ... train_step_timing in s=43.70]
    Epoch 0: :   0%|          | 6/75375 [04:20<907:25:52 ... train_step_timing in s=41.60]
    Epoch 0: :   0%|          | 7/75375 [05:01<901:53:34 ... train_step_timing in s=41.60]
    Epoch 0: :   0%|          | 7/75375 [05:01<901:53:38 ... train_step_timing in s=41.60]
    Epoch 0: :   0%|          | 8/75375 [05:43<897:38:17 ... train_step_timing in s=41.60]
    Epoch 0: :   0%|          | 8/75375 [05:43<897:38:21 ... train_step_timing in s=41.50]
    Epoch 0: :   0%|          | 9/75375 [06:24<894:16:56 ... train_step_timing in s=41.50]
    Epoch 0: :   0%|          | 9/75375 [06:24<894:16:59 ... train_step_timing in s=41.50]
    Epoch 0: :   0%|          | 10/75375 [07:05<891:30:50 ... train_step_timing in s=41.50]

    Cela indique que chaque étape d'entraînement s'est terminée en 41,5 secondes. Des étapes beaucoup plus rapides peuvent être réalisées avec plus de GPU dans le cluster.