[DeepSpeed チュートリアル翻訳] 第三に、パフォーマンス デバッグと Flops Profiler チュートリアル翻訳に DeepSpeed で PyTorch Profiler を使用します

0x0.プリアンブル

この翻訳は、https://www.deepspeed.ai/tutorials/pytorch-profiler/ および https://www.deepspeed.ai/tutorials/flops-profiler/ の 2 つのチュートリアル用であり、DeepSpeed トレーニング モデルを使用してベースにすることができます。これら 2 つのチュートリアルでは、プロファイルの作業判断モデルとメモリのボトルネックがどこにあるかを計算します。

0x1. パフォーマンスのデバッグに DeepSpeed で PyTorch Profiler を使用する

元のチュートリアルに対応: https://www.deepspeed.ai/tutorials/pytorch-profiler/

このチュートリアルでは、DeepSpeed で PyTorch Profiler ツール (https://pytorch.org/blog/introducing-pytorch-profiler-the-new-and-improved-performance-tool/) を使用する方法について説明します。

PyTorch Profiler は、大規模な深層学習モデルの正確かつ効率的なパフォーマンス プロファイリングとトラブルシューティングを提供するオープン ソース ツールです。解析結果は.jsonトレースファイルとして出力し、Google Chromeのトレースビューア(chrome://tracing)で確認できます。Microsoft Visual Studio Code の Python 拡張機能は、PyTorch Profiler のサポートを含め、TensorBoard をコード エディターに統合します。詳細については、(https://pytorch.org/tutorials/recipes/recipes/profiler_recipe.html#pytorch-profiler) を参照してください。

プロファイルモデルトレーニングのサイクル

以下は、プロファイラー コンテキスト マネージャーでコードをラップすることによってトレーニング ループをプロファイリングする方法を示しています。プロファイラーは、トレーニング プロセスがステップ (0 から番号付け) で構成されていると想定します。PyTorch Profiler はscheduleon_trace_readywith_stackなどの多くのパラメータを受け入れます。

以下の例では、アナライザーは前の5ステップをスキップし、次の2ステップをウォームアップとして使用し、次の6ステップを記録します。repeat設定されているため2、アナライザーは 2 サイクル後に記録を停止します (ここでのサイクルとは、アクティブなステップ数を繰り返すことを意味しますrepeat)。schedule詳しい使用方法については、「プロファイラーを使用して長時間実行ジョブを分析する」 (https://pytorch.org/tutorials/recipes/recipes/profiler_recipe.html#using-profiler-to-analyze-long-running-jobs) を参照してください。


from torch.profiler import profile, record_function, ProfilerActivity

with torch.profiler.profile(
    schedule=torch.profiler.schedule(
        wait=5, # During this phase profiler is not active.
        warmup=2, # During this phase profiler starts tracing, but the results are discarded.
        active=6, # During this phase profiler traces and records data.
        repeat=2), # Specifies an upper bound on the number of cycles.
    on_trace_ready=tensorboard_trace_handler,
    with_stack=True # Enable stack tracing, adds extra profiling overhead.
) as profiler:
    for step, batch in enumerate(data_loader):
        print("step:{}".format(step))

        #forward() method
        loss = model_engine(batch)

        #runs backpropagation
        model_engine.backward(loss)

        #weight update
        model_engine.step()
        profiler.step() # Send the signal to the profiler that the next step has started.

任意のコード範囲をマークします

record_functionコンテキスト マネージャーを使用して、任意のユーザー指定のコード範囲をマークできます。たとえば、次のコードは「model_forward」をラベルとしてマークします。

with profile(record_shapes=True) as prof: # record_shapes indicates whether to record shapes of the operator inputs.
    with record_function("model_forward"):"
        model_engine(inputs)

その後、プロファイル結果で、マークされた「model_forward」の時間がかかっている状況を確認できます。

CPU/GPUアクティビティをプロファイルする

プロファイラーに渡されるアクティビティ パラメーターは、プロファイラー コンテキスト マネージャーでラップされたコード スコープの実行中にプロファイリングされるアクティビティのリストを指定します。

  • ProfilerActivity.CPU - PyTorch オペレーター、TorchScript 関数、およびユーザー定義コード タグ ( record_function)。
  • ProfilerActivity.CUDA - デバイス上の CUDA カーネル。CUDA プロファイリングは無視できないオーバーヘッドを課すことに注意してください。
    以下の例では、モデルのフォワード パス中に CPU と GPU のアクティビティをプロファイリングし、合計 CUDA 時間でソートされた概要テーブルを出力します。
with profile(activities=[
        ProfilerActivity.CPU, ProfilerActivity.CUDA], record_shapes=True) as prof:
    with record_function("model_forward"):
        model_engine(inputs)

print(prof.key_averages().table(sort_by="cuda_time_total", row_limit=10))

プロファイルのメモリ消費量

PyTorch Profiler に渡すことでprofile_memory=True、モデル OP の実行中に割り当てられた (または解放された) モデル テンソルによって使用されるメモリの量を記録するメモリ プロファイリング機能が有効になります。例えば:

with profile(activities=[ProfilerActivity.CUDA],
        profile_memory=True, record_shapes=True) as prof:
    model(inputs)

print(prof.key_averages().table(sort_by="self_cuda_memory_usage", row_limit=10))

0x2。フロップスプロファイラー

元のチュートリアルに対応: https://www.deepspeed.ai/tutorials/flops-profiler/

このチュートリアルでは、DeepSpeed Flops Profiler を紹介し、その使用例を示します。

概要

ハードウェア リソースを効率的に利用することは、優れたパフォーマンスを実現するために重要ですが、既存の大規模モデルのトレーニングと推論の実装では、パフォーマンスの非効率性を検出するのが難しく、特定のモジュール コンポーネントが原因であることがよくあります。DeepSpeed Flops Profiler は、ユーザーがモデルとそのサブモジュールのトレーニング/推論速度 (レイテンシ、スループット) と効率 (1 秒あたりの浮動小数点演算、つまり FLOPS) を簡単に測定できるようにし、既存の実装における非効率性を排除することを目的としています。

以下は、A100 GPU でバッチ サイズ 80 を使用した BERT-Large (NVIDIA) からの出力例です。

-------------------------- DeepSpeed Flops Profiler --------------------------
Profile Summary at step 10:
Notations:
data parallel size (dp_size), model parallel size(mp_size),
number of parameters (params), number of multiply-accumulate operations(MACs),
number of floating-point operations (flops), floating-point operations per second (FLOPS),
fwd latency (forward propagation latency), bwd latency (backward propagation latency),
step (weights update latency), iter latency (sum of fwd, bwd and step latency)

world size:                                                   1
data parallel size:                                           1
model parallel size:                                          1
batch size per GPU:                                           80
params per gpu:                                               336.23 M
params of model = params per GPU * mp_size:                   336.23 M
fwd MACs per GPU:                                             3139.93 G
fwd flops per GPU:                                            6279.86 G
fwd flops of model = fwd flops per GPU * mp_size:             6279.86 G
fwd latency:                                                  76.67 ms
bwd latency:                                                  108.02 ms
fwd FLOPS per GPU = fwd flops per GPU / fwd latency:          81.9 TFLOPS
bwd FLOPS per GPU = 2 * fwd flops per GPU / bwd latency:      116.27 TFLOPS
fwd+bwd FLOPS per GPU = 3 * fwd flops per GPU / (fwd+bwd latency):   102.0 TFLOPS
step latency:                                                 34.09 us
iter latency:                                                 184.73 ms
samples/second:                                               433.07

----------------------------- Aggregated Profile per GPU -----------------------------
Top modules in terms of params, MACs or fwd latency at different model depths:
depth 0:
    params      - {
    
    'BertForPreTrainingPreLN': '336.23 M'}
    MACs        - {
    
    'BertForPreTrainingPreLN': '3139.93 GMACs'}
    fwd latency - {
    
    'BertForPreTrainingPreLN': '76.39 ms'}
depth 1:
    params      - {
    
    'BertModel': '335.15 M', 'BertPreTrainingHeads': '32.34 M'}
    MACs        - {
    
    'BertModel': '3092.96 GMACs', 'BertPreTrainingHeads': '46.97 GMACs'}
    fwd latency - {
    
    'BertModel': '34.29 ms', 'BertPreTrainingHeads': '3.23 ms'}
depth 2:
    params      - {
    
    'BertEncoder': '302.31 M', 'BertLMPredictionHead': '32.34 M'}
    MACs        - {
    
    'BertEncoder': '3092.88 GMACs', 'BertLMPredictionHead': '46.97 GMACs'}
    fwd latency - {
    
    'BertEncoder': '33.45 ms', 'BertLMPredictionHead': '2.61 ms'}
depth 3:
    params      - {
    
    'ModuleList': '302.31 M', 'Embedding': '31.79 M', 'Linear': '31.26 M'}
    MACs        - {
    
    'ModuleList': '3092.88 GMACs', 'Linear': '36.23 GMACs'}
    fwd latency - {
    
    'ModuleList': '33.11 ms', 'BertPredictionHeadTransform': '1.83 ms''}
depth 4:
    params      - {'BertLayer': '302.31 M', 'LinearActivation': '1.05 M''}
    MACs        - {
    
    'BertLayer': '3092.88 GMACs', 'LinearActivation': '10.74 GMACs'}
    fwd latency - {
    
    'BertLayer': '33.11 ms', 'LinearActivation': '1.43 ms'}
depth 5:
    params      - {
    
    'BertAttention': '100.76 M', 'BertIntermediate': '100.76 M'}
    MACs        - {
    
    'BertAttention': '1031.3 GMACs', 'BertIntermediate': '1030.79 GMACs'}
    fwd latency - {
    
    'BertAttention': '19.83 ms', 'BertOutput': '4.38 ms'}
depth 6:
    params      - {
    
    'LinearActivation': '100.76 M', 'Linear': '100.69 M'}
    MACs        - {
    
    'LinearActivation': '1030.79 GMACs', 'Linear': '1030.79 GMACs'}
    fwd latency - {
    
    'BertSelfAttention': '16.29 ms', 'LinearActivation': '3.48 ms'}

------------------------------ Detailed Profile per GPU ------------------------------
Each module profile is listed after its name in the following order:
params, percentage of total params, MACs, percentage of total MACs, fwd latency, percentage of total fwd latency, fwd FLOPS

BertForPreTrainingPreLN(
  336.23 M, 100.00% Params, 3139.93 GMACs, 100.00% MACs, 76.39 ms, 100.00% latency, 82.21 TFLOPS,
  (bert): BertModel(
    335.15 M, 99.68% Params, 3092.96 GMACs, 98.50% MACs, 34.29 ms, 44.89% latency, 180.4 TFLOPS,
    (embeddings): BertEmbeddings(...)
    (encoder): BertEncoder(
      302.31 M, 89.91% Params, 3092.88 GMACs, 98.50% MACs, 33.45 ms, 43.79% latency, 184.93 TFLOPS,
      (FinalLayerNorm): FusedLayerNorm(...)
      (layer): ModuleList(
        302.31 M, 89.91% Params, 3092.88 GMACs, 98.50% MACs, 33.11 ms, 43.35% latency, 186.8 TFLOPS,
        (0): BertLayer(
          12.6 M, 3.75% Params, 128.87 GMACs, 4.10% MACs, 1.29 ms, 1.69% latency, 199.49 TFLOPS,
          (attention): BertAttention(
            4.2 M, 1.25% Params, 42.97 GMACs, 1.37% MACs, 833.75 us, 1.09% latency, 103.08 TFLOPS,
            (self): BertSelfAttention(
              3.15 M, 0.94% Params, 32.23 GMACs, 1.03% MACs, 699.04 us, 0.92% latency, 92.22 TFLOPS,
              (query): Linear(1.05 M, 0.31% Params, 10.74 GMACs, 0.34% MACs, 182.39 us, 0.24% latency, 117.74 TFLOPS,...)
              (key): Linear(1.05 M, 0.31% Params, 10.74 GMACs, 0.34% MACs, 57.22 us, 0.07% latency, 375.3 TFLOPS,...)
              (value): Linear(1.05 M, 0.31% Params, 10.74 GMACs, 0.34% MACs, 53.17 us, 0.07% latency, 403.91 TFLOPS,...)
              (dropout): Dropout(...)
              (softmax): Softmax(...)
            )
            (output): BertSelfOutput(
              1.05 M, 0.31% Params, 10.74 GMACs, 0.34% MACs, 114.68 us, 0.15% latency, 187.26 TFLOPS,
              (dense): Linear(1.05 M, 0.31% Params, 10.74 GMACs, 0.34% MACs, 64.13 us, 0.08% latency, 334.84 TFLOPS, ...)
              (dropout): Dropout(...)
            )
          )
          (PreAttentionLayerNorm): FusedLayerNorm(...)
          (PostAttentionLayerNorm): FusedLayerNorm(...)
          (intermediate): BertIntermediate(
            4.2 M, 1.25% Params, 42.95 GMACs, 1.37% MACs, 186.68 us, 0.24% latency, 460.14 TFLOPS,
            (dense_act): LinearActivation(4.2 M, 1.25% Params, 42.95 GMACs, 1.37% MACs, 175.0 us, 0.23% latency, 490.86 TFLOPS,...)
          )
          (output): BertOutput(
            4.2 M, 1.25% Params, 42.95 GMACs, 1.37% MACs, 116.83 us, 0.15% latency, 735.28 TFLOPS,
            (dense): Linear(4.2 M, 1.25% Params, 42.95 GMACs, 1.37% MACs, 65.57 us, 0.09% latency, 1310.14 TFLOPS,...)
            (dropout): Dropout(...)
          )
        )
        ...
        (23): BertLayer(...)
      )
    )
    (pooler): BertPooler(...)
  )
  (cls): BertPreTrainingHeads(...)
)
------------------------------------------------------------------------------

DeepSpeed Flops Profiler は、プロファイルの概要で、モデルのパラメーターの数、浮動小数点演算 (フロップ) の数、FLOPS、レイテンシー、サンプル/秒のスループットを出力します。この概要は、現在のモデル実行とハードウェアのピーク パフォーマンスの間のパフォーマンス ギャップを示し、ユーザーがトレーニングまたは推論設定 (ハイパーパラメーター、データ並列処理、モデル並列処理、システム構成など) を調整してより良いパフォーマンスを達成するのに役立ちます。

DeepSpeed Flops Profiler は、さまざまなモデルの深さで重要なモジュール (集約プロファイル) やモデル アーキテクチャ内の特定のモジュール (詳細プロファイル) をプロファイリングすることもできます。これらのプロファイルを通じて、DeepSpeed ユーザーは、モデル全体の複雑さ/パフォーマンスに対する各レイヤーまたはサブモジュールの寄与を理解できます。その後、ユーザーはモデル設計を調整またはリファクタリングして、パフォーマンスを向上させることができます。たとえば、DeepSpeed ユーザーはプロファイラーを使用して、小さなレイヤーを積み重ねた方が大きなレイヤーを積み重ねる場合よりも軽量であるか、パフォーマンスが優れているかを定量化できます。集約された詳細なプロファイルにより、ユーザーはボトルネック モジュールを迅速に特定することもできます。上記の BERT-Large の例では、DeepSpeed Flops Profiler を使用して、BertLayer が最も重要なレイヤーであり、多くのドロップアウト、ソフトマックス、レイヤー ノルム、および線形レイヤー モジュールが含まれていることがわかりました。これらのモジュールはフロップでは重くありませんが、多くの GPU カーネル呼び出しをトリガーし、過剰なメモリ読み取り/書き込みリクエストを作成します。詳細なプロファイルに示されているパターンは、これがカーネル融合に完全に一致していることを示しており、データの移動を減らすために融合トランスフォーマー カーネルを開発しました (https://www.deepspeed.ai/tutorials/bert-pretraining/ を参照)。最適化を適用した後、DeepSpeed Flops Profiler の出力で GPU あたりの FLOPS と全体的なトレーニング サンプル/秒が 25% 向上しました。

DeepSpeed Flops Profiler は、ユーザー コードを変更せずに DeepSpeed ランタイムと一緒に使用することも、DeepSpeed から独立したスタンドアロン パッケージとして使用することもできます。モデルのトレーニングに DeepSpeed を使用する場合、プロファイラーは DeepSpeed 構成ファイル (https://www.deepspeed.ai/docs/config-json/#flops-profiler) で有効にすることができます。Analyzer API はスタンドアロン パッケージとして、トレーニング コードと推論コードの両方で使用できます。DeepSpeed Profiler はまだ開発中であり、現在は初期機能のみが含まれています。さらにエキサイティングな機能が間もなく追加される予定ですので、ご期待ください。

フロップ測定

既存のフロップ計算ツールまたは手法と同様に、DeepSpeed Flops Analyzer はモジュールの順伝播フロップを測定しますが、逆伝播フロップは順伝播フロップの 2 倍と推定されます。PyTorch Op のフロップをカウントする PyTorch Analyzer とは異なり、DeepSpeed Flops Analyzer はモデル内のモジュール内のフロップを測定し、モデルの実行についてのより多くの洞察をユーザーに提供します。フロップス推定部分は ptflops (https://github.com/sovrasov/flops-counter.pytorch) からインスピレーションを得ています。主な違いは、DeepSpeed Flops アナライザーがモジュール レベルで FLOPS 計算を直接サポートするだけでなく、モジュール内の呼び出しをキャプチャしてtorch.nn.functionalフロップを推定します。ParallelTransformerLayerworksしたがって、DeepSpeed Flops アナライザーでは、Megatron-LM の、ParallelSelfAttention、などのカスタム モジュールをモデルで使用できますRowParallelLinearこれは、ユーザーがカスタム モジュールごとにカスタム フロップス計算関数を作成する必要がある ptflops とは対照的です。

マルチ GPU、マルチノード、データ並列、モデル並列

DeepSpeed Flops Analyzerは、ワールドサイズ、データ並列サイズ、モデル並列サイズとともにGPUごとの解析結果を出力します。

複数の GPU または複数のノードで実行されるモデルの場合、モデルの並列処理 (たとえば、 Megatron-LM --model-parallel-size) の変更のみが、浮動小数点オペランドとパラメータ、つまりmodel_parallel_size * flops = total_flopsおよびの解析結果に影響しますmodel_parallel_size * parameters = total_parametersデータの並列サイズまたはワールド サイズ (GPU またはノードの数に関連) は、GPU ごとの解析結果に影響しません。

DeepSpeed Flops Analyzer は、DeepSpeed ランタイムと一緒に、またはスタンドアロン パッケージとして使用できます。モデルのトレーニングに DeepSpeed を使用する場合、ユーザーはコードを変更せずに DeepSpeed 構成ファイル (https://www.deepspeed.ai/docs/config-json/#flops-profiler) でプロファイラーを構成できます。DeepSpeed ランタイムの外部でフロップス アナライザーを使用するには、DeepSpeed をインストールし、flops_profilerパッケージをインポートして API を直接使用します。それぞれの使用方法の例を以下に示します。

DeepSpeed ランタイムで使用するため

モデルのトレーニングに DeepSpeed を使用する場合、アナライザーは DeepSpeed 構成ファイルで構成できます。プロファイラーを使用する場合、明示的な API 呼び出しは必要ありません。アナライザーは、deepspeed の構成 json ファイルに次のフィールドを追加することで有効にできます。詳細については、flops プロファイラー (https://www.deepspeed.ai/docs/config-json/#flops-profiler) を参照してください。

{
    
    
  "flops_profiler": {
    
    
    "enabled": true,
    "profile_step": 1,
    "module_depth": -1,
    "top_modules": 1,
    "detailed": true,
    "output_file": null
    }
}

メガトロンLMで使用

DeepSpeed で Megatron-LM を実行する方法については、チュートリアル Megatron-LM を参照してください。

12 層 Megatron-LM モデルの出力例 ( hidden_size = 8192num_attention_heads = 32batch_size = 1024、 ) を以下に示しますseq_length = 1024

-------------------------- DeepSpeed Flops Profiler --------------------------
Profile Summary at step 10:
Notations:
data parallel size (dp_size), model parallel size(mp_size),
number of parameters (params), number of multiply-accumulate operations(MACs),
number of floating-point operations (flops), floating-point operations per second (FLOPS),
fwd latency (forward propagation latency), bwd latency (backward propagation latency),
step (weights update latency), iter latency (sum of fwd, bwd and step latency)

world size:                                                   1
data parallel size:                                           1
model parallel size:                                          1
batch size per GPU:                                           1024
params per gpu:                                               1.29 M
params of model = params per GPU * mp_size:                   1.29 M
fwd MACs per GPU:                                             41271.95 G
fwd flops per GPU:                                            82543.9 G
fwd flops of model = fwd flops per GPU * mp_size:             82543.9 G
fwd latency:                                                  1.89 s
bwd latency:                                                  5.38 s
fwd FLOPS per GPU = fwd flops per GPU / fwd latency:          43.68 TFLOPS
bwd FLOPS per GPU = 2 * fwd flops per GPU / bwd latency:      30.7 TFLOPS
fwd+bwd FLOPS per GPU = 3 * fwd flops per GPU / (fwd+bwd latency):   34.07 TFLOPS
step latency:                                                 34.12 s
iter latency:                                                 41.39 s
samples/second:                                               24.74

----------------------------- Aggregated Profile per GPU -----------------------------
Top 1 modules in terms of params, MACs or fwd latency at different model depths:
depth 0:
    params      - {
    
    'GPT2Model': '1.29 M'}
    MACs        - {
    
    'GPT2Model': '41271.95 GMACs'}
    fwd latency - {
    
    'GPT2Model': '1.84 s'}
depth 1:
    params      - {
    
    'TransformerLanguageModel': '1.29 M'}
    MACs        - {
    
    'TransformerLanguageModel': '39584.03 GMACs'}
    fwd latency - {
    
    'TransformerLanguageModel': '1.83 s'}
depth 2:
    params      - {
    
    'ParallelTransformer': '1.29 M'}
    MACs        - {
    
    'ParallelTransformer': '39584.03 GMACs'}
    fwd latency - {
    
    'ParallelTransformer': '1.81 s'}
depth 3:
    params      - {
    
    'ModuleList': '1.28 M'}
    MACs        - {
    
    'ModuleList': '39584.03 GMACs'}
    fwd latency - {
    
    'ModuleList': '1.3 s'}
depth 4:
    params      - {
    
    'ParallelTransformerLayerPart2': '688.15 k'}
    MACs        - {
    
    'ParallelTransformerLayerPart2': '26388.28 GMACs'}
    fwd latency - {
    
    'ParallelTransformerLayerPart2': '865.73 ms'}
depth 5:
    params      - {
    
    'ParallelMLP': '491.54 k'}
    MACs        - {
    
    'ParallelMLP': '26388.28 GMACs'}
    fwd latency - {
    
    'ParallelMLP': '849.4 ms'}

------------------------------ Detailed Profile per GPU ------------------------------
Each module profile is listed after its name in the following order:
params, percentage of total params, MACs, percentage of total MACs, fwd latency, percentage of total fwd latency, fwd FLOPS

Note: 1. A module can have torch.nn.module or torch.nn.functional to compute logits (e.g. CrossEntropyLoss). They are not counted as submodules, thus not to be printed out. However they make up the difference between a parent's MACs(or latency) and the sum of its submodules'.
1. Number of floating-point operations is a theoretical estimation, thus FLOPS computed using that could be larger than the maximum system throughput.
2. The fwd latency listed in the top module's profile is directly captured at the module forward function in PyTorch, thus it's less than the fwd latency shown above which is captured in DeepSpeed.

GPT2Model(
  1.29 M, 100.00% Params, 41271.95 GMACs, 100.00% MACs, 1.84 s, 100.00% latency, 44.78 TFLOPS,
  (language_model): TransformerLanguageModel(
    1.29 M, 100.00% Params, 39584.03 GMACs, 95.91% MACs, 1.83 s, 99.11% latency, 43.34 TFLOPS,
    (embedding): Embedding(
      2, 0.00% Params, 0 MACs, 0.00% MACs, 18.1 ms, 0.98% latency, 0.0 FLOPS,
      (word_embeddings): VocabParallelEmbedding(1, 0.00% Params, 0 MACs, 0.00% MACs, 164.75 us, 0.01% latency, 0.0 FLOPS, )
      (position_embeddings): Embedding(1, 0.00% Params, 0 MACs, 0.00% MACs, 489.23 us, 0.03% latency, 0.0 FLOPS, 1024, 8192)
      (embedding_dropout): Dropout(0, 0.00% Params, 0 MACs, 0.00% MACs, 93.94 us, 0.01% latency, 0.0 FLOPS, p=0.1, inplace=False)
    )
    (transformer): ParallelTransformer(
      1.29 M, 100.00% Params, 39584.03 GMACs, 95.91% MACs, 1.81 s, 98.11% latency, 43.78 TFLOPS,
      (layers): ModuleList(
        1.28 M, 98.73% Params, 39584.03 GMACs, 95.91% MACs, 1.3 s, 70.66% latency, 60.79 TFLOPS,
        (0): ParallelTransformerLayerPart1(
          49.15 k, 3.80% Params, 1099.65 GMACs, 2.66% MACs, 23.5 ms, 1.27% latency, 93.6 TFLOPS,
          (input_layernorm): FusedLayerNorm(16.38 k, 1.27% Params, 0 MACs, 0.00% MACs, 128.75 us, 0.01% latency, 0.0 FLOPS, torch.Size([8192]), eps=1e-05, elementwise_affine=True)
          (attention): ParallelSelfAttention(
            32.77 k, 2.53% Params, 1099.65 GMACs, 2.66% MACs, 22.8 ms, 1.24% latency, 96.46 TFLOPS,
            (query_key_value): ColumnParallelLinear(24.58 k, 1.90% Params, 824.63 GMACs, 2.00% MACs, 8.93 ms, 0.48% latency, 184.7 TFLOPS, )
            (scale_mask_softmax): FusedScaleMaskSoftmax(0, 0.00% Params, 134.22 MMACs, 0.00% MACs, 151.16 us, 0.01% latency, 1.78 TFLOPS, )
            (attention_dropout): Dropout(0, 0.00% Params, 0 MACs, 0.00% MACs, 79.63 us, 0.00% latency, 0.0 FLOPS, p=0.1, inplace=False)
            (dense): RowParallelLinear(8.19 k, 0.63% Params, 274.88 GMACs, 0.67% MACs, 2.67 ms, 0.14% latency, 205.81 TFLOPS, )
          )
        )
        (1): ParallelTransformerLayerPart2(
          57.35 k, 4.43% Params, 2199.02 GMACs, 5.33% MACs, 77.53 ms, 4.21% latency, 56.73 TFLOPS,
          (post_attention_layernorm): FusedLayerNorm(16.38 k, 1.27% Params, 0 MACs, 0.00% MACs, 116.11 us, 0.01% latency, 0.0 FLOPS, torch.Size([8192]), eps=1e-05, elementwise_affine=True)
          (mlp): ParallelMLP(
            40.96 k, 3.16% Params, 2199.02 GMACs, 5.33% MACs, 76.19 ms, 4.13% latency, 57.72 TFLOPS,
            (dense_h_to_4h): ColumnParallelLinear(32.77 k, 2.53% Params, 1099.51 GMACs, 2.66% MACs, 10.79 ms, 0.59% latency, 203.81 TFLOPS, )
            (dense_4h_to_h): RowParallelLinear(8.19 k, 0.63% Params, 1099.51 GMACs, 2.66% MACs, 14.38 ms, 0.78% latency, 152.95 TFLOPS, )
          )
        )
        ...
        (23): ParallelTransformerLayerPart2(...)
      )
      (final_layernorm): FusedLayerNorm(16.38 k, 1.27% Params, 0 MACs, 0.00% MACs, 110.86 us, 0.01% latency, 0.0 FLOPS, torch.Size([8192]), eps=1e-05, elementwise_affine=True)
    )
  )
)
------------------------------------------------------------------------------

最新の DeepSpeed-Megatron ウェアハウスを参照し、モデルのトレーニング時に DeepSpeed 構成ファイルを DeepSpeed Profiler に構成できます。

DeepSpeed ランタイム環境外での使用

プロファイラーは、DeepSpeed ランタイム環境の外部でスタンドアロン パッケージとして使用できます。flops_profilerDeepSpeed をインストールし、パッケージをインポートするだけで API を直接使用できます。DeepSpeedのインストール方法については、DeepSpeedインストールガイドを参照してください。

モデル推論では

トレーニングされたモデルの推論状態をプロファイリングするには、get_model_profile関数を使用します。いくつかの例を以下に示します。

AlexNet の例

次の例は、DeepSpeed flops プロファイラーを使用して AlexNet をプロファイリングする方法を示しています。

import torchvision.models as models
import torch
from deepspeed.profiling.flops_profiler import get_model_profile
from deepspeed.accelerator import get_accelerator

with get_accelerator().device(0):
    model = models.alexnet()
    batch_size = 256
    flops, macs, params = get_model_profile(model=model, # model
                                    input_shape=(batch_size, 3, 224, 224), # input shape to the model. If specified, the model takes a tensor with this shape as the only positional argument.
                                    args=None, # list of positional arguments to the model.
                                    kwargs=None, # dictionary of keyword arguments to the model.
                                    print_profile=True, # prints the model graph with the measured profile attached to each module
                                    detailed=True, # print the detailed profile
                                    module_depth=-1, # depth into the nested modules, with -1 being the inner most modules
                                    top_modules=1, # the number of top modules to print aggregated profile
                                    warm_up=10, # the number of warm-ups before measuring the time of each module
                                    as_string=True, # print raw numbers (e.g. 1000) or as human-readable strings (e.g. 1k)
                                    output_file=None, # path to the output file. If None, the profiler prints to stdout.
                                    ignore_modules=None) # the list of modules to ignore in the profiling
BERT の例
from functools import partial
import torch
from transformers import BertForSequenceClassification, BertTokenizer
from deepspeed.profiling.flops_profiler import get_model_profile
from deepspeed.accelerator import get_accelerator


def bert_input_constructor(batch_size, seq_len, tokenizer):
    fake_seq = ""
    for _ in range(seq_len - 2):  # ignore the two special tokens [CLS] and [SEP]
      fake_seq += tokenizer.pad_token
    inputs = tokenizer([fake_seq] * batch_size,
                       padding=True,
                       truncation=True,
                       return_tensors="pt")
    labels = torch.tensor([1] * batch_size)
    inputs = dict(inputs)
    inputs.update({
    
    "labels": labels})
    return inputs


with get_accelerator().device(0):
    tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
    model = BertForSequenceClassification.from_pretrained('bert-base-uncased')
    batch_size = 4
    seq_len = 128
    enable_profile = True
    if enable_profile:
      flops, macs, params = get_model_profile(
          model,
          kwargs=bert_input_constructor(batch_size, seq_len, tokenizer),
          print_profile=True,
          detailed=True,
      )
    else:
      inputs = bert_input_constructor((batch_size, seq_len), tokenizer)
      outputs = model(inputs)

モデルトレーニングワークフロー内

トレーニング ワークフローでモデルのフォワード パスをプロファイリングするには、FlopsProfilerクラスを使用します。FlopsProfilerこのクラスは次のメソッドを提供します。

  • start_profile()- プロファイリングを開始します。
  • get_total_flops(as_string=False)- モデル内の浮動小数点演算の合計数を返します。
  • get_total_macs(as_string=False- モデル内の Mac の合計数を返します。
  • get_total_params(as_string=False)- モデル内のパラメータの合計数を返します。
  • print_model_profile(profile_step=1, module_depth=-1, top_modules=3, detailed=True, output_file=None)- モデルプロファイルを印刷します。
  • stop_profile()- プロファイリングを停止します。これにより、モデル内の浮動小数点演算のカウントが停止されます。
  • end_profile()- そうじする。これにより、プロファイリング中にモデルに追加されたプロファイリング属性がクリーンアップされます。これは、プロファイリングの最後で、 を呼び出した後get_total_flopsget_total_paramsまたはprint_model_profileその後に実行する必要があります。

トレーニングワークフローの例

以下は、一般的なトレーニング ワークフローでこのメソッドを使用する例です。

from deepspeed.profiling.flops_profiler import FlopsProfiler

model = Model()
prof = FlopsProfiler(model)

profile_step = 5
print_profile= True

for step, batch in enumerate(data_loader):
  # start profiling at training step "profile_step"
  if step == profile_step:
    prof.start_profile()

  # forward() method
  loss = model(batch)

  # end profiling and print output
  if step == profile_step: # if using multi nodes, check global_rank == 0 as well
    prof.stop_profile()
    flops = prof.get_total_flops()
    macs = prof.get_total_macs()
    params = prof.get_total_params()
    if print_profile:
        prof.print_model_profile(profile_step=profile_step)
    prof.end_profile()

  # runs backpropagation
  loss.backward()

  # weight update
  optimizer.step()

おすすめ

転載: blog.csdn.net/just_sort/article/details/131402383