NVIDIA
NVIDIA
Transformer for PyTorch
Resource
NVIDIA
NVIDIA
Transformer for PyTorch

This implementation of Transformer model architecture is based on the optimized implementation in Fairseq NLP toolkit.

The performance measurements in this document were conducted at the time of publication and may not reflect the performance achieved from NVIDIA's latest software release. For the most up-to-date performance measurements, go to NVIDIA Data Center Deep Learning Product Performance.

Benchmarking

The following section shows how to run benchmarks measuring the model performance in training and inference modes.

Training performance benchmark

To benchmark the training performance on a specific batch size, run train.py training script. Performance in tokens/s will be printed to standard output every N iterations, specified by the --log-interval option. Additionally performance and loss values will be logged by dllogger to the file specified in --stat-file option. Every line in the output file will be a valid JSON file prepended with DLLL prefix.

Inference performance benchmark

To benchmark the inference performance on a specific batch size, run following command to start the benchmark

for i in {1..10}; do sacrebleu -t wmt14/full -l en-de --echo src; done | python inference.py --buffer-size 5000 --path /path/to/your/checkpoint.pt --max-tokens 10240 --fuse-dropout-add --remove-bpe --bpe-codes /data/code --fp16 > /dev/null

Results will be printed to stderr.

Results

The following sections provide details on how we achieved our performance and accuracy in training and inference.

Training accuracy results

Following the spirit of the paper A Call for Clarity in Reporting BLEU Scores we decided to change evaluation metric implemented in fairseq to SacreBleu score. We have calculated that the new metric has almost linear relationship with the old one. We run linear regression on nearly 2000 checkpoints to discover that the SacreBleu score almost perfectly follows the formula: newScore = 0.978 * oldScore - 0.05.


Figure 2. Linear relationship between old and new BLEU metric.

To take into account the varibaility of the results we computed basic statistics that help us verify whether a model trains correctly. Evaluating nearly 2000 checkpoints from 20 runs, the best score we achieved is 28.09 BLEU (which corresponds to 28.77 old score). Variance of the score of the best performing model between those 20 runs is 0.011. Knowing that max statistic is skewed toward higher values we have also run studies which calculate threshold beyond which validation loss is no longer correlated with BLEU score. Of course our hope is that dev's set distribution is similar to test's set distribution and when validation loss drops, BLEU score rises. But due to the finiteness of the validation and test sets we expect that there is such a loss value that makes performance on both sets decoupled from each other. To find this point we used Pearson correlation coefficient as a metric. The results indicate that optimizing beyond 4.02 validation loss value is no longer beneficial for the BLEU score. Further optimization does not cause overfitting but results become stochastic. Mean BLEU score after reaching 4.02 validation loss is 27.38. We observe variance of 0.08, which translate to nearly 0.3 BLEU average difference between mean score and obtained score.


Figure 3. Validation loss vs BLEU score. Plots are trimmed to certain validation loss threshold.

Training accuracy: NVIDIA DGX A100 (8x A100 40GB)

Our results were obtained by running the run_DGXA100_AMP_8GPU.sh and run_DGXA100_TF32_8GPU.sh training scripts in the pytorch-20.06-py3 NGC container on NVIDIA DGX A100 (8x A100 40GB) GPUs. We report average accuracy over 6 runs. We consider a model trained when it reaches minimal validation loss. Time to train contains only training time without validation. Depending on a configuration and frequency of validation it can take up to additional minute per epoch.

GPUsBatch size / GPUAccuracy - TF32Accuracy - mixed precisionTime to train - TF32Time to train - mixed precisionTime to train speedup (TF32 to mixed precision)
81024027.9227.762.87 hours2.79 hoursx1.03
Training accuracy: NVIDIA DGX-1 (8x V100 16GB)

Our results were obtained by running the run_DGX1_AMP_8GPU.sh and run_DGX1_FP32_8GPU.sh training scripts in the pytorch-20.06-py3 NGC container on NVIDIA DGX-1 (8x V100 16GB) GPUs. We report average accuracy over 6 runs. We consider a model trained when it reaches minimal validation loss. Time to train contains only training time without validation. Depending on a configuration and frequency of validation it can take up to additional minute per epoch. Using mixed precision we could fit a larger batch size in the memory, further speeding up the training.

GPUsBatch size / GPUAccuracy - FP32Accuracy - mixed precisionTime to train - FP32Time to train - mixed precisionTime to train speedup (FP32 to mixed precision)
85120/256027.6627.8212 hours4.6 hoursx2.64

Training performance results

Training performance: NVIDIA DGX A100 (8x A100 40GB)

Our results were obtained by running the run_DGXA100_AMP_8GPU.sh and run_DGXA100_TF32_8GPU.sh training scripts in the pytorch-20.06-py3 NGC container on NVIDIA DGX A100 (8x A100 40GB) GPUs. Performance numbers (in tokens per second) were averaged over an entire training epoch.

GPUsBatch size / GPUThroughput - TF32Throughput - mixed precisionThroughput speedup (TF32 - mixed precision)Weak scaling - TF32Weak scaling - mixed precision
810240316913582721x1.846.937.05
410240161980298741x1.843.543.62
1102404575582618x1.8111

To achieve these same results, follow the steps in the Quick Start Guide.

Training stability test

The following plot shows average validation loss curves for different configs. We can see that training with AMP O2 converges slightly slower that FP32 and TF32 training. In order to mitigate this, you can use option --amp-level O1 at the cost of 20% performance drop compared to the default AMP setting.


Figure 4. Validation loss curves

Training performance: NVIDIA DGX-1 (8x V100 16GB)

Our results were obtained by running the run_DGX1_AMP_8GPU.sh and run_DGX1_FP32_8GPU.sh training scripts in the pytorch-20.06-py3 NGC container on NVIDIA DGX-1 with (8x V100 16GB) GPUs. Performance numbers (in tokens per second) were averaged over an entire training epoch. Using mixed precision we could fit a larger batch size in the memory, further speeding up the training.

GPUsBatch size / GPUThroughput - FP32Throughput - mixed precisionThroughput speedup (FP32 - mixed precision)Weak scaling - FP32Weak scaling - mixed precision
85120/256058742223245x3.806.916.67
45120/256029674115269x3.883.493.44
15120/2560849833468x3.9411

To achieve these same results, follow the steps in the Quick Start Guide.

Training performance: NVIDIA DGX-2 (16x V100 32GB)

Our results were obtained by running the run_DGX1_AMP_8GPU.sh and run_DGX1_FP32_8GPU.sh training scripts setting number of GPUs to 16 in the pytorch-20.06-py3 NGC container on NVIDIA DGX-2 with (16x V100 32GB) GPUs. Performance numbers (in tokens per second) were averaged over an entire training epoch. Using mixed precision we could fit a larger batch size in the memory, further speeding up the training.

GPUsBatch size / GPUThroughput - FP32Throughput - mixed precisionThroughput speedup (FP32 - mixed precision)Weak scaling - FP32Weak scaling - mixed precision
1610240/5120130867510267x3.913.3812.7
810240/512068829269464x3.917.046.71
410240/512035168141143x4.013.63.51
110240/5120977940163x4.1111

To achieve these same results, follow the steps in the Quick Start Guide.

Inference performance results

Our implementation of the Transformer has dynamic batching algorithm, which batches sentences together in such a way that there are no more than N tokens in each batch or no more than M sentences in each batch. In this benchmark we use the first option in order to get the most stable results.

Inference performance: NVIDIA DGX A100 (1x A100 40GB)

Our results were obtained by running the inference.py inferencing benchmarking script in the pytorch-20.06-py3 NGC container on NVIDIA DGX A100 (1x A100 40GB) GPU.

FP16

Batch sizeThroughput AvgLatency AvgLatency 90%Latency 95%Latency 99%
1024096530.986s1.291s2.157s2.167s
256050920.504s0.721s0.830s1.752s
102425900.402s0.587s0.666s0.918s
51213570.380s0.561s0.633s0.788s
2567210.347s0.513s0.576s0.698s

TF32

Batch sizeThroughput AvgLatency AvgLatency 90%Latency 95%Latency 99%
1024077551.227s1.592s2.512s2.525s
256046240.555s0.786s0.872s1.886s
102423940.435s0.627s0.702s0.881s
51212750.405s0.586s0.663s0.821s
2566770.370s0.546s0.613s0.733s

To achieve these same results, follow the steps in the Quick Start Guide.

Inference performance: NVIDIA DGX-1 (1x V100 16GB)

Our results were obtained by running the inference.py inferencing benchmarking script in the pytorch-20.06-py3 NGC container on NVIDIA DGX-1 with (1x V100 16GB) GPU.

FP16

Batch sizeThroughput AvgLatency AvgLatency 90%Latency 95%Latency 99%
1024074641.283s1.704s1.792s1.801s
256035960.719s1.066s1.247s1.423s
102418620.563s0.857s0.936s1.156s
51210030.518s0.782s0.873s1.103s
2565200.484s0.723s0.813s0.992s

FP32

Batch sizeThroughput AvgLatency AvgLatency 90%Latency 95%Latency 99%
1024037822.531s3.091s3.121s3.136s
256029100.888s1.221s1.252s1.432s
102415160.692s1.001s1.126s1.297s
5129410.551s0.812s0.893s1.133s
2565020.501s0.734s0.822s0.978s

To achieve these same results, follow the steps in the Quick Start Guide.