数据中心/云端

重现 NVIDIA MLPerf v5.0 的 LLM 基准测试训练成绩

 

预备知识

运行 NVIDIA 基准测试时,您的系统需要具备以下内容:

  • 容器准备、数据集/ 检查点下载和预处理 Docker Hugging Face 访问令牌 (用于数据集/ 检查点下载) Llama 3.1 至少有 2.5 TB 的磁盘空间,LoRA 微调需要 300 GB
  • 硬件要求 Llama 2 70B LoRA:NVIDIA DGX B200 或 NVIDIA GB200 NVL72 系统,或多个通过 InfiniBand 连接的 GB200 NVL72 系统,可实现超过 72 个 GPU 的扩展。NVIDIA 针对此基准测试提交的最小数据是 8 个 GPU。 Llama 3.1 405B:至少四个 GB200 NVL72 系统通过 InfiniBand 连接。NVIDIA 针对此基准测试提交的最小数据是 256 个 GPU。

集群设置

运行 NVIDIA MLPerf 训练基准测试需要:

  • 基于 Slurm、Pyxis 和 Enroot 的环境
  • 使用 NVIDIA NVLink 和 InfiniBand 进行网络建设
  • 在 RAID0 配置中快速设置本地存储,以更大限度地减少数据加载瓶颈

NVIDIA 提交集群不支持使用 Docker 运行工作负载。这些集群由 NVIDIA Base Command Manager (BCM) 管理。按照官方说明正确设置 BCM SLURM 集群

正确设置后,您应能登录头节点并访问 SLURM 命令 ( sinFO、squeue、srun、sbatch) 以在计算节点上启动作业。

运行基准测试

开始对任何模型进行基准测试所需的步骤包括:

  1. Build a Docker container.
  2. 使用 Docker 在任何计算机上运行容器,以下载和处理数据集和检查点。此步骤可以在任何机器上完成,无论是否在集群中,通常不需要配备 GPU 的系统。确保计算节点可以访问数据。数据最好存储在节点的本地;或者,可以通过快速 (并行) 文件系统进行访问。
  3. 启动训练并解析日志。

Llama 2 70B LoRA

要运行 Llama 2 70B LoRA 的基准测试,请按照本节中的说明操作。

创建容器

  • cd NVIDIA/ benchmarks/ llama2_70b_lora/ implementations/ tyche_ngpu72_ngc25.04_nemo
  • Docker build -t mlperf-nvidia:llama2_70b_lora-pyt。如果您有要推送镜像的注册表,请将注册表名称添加到镜像名称中。

下载数据集和模型

此基准测试使用了政府报告数据集和 Hugging Face 检查点。NVIDIA NeMo 需要对数据集和检查点进行预处理。您需要 Hugging Face 令牌才能下载检查点。

如需下载并预处理,请执行以下操作:

# create a directory where the data will be stored
mkdir </path/to/dataset>
# start the docker container 
docker run -it --rm --gpus all --network=host --ipc=host --volume </path/to/dataset>:/data mlperf-nvidia:llama2_70b_lora-pyt
# now you should be inside the container in the /workspace/ft-llm directory. run the download scripts
python scripts/download_dataset.py --data_dir /data/gov_report  # download dataset
python scripts/download_model.py --model_dir /data/model  # download preprocessed model checkpoint in NeMo format used for initialization; could take up to 30 minutes

如果模型下载失败,您可能需要先导出 HF_TOKEN,然后再调用 download_model.py 脚本:

export HF_TOKEN=<your/huggingface/token>

转换后,您应在/data 目录下看到以下文件:

/data
├── gov_report
│   ├── train.npy
│   └── validation.npy
└── model
    ├── context
    │   ├── io.json
    │   ├── model.yaml
    │   └── nemo_tokenizer
    └── weights
        ├── common.pt
        ├── metadata.json
        ├── module.decoder.final_layernorm._extra_state
        ├── module.decoder.final_layernorm.weight
        ├── module.decoder.layers.mlp.linear_fc1._extra_state
        ├── module.decoder.layers.mlp.linear_fc1.layer_norm_weight
        ├── module.decoder.layers.mlp.linear_fc1.weight
        ├── module.decoder.layers.mlp.linear_fc2._extra_state
        ├── module.decoder.layers.mlp.linear_fc2.weight
        ├── module.decoder.layers.self_attention.core_attention._extra_state
        ├── module.decoder.layers.self_attention.linear_proj._extra_state
        ├── module.decoder.layers.self_attention.linear_proj.weight
        ├── module.decoder.layers.self_attention.linear_qkv._extra_state
        ├── module.decoder.layers.self_attention.linear_qkv.layer_norm_weight
        ├── module.decoder.layers.self_attention.linear_qkv.weight
        ├── module.embedding.word_embeddings.weight
        └── module.output_layer.weight

此时,您可以退出容器。

启动基准测试

NVIDIA 使用 SLURM 在计算节点上启动基准测试。两个文件用于促进作业启动过程:

  1. 配置文件 (config_*.sh) ,用于描述模型的超参数,包括节点数量、墙面时间等。通过将每个提交的内容整理成一个文件,可以轻松配置工作负载,以便使用最佳超参数以所需规模运行。
  2. 一个固定的 run.sub 文件,其中包含用于启动训练的 srun 命令,并将配置中的所有超参数传递到 Python 脚本。

如要查看典型的配置文件 (本例中为 config_GB200_18x4x1xtp1pp1cp8.sh) ,其名称将描述系统的大小和类型:

  • GB200:设计为在 GB200 计算机上运行
  • 18 4:可解码为 NNODES x NGPUS 的系统设置 节点数量:GB200 节点数量 NGPUS:每个节点的 GPU 数量
  • x1xtp1pp1cp8 是并行化模式 x1 表示 GradientAccumulation,此处等于 1,表示无 GA TP1:无 TensorParallel PP1:无 PipelineParallel CP8:8 路 ContextParallel

这意味着将使用 72-GPU 配置,在单个 GB200 NVL72 机架上运行。基准测试将运行 GA1TP1PP1CP8:全局批量大小 (GBS) = 9。

接下来,仔细查看配置文件的内容。第一部分来自 config_common.sh,其中包含所有配置使用的超参数和优化标志。某些情况下会覆盖 config_common.sh 中的标志。设置最大步长、学习率、梯度累积 (MINIBS) 和上述并行化模式。

#!/bin/bash
source $(dirname ${BASH_SOURCE[0]})/config_common.sh

# hyperparameters
export MAX_STEPS=800
export LR=0.0005
export MINIBS=1
export TP=1
export SP=0
export CP=8

下一节将添加系统特定的优化,并在需要时覆盖通用标志。

export LAYER_CUDA_GRAPH=0
export MCORE_CUDA_GRAPH=1

接下来是要传递给 SLURM 的系统级设置。

# system parameters
export VBOOST_VALUE=0
export DGXNNODES=18
export DGXNGPU=4
export WALLTIME_RUNANDTIME=10
export WALLTIME=$((5 + ${NEXP:-1} * ($WALLTIME_RUNANDTIME + 5)))

正在针对特定系统大小调整配置,包括优化标志 (影响性能) 和超参数 (影响收) 。可以修改给定配置以在不同大小的系统上运行,但这需要仔细考虑,并且不能保证性能与原始配置一样出色。

要开始实际训练,您需要告知脚本数据集/ 模型的位置、日志文件的存储位置、要使用的容器、源配置文件,然后运行 sbatch 命令:

export DATADIR="</path/to/dataset>/gov_report"  # set your </path/to/dataset>
export MODEL="</path/to/dataset>/model"  # set your </path/to/dataset>
export LOGDIR="</path/to/output_logdir>"  # set the place where the output logs will be saved
export CONT=mlperf-nvidia:llama2_70b_lora-pyt
source config_<system>.sh  # select config and source it
sbatch -N $DGXNNODES -t $WALLTIME run.sub  # you may be required to set --account and --partition here

解析日志

日志文件将包含初始化和其他信息行的大量输出。MLPerf 相关行以 MLPerf logger 前缀 :::MLLOG 开头。有一些有趣的标记,如下所示。

Initialization starts:

:::MLLOG {"namespace": "", "time_ms": 1745066769306, "event_type": "INTERVAL_START", "key": "init_start", "value": null, "metadata": {"file": "/workspace/ft-llm/train.py", "lineno": 327}}

在这里,您可以看到 Python 脚本已启动。下面,您可以看到使用配置文件选择的超参数以及默认 (不可变) 参数。

初始化完成,模型预热后,打印出 init_stop 和 tg_ 16 标记:

:::MLLOG {"namespace": "", "time_ms": 1745066917960, "event_type": "INTERVAL_END", "key": "init_stop", "value": null, "metadata": {"file": "/usr/local/lib/python3.12/dist-packages/mlperf_common/callbacks/logging.py", "lineno": 83}}
:::MLLOG {"namespace": "", "time_ms": 1745066917961, "event_type": "INTERVAL_START", "key": "run_start", "value": null, "metadata": {"file": "/usr/local/lib/python3.12/dist-packages/mlperf_common/callbacks/logging.py", "lineno": 83}}

run_start 行表示计时时钟的开始。以下行显示了训练的进度,包括评估。您可以看到,评估损失正在减少,由 eval_accuracy 标记标记。

当评估精度 (现实中的评估损失) 降至值 0.925 以下时,训练停止并打印 run_stop 标记:

:::MLLOG {"namespace": "", "time_ms": 1745067009412, "event_type": "POINT_IN_TIME", "key": "eval_accuracy", "value": 0.92474365234375, "metadata": {"file": "/usr/local/lib/python3.12/dist-packages/mlperf_common/callbacks/logging.py", "lineno": 303, "samples_count": 3024}}
…
:::MLLOG {"namespace": "", "time_ms": 1745067009420, "event_type": "INTERVAL_END", "key": "run_stop", "value": null, "metadata": {"file": "/usr/local/lib/python3.12/dist-packages/mlperf_common/callbacks/logging.py", "lineno": 106, "samples_count": 3024, "status": "success"}}

如果基准测试收失败,run_stop 状态将显示为`aborted`。MLPerf 分数是 run_stop 和 tg_ 23 的时间之间的差值。在本例中:

分数【毫秒】= (1745067009420 – 1745066917961) 91459 分数【分钟】= 91459/ 60000 = 1.524

请记住,由于收是非确定性的,因此必须从多次运行中推导出最终分数,因为要收的样本数量可能会有所不同。在这里,基准测试收于 3072 个样本,而平均而言,它应该收于大约 3100-3200 个样本。

Llama 3.1 405B

要运行 Llama 3.1 405B 的基准测试,请按照本节中的说明操作。

创建容器

  • cd NVIDIA/ benchmarks/ llama31_405b/ implementations/ tyche_ngpu512_ngc25.04_nemo
  • docker build -t mlperf-nvidia:large_language_model-pyt。如果您有想要推送镜像的注册表,请随时将注册表名称添加到镜像名称中。

下载数据集和模型

有关如何下载数据集和分词器的说明,请参阅 Llama 3.1 405B 参考自述文件

环境变量 PREPROCESSED_PATH 指向预处理的数据集。下载的文件应以 .idx 和 .bin 结尾。

c4-train.en_&lt;number&gt;_text_document where number belongs to 0~7.
c4-validation-91205-samples

环境变量 TOKENIZER_PATH 指向此基准测试中使用的分词器。下载的文件包括:

special_tokens_map.json
tokenizer.json
tokenizer.model
tokenizer.model.v1
tokenizer_config.json

您可以通过运行清理脚本来清理不必要的文件:

bash scripts/cleanup.sh

最终的 PREPROCESSED_PATH 目录应包含:

c4-train.en_6_text_document.bin
c4-train.en_6_text_document.idx
c4-train.en_7_text_document.bin
c4-train.en_7_text_document.idx
c4-validation-91205-samples.en_text_document.bin
c4-validation-91205-samples.en_text_document.idx

检查点

在基准测试区域,通过 Meta 官方 Hugging Face 检查点恢复训练。请参考参考 README 中的说明下载 BF16 模型检查点。请注意,在继续之前,请确保您当前的工作目录能够容纳 > 1.5 TB 的数据。

假设您在给定目录下运行下载命令,其位置存储在 LOAD_CHECKPOINTS_PATH 环境变量下。下载检查点后,您应能找到一个 405B 文件夹,其中包含当前目录下的上下文和权重子文件夹:

&lt;LOAD_CHECKPOINTS_PATH&gt;
└── 405b
	├── context
	│   ├── nemo_tokenizer
	│   │   ├── special_tokens_map.json
	│   │   ├── tokenizer_config.json
	│   │   └── tokenizer.json
	│   ├── io.json
	│   └── model.yaml
	└── weights
    	├── __0_0.distcp
    	├── __0_1.distcp
    	├── .metadata
    	├── common.pt
    	└── metadata.json

启动基准测试

NVIDIA 使用 SLURM 在计算节点上启动基准测试。为简化作业启动过程,与 Llama 2 70B LORA 类似,使用了两个文件:

  1. 配置文件 (config_*.sh) ,用于描述模型的超参数,包括节点数量、墙面时间等。通过选择合适的文件,您可以轻松配置工作负载,使其使用最佳超参数以所需规模运行。
  2. 一个固定的 run.sub 文件,其中包含用于启动训练的 srun 命令,并将配置中的所有超参数传递到 Python 脚本。

要查看典型的配置文件 (在本例中为 config_GB200_128x4x112xtp4pp8cp2_cg_dplast.sh) ,其名称描述了系统的大小和类型:

  • GB200:设计为在 GB200 计算机上运行
  • 128 4:可解码为 NNODES x NGPUS 的系统设置 节点数量:GB200 节点数量 NGPUS:每个节点的 GPU 数量
  • x112xtp4pp8cp2 是并行化模式: x112 表示 GradientAccumulation,此处等于 112 TP4:4 路 TensorParallel PP8:8 路 PipelineParallel CP2:2 路 ContextParallel

这意味着将在 8 个 GB200 NVL72 机架上运行 512-GPU 配置,每个机架使用 64 个 GPU。基准测试将运行 GA112TP4PP8CP2:全局批量大小 (GBS) = 896。

为了更深入地了解配置文件的内容,第一部分源配置包含以下各项使用的超参数和优化标志:所有配置、使用 Blackwell GPU 的配置以及使用 CUDA 图形的配置。在某些情况下,config_common.sh 中的标志会被覆盖。稍后,设置梯度累积 (MINIBS) 、并行化模式、微批量大小、模型大小 (冻结) 和最大步长。

source $(dirname ${BASH_SOURCE[0]})/config_common.sh 
source $(dirname ${BASH_SOURCE[0]})/config_common_blackwell.sh 
source $(dirname ${BASH_SOURCE[0]})/config_common_cg.sh

export MINIBS=112
export TENSOR_MODEL_PARALLEL=4
export PIPELINE_MODEL_PARALLEL=8
export INTERLEAVED_PIPELINE=8
export CONTEXT_PARALLEL=2
export MICRO_BATCH_SIZE=1
export MODEL_SIZE="405b"
export MAX_STEPS=450

接下来,设置性能优化标志:

export FP8_PARAM_GATHER=True
export TP_COMM_OVERLAP=True
export ASYM_PP_EMBED=True
export ASYM_PP_LOSS=True
export TP_PP_DP_MAPPING=True

# Binding
export BINDCMD="bindpcie --cpu=node"

接下来是要传递给 SLURM 的系统级设置:

export DGXNNODES=128
export DGXNGPU=4
export DGXSYSTEM=$(basename $(readlink -f ${BASH_SOURCE[0]}) | sed 's/^config_//' | sed 's/\.sh$//' )

export WALLTIME_RUNANDTIME=180
export WALLTIME=$((5 + ${NEXP:-1} * ($WALLTIME_RUNANDTIME + 5)))

要开始实际训练,您需要告知脚本数据集/ 检查点的位置、日志文件的存储位置、要使用的容器、源配置文件,然后运行 sbatch 命令:

export PREPROC_DATA="/path/to/your/preprocessed_c4"
export TOKENIZER="/path/to/your/tokenizer.model"
export LOAD_CHECKPOINTS_PATH="/path/to/your/downloaded/checkpoint"
export LOAD_CHECKPOINT="/load_checkpoints/405b"
export LOGDIR=</path/to/output/dir>  # set the place where the output logs will be saved
export CONT=mlperf-nvidia:large_language_model-pyt
source config_GB200_128x4x112xtp4pp8cp2_cg_dplast.sh  # select config and source it
sbatch -N ${DGXNNODES} --time=${WALLTIME} run.sub  # you may be required to set --account and --partition here

解析日志

日志文件应大致类似于 Llama 2 70B LoRA 日志。目标准确度 (评估损失) 为 5.6。一旦达到目标,训练将停止,并打印 run_stop 标记。

 

标签