NCCL通信パターン解析器
このツールでは、実行中にアプリケーションのNCCL通信パターンを解析できます。
使い方
# 1. NCCLログありでアプリケーションを実行し、ログ出力を保存しておく
$ NCCL_DEBUG=INFO NCCL_DEBUG_SUBSYS=ALL TORCH_DISTRIBUTED_DEBUG=DETAIL /path/to/application_you_want_to_analyze | tee out.log
# 2. 保存されたログからパターンを解析する
$ cd <AIBoosterパッケージをcloneした場所>/observability/nccl/pattern_analyzer
$ python nccl_pattern_analyzer.py /path/to/out.log
routine,num_samples,datatype,nranks,ALGO,PROTOCOL,TOTALBYTES,TIME_FOR_EACH_NCCL_COMM_CALL_MICROSEC
allreduce,1,float32,8,Ring,LL,4,15.00005
allreduce,262144,float32,8,Ring,LL,1048576,28.01424
allreduce,524288,float32,8,Nvls,Simple,2097152,32.864319
allreduce,1048576,float32,8,Nvls,Simple,4194304,40.728642
allreduce,2097152,float32,8,Nvls,Simple,8388608,56.457283
allreduce,4194304,float32,8,Nvls,Simple,16777216,87.914566
allreduce,8388608,float32,8,Nvls,Simple,33554432,150.829132
allreduce,16777216,float32,8,Nvls,Simple,67108864,276.658264
allreduce,33554432,float32,8,Nvls,Simple,134217728,528.316528
allreduce,67108864,float32,8,Nvls,Simple,268435456,1031.633057
allreduce,134217728,float32,8,Nvls,Simple,536870912,2038.265991
allreduce,268435456,float32,8,Nvls,Simple,1073741824,4051.531982
allreduce,536870912,float32,8,Nvls,Simple,2147483648,8078.063965
allreduce,1073741824,float32,8,Nvls,Simple,4294967296,16131.12793
allreduce,2147483648,float32,8,Nvls,Simple,8589934592,32237.255859
allreduce,4294967296,float32,8,Nvls,Simple,17179869184,64449.511719
解析結果の解説
実行結果はCSV形式で以下のように標準出力に表示されます
routine,num_samples,datatype,nranks,ALGO,PROTOCOL,TOTALBYTES,TIME_FOR_EACH_NCCL_COMM_CALL_MICROSEC
allreduce,8388608,float32,8,Nvls,Simple,33554432,150.829132
allreduce,16777216,float32,8,Nvls,Simple,67108864,276.658264
allreduce,33554432,float32,8,Nvls,Simple,134217728,528.316528
各行が、今回実行したアプリケーションで用いられたNCCL通信のパターンを示しています。例えば
allreduce,16777216,float32,8,Nvls,Simple,67108864,276.658264
の行は以下を意味しています。
- 通信ルーチン名は、
allreduce
(全縮約)だった - 通信要素数は、
16777216
個だった - 使用されたデータ型は、
float32
だった - 通信が発生したGPU数は、
8
個だっった - 使われた通信アルゴリズムは、
NVLS
だった - 使われたプロトコルは、
Simple
だった - 通信したデータ長は、
67108864
バイトだった - 1回の通信にかかる推定時間は、
276.658264
マイクロ秒だった- なお、使用しているNCCLのバージョンによっては、この値が抽出できない場合があります
使用例
具体例として、MDKのMegatron-LMを用いた事前学習のうち、シングルノード実行で発生するNCCL通信パターンを解析してみる場合について解説します。
0. 通常の手順で実行できることを確認する
まずは何もしない素の状態で、ハウツーに記載されている手順に従ってシングルノード実行ができることを確認してください。
mpirun /opt/singularity/bin/singularity exec --nv ./pytorch.sif bash examples/gpt3/train_gpt3_7b_mpi.sh ./checkpoint_1node ./tensorboard ./gpt2/vocab.json ./gpt2/merges.txt ./arxiv_text_document
1. NCCLログ付きで実行する
次に冒頭の手順に従って、ログNCCL_DEBUG=INFO NCCL_DEBUG_SUBSYS=ALL TORCH_DISTRIBUTED_DEBUG=DETAIL
をつけて同じコマンドを実行し、| tee out.log
で標準出力を保存しておきます。
NCCL_DEBUG=INFO NCCL_DEBUG_SUBSYS=ALL TORCH_DISTRIBUTED_DEBUG=DETAIL mpirun /opt/singularity/bin/singularity exec --nv ./pytorch.sif bash examples/gpt3/train_gpt3_7b_mpi.sh ./checkpoint_1node ./tensorboard ./gpt2/vocab.json ./gpt2/merges.txt ./arxiv_text_document | tee out.log
学習中に大量のNCCLログが表示されつつ実行が完了するのを待ちます。
なお、学習中は基本的にすべてのイテレーションでは処理内容が同じであることが分かっていますので、学習スクリプト内の--train-iters
などを少なく調整しても構いません。
ここでは20イテレーションに制限して実行し、次に進みます。
2. 解析する
このディレクトリに戻ってきて、解析を実行します
$ cd <AIBoosterパッケージをcloneした場所>/observability/nccl/pattern_analyzer
$ python nccl_pattern_analyzer.py ../../../mdk/outputs/Megatron-LM/out.log
routine,num_samples,datatype,nranks,ALGO,PROTOCOL,TOTALBYTES,TIME_FOR_EACH_NCCL_COMM_CALL_MICROSEC
allgather,1,float32,8,Ring,LL,32,10.800199
allgather,2,float32,8,Ring,LL,64,10.800397
allgather,24,float32,8,Ring,LL,768,10.804766
allgather,5571584,float16,8,Ring,Simple,89145344,248.872696
allgather,8389632,float16,8,Ring,Simple,134234112,358.46347
allgather,11141120,float16,8,Ring,Simple,178257920,465.465759
allgather,25755648,float16,8,Ring,Simple,412090368,1033.808472
allgather,27853824,float16,8,Ring,Simple,445661184,1115.404175
allreduce,1,uint8,8,Ring,LL,1,15.000012
allreduce,1,float32,8,Ring,LL,4,15.00005
allreduce,1,float64,8,Ring,LL,8,15.000099
allreduce,2,float32,8,Ring,LL,8,15.000099
broadcast,3,int64,8,Ring,LL,24,7.20017
reducescatter,5571584,float16,8,Ring,Simple,89145344,248.872696
reducescatter,8389632,float16,8,Ring,Simple,134234112,358.46347
reducescatter,11141120,float16,8,Ring,Simple,178257920,465.465759
reducescatter,25755648,float16,8,Ring,Simple,412090368,1033.808472
reducescatter,27853824,float16,8,Ring,Simple,445661184,1115.404175
3. 結果の考察
上記の結果から、以下のようなことが分かります
- 通信は4ルーチン(allgather, allreduce, broadcast, reducescatter)がある
- allgatherとreducescatterが大きく400[MB]程度の通信をしている
- allreduce, broadcastは細かい通信なので考えなくて良い