此处给出了基于 NGC TensorFlow 实现的 Bert Base Pre-Training 任务的详细复现流程,包括执行环境、TensorFlow版本、环境搭建、复现脚本、测试结果和测试日志。
我们使用了同一个物理机环境,对 NGC TensorFlow 的 Bert 模型进行了测试,详细物理机配置,见Paddle Bert Base 性能测试。
-
单机(单卡、8卡)
- 系统:CentOS release 7.5 (Final)
- GPU:Tesla V100-SXM2-32GB * 8
- CPU:Intel(R) Xeon(R) Gold 6271C CPU @ 2.60GHz * 80
- Driver Version: 470.83.01
- 内存:630 GB
-
多机(32卡)
- 系统:CentOS release 6.3 (Final)
- GPU:Tesla V100-SXM2-32GB * 8
- CPU:Intel(R) Xeon(R) Gold 6271C CPU @ 2.60GHz * 48
- Driver Version: 450.80.02
- 内存:502 GB
NGC TensorFlow 的代码仓库提供了自动构建 Docker 镜像的的 shell 脚本,
- 镜像版本:
nvcr.io/nvidia/tensorflow:20.06-tf1-py3
- TensorFlow 版本:
1.15.2+nv
- CUDA 版本:
11.0
- cuDnn 版本:
8.0.1
我们遵循了 NGC TensorFlow 官网提供的 Quick Start Guide 教程成功搭建了测试环境,主要过程如下:
-
拉取代码
git clone https://github.com/NVIDIA/DeepLearningExamples cd DeepLearningExamples/TensorFlow/LanguageModeling/BERT # 本次测试是在如下版本下完成的: git checkout 4a15e9146a6516941ba3ae146621a5c94e4bc431
-
构建镜像
bash scripts/docker/build.sh # 构建镜像 bash scripts/docker/launch.sh # 启动容器
我们将
launch.sh
脚本中的docker
命令换为了nvidia-docker
启动的支持 GPU 的容器,其他均保持不变,脚本如下:#!/bin/bash CMD=${@:-/bin/bash} NV_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES:-"all"} nvidia-docker run --name=test_tf_bert -it \ --net=host \ --shm-size=1g \ --ulimit memlock=-1 \ --ulimit stack=67108864 \ -e NVIDIA_VISIBLE_DEVICES=$NV_VISIBLE_DEVICES \ -v $PWD:/workspace/bert \ -v $PWD/results:/results \ bert $CMD
-
准备数据
NGC TensorFlow 提供单独的数据下载和预处理脚本 data/create_datasets_from_start.sh。在容器中执行如下命令,可以下载和制作
wikicorpus_en
的 tfrecord 数据集。bash data/create_datasets_from_start.sh wiki_only
由于数据集比较大,且容易受网速的影响,上述命令执行时间较长。因此,为了更方便复现竞品的性能数据,我们提供了已经处理好的 tfrecord 格式样本数据集。
下载后的数据集需要放到容器中
/workspace/bert/data/
目录下,并修改scripts/run_pretraining_lamb_phase1.sh的第81行的数据集路径,如:# 解压数据集 tar -xzvf benchmark_sample_tfrecord.tar.gz # 放到 data/目录下 mv benchmark_sample_tfrecord bert/data/tfrecord # 修改 run_pretraining_lamb_phase1 L81 行数据集路径 INPUT_FILES="$DATA_DIR/tfrecord/lower_case_1_seq_len_${seq_len}_max_pred_${max_pred_per_seq}_masked_lm_prob_0.15_random_seed_12345_dupe_factor_5_shard_1472_test_split_10/wikicorpus_en/training" EVAL_FILES="$DATA_DIR/tfrecord/lower_case_1_seq_len_${seq_len}_max_pred_${max_pred_per_seq}_masked_lm_prob_0.15_random_seed_12345_dupe_factor_5_shard_1472_test_split_10/wikicorpus_en/test"
为了更准确的测试 NGC TensorFlow 在 NVIDIA DGX-1 (8x V100 32GB)
的性能数据,我们严格按照官方提供的模型代码配置、启动脚本,进行了的性能测试。
官方提供的 scripts/run_pretraining_lamb.sh 执行脚本中,默认配置的是两阶段训练。我们此处统一仅执行 第一阶段训练,并根据日志中的输出的数据计算吞吐。因此我们注释掉了scripts/run_pretraining_lamb.sh的60行:
# RUN PHASE 2
# bash scripts/run_pretraining_lamb_phase2.sh $SCRIPT_ARGS |& tee -a $LOGFILE
重要的配置参数:
- train_batch_size_phase1: 用于指定每张卡上的 batch_size 数目
- precision: 用于指定精度训练模式,fp32 或 fp16
- use_xla: 是否开启 XLA 加速,我们统一开启此选项
- num_gpus: 用于指定 GPU 卡数
- bert_model: 用于指定 Bert 模型,我们统一指定为 base
为了更方便地测试不同 batch_size、num_gpus、precision组合下的 Pre-Training 性能,我们单独编写了 run_benchmark.sh
脚本,并放在scripts
目录下。
-
shell 脚本内容如下:
#!/bin/bash set -x batch_size=$1 # batch size per gpu num_gpus=$2 # number of gpu precision=$3 # fp32 | fp16 num_accumulation_steps_phase1=$(expr 67584 \/ $batch_size \/ $num_gpus) train_steps=${4:-200} # max train steps bert_model=${5:-"base"} # base | large # run pre-training bash scripts/run_pretraining_lamb.sh $batch_size 64 8 7.5e-4 5e-4 $precision true $num_gpus 2000 200 $train_steps 200 $num_accumulation_steps_phase1 512 $bert_model
注:由于原始 global_batch_size=65536 对于 batch_size=48/96 时出现除不尽情况。因此我们按照就近原则,选取 67584 作为 global_batch_size.
计算公式:global_batch_size = batch_size_per_gpu * num_gpu * num_accumulation_steps -
单卡启动脚本:
若测试单机单卡 batch_size=96、FP32 的训练性能,执行如下命令:
bash scripts/run_benchmark.sh 96 1 fp32
-
8卡启动脚本:
若测试单机8卡 batch_size=96、FP16 的训练性能,执行如下命令:
bash scripts/run_benchmark.sh 96 8 fp16
基础配置和上文所述的单机配置相同,多机这部分主要侧重于多机和单机的差异部分。
NGC TensorFlow BERT使用MPI管理作业进程,内部使用Horovod作为分布式通信框架。
另:多机测试时,是否使用gradient accumulation
对 性能影响很大。为了方便区分,我们同时测试了打开(默认打开)和关闭(W/O AccGrad)两种情况。关闭的测试方法为:设置num_accumulation_steps_phase1
为"false",同时设置allreduce_post_accumulation
为 "False"。
卡数 | FP32(BS=32) | AMP(BS=96) |
---|---|---|
1 | 156.33 | 530.28 |
8 | 1231.74 | 4181.32 |
32 | 4379.4 | 16554.3 |
32[W/O AccGrad] | 2943.8 | 12767.2 |