Exécuter les travaux de formation NVIDIA NeMo Framework

NVIDIA NeMo Framework Launcher est un outil cloud natif permettant de lancer des travaux 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 structure NeMo pour exécuter le modèle de langage gpt3_5b large, les étapes de préparation des données et d'entraînement.

Reportez-vous à la documentation NVIDIA pour plus de détails sur NeMo et le lanceur de structure NeMo :

Exécuter une charge de travail de formation LLM

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

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

    Pour ce paramètre Python3 est requis, plus les modules python répertoriés dans requirements.txt. Oracle Linux 7 (et d'autres versions de l'O/S) 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

    Remarques :

    Si des utilisateurs autres que opc partagent le cluster, vous devez 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 l'ensemble de données sans droits d'auteur "the pile", extraire (décompresser) les données et prétraiter les données.

  1. Modifiez launcher_scripts/conf/config.yaml :
    1. Définissez le travail stage sur 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. A partir du répertoire launcher_scripts, exécutez main.py pour soumettre le travail à 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 obtenir le statut du travail d'observateur.
    $ 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 travaux avec le statut R indiquent que certains travaux sont en cours d'exécution. D'autres travaux affichés attendent des ressources ou attendent que d'autres travaux se terminent en premier (dépendances).

    Consultez results/download_gpt3_pile/download pour voir la sortie des travaux terminés et en cours d'exécution. Vous pouvez également trouver le script bash qui a été utilisé pour soumettre les travaux Slurm. Le script et la sortie peuvent être utiles pour le dépannage des 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 shards de données peuvent être mis en parallèle sur jusqu'à 30 noeuds.

Formation

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

  1. Modifiez launcher_scripts/conf/config.yaml :
    1. Définissez le travail stage sur 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 notez 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. Dans le répertoire launcher_scripts, exécutez main.py pour soumettre le travail à Slurm. Utilisez la commande squeue pour vérifier que le travail 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 visualiser les messages de sortie et d'erreur et surveiller la progression des travaux en cours d'exécution.
    La formation LLM fonctionne si vous voyez des lignes similaires à celle-ci 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 temps d'étape beaucoup plus rapides peuvent être obtenus avec plus de GPU dans le cluster.