PyTorch 1.8 チュートリアル : レシピ : 基本 :- PyTorch Profiler (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/29/2021 (1.8.1+cu102)
* 本ページは、PyTorch 1.8 Tutorials の以下のページを翻訳した上で適宜、補足説明したものです:
- PyTorch Recipes : Basics : PyTorch Profiler
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
スケジュールは弊社 公式 Web サイト でご確認頂けます。
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
- ウェビナー運用には弊社製品「ClassCat® Webinar」を利用しています。
人工知能研究開発支援 | 人工知能研修サービス | テレワーク & オンライン授業を支援 |
PoC(概念実証)を失敗させないための支援 (本支援はセミナーに参加しアンケートに回答した方を対象としています。) |
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション |
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/ ; Facebook |
レシピ : 基本 :- PyTorch Profiler
このレシピはどのように PyTorch profile を利用するか、そしてモデルの演算の時間とメモリ消費をどのように計測するかを説明します。
イントロダクション
PyTorch は単純な profiler API を含み、これはユーザがモデルで最も高価な演算を決定する必要があるとき有用です。
このレシピでは、モデルパフォーマンスを分析するためにどのように profiler を使用するかを実演するために単純な Resnet モデルを使用します。
セットアップ
torch と torchvision をインストールするために以下のコマンドを使用します :
pip install torch torchvision
ステップ
- 総ての必要なライブラリをインポートする
- 単純な Resnet モデルをインスタンス化する
- 実行時間を分析するために profiler を使用する
- メモリ消費を分析するために profiler を使用する
- tracing 機能を使用する
1. 総ての必要なライブラリをインポートする
このレシピでは torch, torchvision.models と profiler モジュールを利用します :
import torch
import torchvision.models as models
import torch.autograd.profiler as profiler
2. 単純な Resnet モデルをインスタンス化する
Resnet モデルのインスタンスを作成してそれのための入力を準備しましょう :
model = models.resnet18()
inputs = torch.randn(5, 3, 224, 224)
3. 実行時間を分析するために profile を使用する
PyTorch profiler はコンテキスト・マネージャを通して有効にされそして幾つかのパラメータを受け取ります、最も有用なものの幾つかは :
- record_shapes – 演算子入力の shape を記録するか否か。
- profile_memory – モデルの Tensor により消費されたメモリの総量を報告するか否か。
- use_cuda – CUDA カーネルの実行時間を測定するか否か。
実行時間を分析するために profiler をどのように利用できるか見ましょう :
with profiler.profile(record_shapes=True) as prof:
with profiler.record_function("model_inference"):
model(inputs)
任意のコード範囲をユーザが提供した名前でラベル付けするために record_function コンテキスト・マネージャを利用できることに注意してください (model_inference は上のサンプルでラベルとして利用されます)。profiler は profiler コンテキスト・マネージャによりラップされたコード範囲の実行の間にどの演算子が呼び出されたかを確認することを可能にします。もし複数の profiler 範囲が同時に有効である場合 (e.g. 並列な PyTorch スレッド)、各 profiling コンテキスト・マネージャは対応する範囲の演算子だけを追跡します。profiler はまた torch.jit._fork により起動された非同期タスクと (backward パスの場合) backward() 呼び出しで起動された backward パス演算子も自動的に profile します。
上の実行のための統計情報をプリントアウトしましょう :
print(prof.key_averages().table(sort_by="cpu_time_total", row_limit=10))
出力はこのようなものです (幾つかのカラムは省略しています) :
# ------------------------- -------------- ---------- ------------ --------- # Name Self CPU total CPU total CPU time avg # Calls # ------------------------- -------------- ---------- ------------ --------- # model_inference 3.541ms 69.571ms 69.571ms 1 # conv2d 69.122us 40.556ms 2.028ms 20 # convolution 79.100us 40.487ms 2.024ms 20 # _convolution 349.533us 40.408ms 2.020ms 20 # mkldnn_convolution 39.822ms 39.988ms 1.999ms 20 # batch_norm 105.559us 15.523ms 776.134us 20 # _batch_norm_impl_index 103.697us 15.417ms 770.856us 20 # native_batch_norm 9.387ms 15.249ms 762.471us 20 # max_pool2d 29.400us 7.200ms 7.200ms 1 # max_pool2d_with_indices 7.154ms 7.170ms 7.170ms 1 # ------------------------- -------------- ---------- ------------ ---------
予想されるように、ここで殆どの時間は畳込みで費やされていることを見ます (そして特に MKL-DNN サポートでコンパイルされた PyTorch のための mkldnn_convolution で)。self cpu 時間と cpu 時間の違いに注意してください – 演算子は他の演算子を呼び出せますが、self cpu 時間は children 演算子呼び出しに費やされる時間を除外している一方で、total cpu 時間はそれを含みます。
より極め細かい結果を得て演算子の入力 shape を含めるためには、group_by_input_shape=True を渡します:
print(prof.key_averages(group_by_input_shape=True).table(sort_by="cpu_time_total", row_limit=10))
# (omitting some columns) # ------------------------- ----------- -------- ------------------------------------- # Name CPU total # Calls Input Shapes # ------------------------- ----------- -------- ------------------------------------- # model_inference 69.571ms 1 [] # conv2d 9.019ms 4 [[5, 64, 56, 56], [64, 64, 3, 3], []] # convolution 9.006ms 4 [[5, 64, 56, 56], [64, 64, 3, 3], []] # _convolution 8.982ms 4 [[5, 64, 56, 56], [64, 64, 3, 3], []] # mkldnn_convolution 8.894ms 4 [[5, 64, 56, 56], [64, 64, 3, 3], []] # max_pool2d 7.200ms 1 [[5, 64, 112, 112]] # conv2d 7.189ms 3 [[5, 512, 7, 7], [512, 512, 3, 3], []] # convolution 7.180ms 3 [[5, 512, 7, 7], [512, 512, 3, 3], []] # _convolution 7.171ms 3 [[5, 512, 7, 7], [512, 512, 3, 3], []] # max_pool2d_with_indices 7.170ms 1 [[5, 64, 112, 112]] # ------------------------- ----------- -------- --------------------------------------
4. メモリ消費を分析するために profiler を使用する
PyTorch profiler はまたモデルの演算子の実行の間に割当てられた (or 解放された) (モデルの tensor により使用された) メモリの総量も示すこともできます。下の出力では、’self’ メモリは演算子により割当てられた (解放された) メモリに対応し、他の演算子の children 呼び出しは除外しています。メモリ profiling 機能を有効にするには profile_memory=True を渡します。
with profiler.profile(profile_memory=True, record_shapes=True) as prof:
model(inputs)
print(prof.key_averages().table(sort_by="self_cpu_memory_usage", row_limit=10))
# (omitting some columns)
# --------------------------- --------------- --------------- ---------------
# Name CPU Mem Self CPU Mem Number of Calls
# --------------------------- --------------- --------------- ---------------
# empty 94.79 Mb 94.79 Mb 123
# resize_ 11.48 Mb 11.48 Mb 2
# addmm 19.53 Kb 19.53 Kb 1
# empty_strided 4 b 4 b 1
# conv2d 47.37 Mb 0 b 20
# --------------------------- --------------- --------------- ---------------
print(prof.key_averages().table(sort_by="cpu_memory_usage", row_limit=10))
# (omitting some columns)
# --------------------------- --------------- --------------- ---------------
# Name CPU Mem Self CPU Mem Number of Calls
# --------------------------- --------------- --------------- ---------------
# empty 94.79 Mb 94.79 Mb 123
# batch_norm 47.41 Mb 0 b 20
# _batch_norm_impl_index 47.41 Mb 0 b 20
# native_batch_norm 47.41 Mb 0 b 20
# conv2d 47.37 Mb 0 b 20
# convolution 47.37 Mb 0 b 20
# _convolution 47.37 Mb 0 b 20
# mkldnn_convolution 47.37 Mb 0 b 20
# empty_like 47.37 Mb 0 b 20
# max_pool2d 11.48 Mb 0 b 1
# max_pool2d_with_indices 11.48 Mb 0 b 1
# resize_ 11.48 Mb 11.48 Mb 2
# addmm 19.53 Kb 19.53 Kb 1
# adaptive_avg_pool2d 10.00 Kb 0 b 1
# mean 10.00 Kb 0 b 1
# --------------------------- --------------- --------------- ---------------
5. tracing 機能を使用する
profiling 結果は .json trace ファイルとして出力できます :
with profiler.profile() as prof:
with profiler.record_function("model_inference"):
model(inputs)
prof.export_chrome_trace("trace.json")
ユーザは trace ファイルを Chrome (chrome://tracing) にロードした後 profile された演算子のシークエンスを調べることができます :
更に学習する
貴方の学習を続けるために以下のレシピ/チュートリアルを見てください :
以上