プロファイリングと最適化

https://www.intel.com/content/www/us/en/developer/articles/training/profiling-and-optimization.html

プロファイリングと最適化
https://github.com/HabanaAI/Gaudi-tutorials/tree/main/PyTorch/Profiling_and_Optimization

このチュートリアルでは、インテル® Gaudi® アクセラレーターのプロファイリング・ツール (habana_perf_tool) と TensorBoard プラグインの使い方を説明します。いずれも、ユーザーに有用な最適化のヒントと情報を伝え、モデルを調整してパフォーマンスを引き出すための手段です。
プロファイラー・ツールの設定については、ドキュメントのインテル® Gaudi® アクセラレーターの「プロファイラー・ユーザー・ガイド」を、その他の最適化に関する背景と環境については、モデル・パフォーマンス最適化ガイドを参照してください。

https://docs.habana.ai/en/latest/Profiling/index.html
https://docs.habana.ai/en/latest/PyTorch/Model_Optimization_PyTorch/index.html

＜初期セットアップ＞
ずは、インテル® Gaudi® アクセラレーターの PyTorch Docker イメージと、この Notebook の起動から開始します。この例では Hugging Face の Optimum-Habana ライブラリーで実行する Hugging Face リポジトリーから Swin Transformer モデルを使用します。
Optimum-Habana ライブラリーと Hugging Face モデルのサンプルをインストールしてください。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/e3fe6bfd-f144-4b1d-a840-ec1d4daa239d.png)

これで utils ファイルにプロファイリングがフル装備されていることを確認できます。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/c22f9905-7113-4051-9291-0221ef75fd94.png)

＜モデルを実行して trace ファイルを収集 (最適化は未完了)＞
Swin Transformer はコンピューター・ビジョンの汎用バックボーンとして機能するモデル、run_image_classification.py は Swin Transformer を HPU でファインチューニングする方法を記述するためのスクリプトです。この例では Swin Transformer を使用します。
インテル® Gaudi® アクセラレーター特有のコマンド:
--use_habana – インテル® Gaudi® アクセラレーター上で学習処理の実行を許可
--use_hpu_graphs – グラフを再生することで再コンパイルを軽減
--gaudi_config_name Habana/swin – HuggingFace Swin モデルのコンフィグへマッピング
torch.profiler 特有のコマンド:
--profiling_warmup_steps 10 – プロファイラーは warmup の工程を待機
--profiling_steps 3 – 次のアクティブ工程を記録
収集した trace ファイルは ./hpu_profile に格納されますが、参照用のコピーは ./swin_profile フォルダーに移動されます。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/f7ac2ead-db0c-4270-8958-8fb405ca02f0.png)

実行が終わると、このような結果が表示されます。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/f5e0540a-abd3-4633-a4be-b8d4b8da5cff.png)

＜パフォーマンス解析ツールの使い方 2 パターン＞
TensorBoard を起動すると、パフォーマンス解析の結果が表示されます。
tensorboard --logdir xxx
または、シンプルに habana_perf_tool (プロファイラー・ツール) を使用して、コンソールの出力解析を確認します。
habana_perf_tool --trace xxx.trace.json
どちらのツールも出力する情報は同じです。
以下の habana_perf_tool コンソールの出力結果に注目してください。
●Device/Host ratio – 全体的なパフォーマンスとデバイスの使用率
●Host Summary – ホストサイドのパフォーマンス、データローダー、グラフのビルド、データコピー、コンパイルを表示
●Device Summary – デバイスサイドのパフォーマンス、MME、TPC、DMA を表示
●Host/Device Recommendations – モデル最適化の際のパフォーマンスの推奨値
この場合、habana_perf_tool を使用して 1 回目の実行からトレースを続け、パフォーマンス向上の方法を探ります。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/99dcb027-43fd-47ae-baf2-b833220c7292.png)
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/8fb7cebe-e1ce-4b8a-9a2c-e43152b9d056.png)

このケースではホスト内でデータローダーの時間がかかりすぎており、ツールから Habana DataLoader を試してみるか、データローダーで使用するワーカー数を増やしてみるように提案されていますので、いずれかを試し、出力結果を確認してください。

＜最適化の適用 1 (num_workers を調節)＞
注目する最適化コマンド:
--dataloader_num_workers 4 – ワーカー数 (num_workers) を正の整数に設定してマルチプロセスのデータ・ローディングを実行

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/49e3d7f2-41c4-4f3b-8fe9-0cfce70f6455.png)

実行が終わると、このような結果が表示されます。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/4675729b-bb95-4271-8fae-06325d254f73.png)

次に habana_perf_tool を実行して、ワークロードが最適化されているか確認します。

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/4b9df251-67ec-4739-aa4e-8e0946114850.png)
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/abc8b6c6-5711-4039-ab22-3bfcbfac9f9a.png)

結果は Host ratio が 9% に低減、スループットが 30% 向上と、大幅に改善されていることがお分かりいただけると思います。ただし、このツールが提案しているのは、ブロッキングなしのデータコピー (非同期コピー) によるコード実行の効率化です。

＜最適化の適用 2 (非同期コピー)＞
注目する最適化コマンド:
--non_blocking_data_copy True – コピー実行中に引数 non_blocking=True を指定。バックグラウンドでコピーを実行している間、Python スレッドはほかのタスクを継続。

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/af169818-e82f-4f03-8a46-660588bc3353.png)

実行が終わると、このような結果が表示されます。

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/864478c6-ef42-42dd-a18d-9eadaa13dc60.png)

最後にもう 1 度 habana_perf_tool を実行して、ワークロードが最適化されているか確認します。

![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/c463d6f9-f148-47ee-aac0-e15c8a44d221.png)

![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/dbde351b-5ae8-4c06-9e5a-06297c6fea35.png)

＜最適化のまとめ＞
【1 回目の実行】
デバイス使用率 61.6%、データローダーの比率が 55.9% とホストの負荷が高い。ワーカー数 (num_workers) の調節またはインテル® Gaudi® アクセラレーターの DataLoader の使用を提案。

【2 回目の実行 (num_workers の調節)】
デバイス使用率は 90.8% に上がるものの、データコピーの負荷が 11.5% とホストの処理時間が長い。torch.Tensor.to でのブロッキングなしと DataLoader での pin_memory の設定を提案。

【3 回目の実行 (非同期コピー)】
デバイス使用率が 91.7% に向上。モデルは高度に最適化されている状態。

【TensorBoard Viewer での表示確認】
最後に TensorBoard Viewer を起動して学習処理を実行します。この Viewer では、インテル® Gaudi® アクセラレーター全体の情報、カーネル、メモリー・プロファイリングの 3 つのセクションを確認できます。

【インテル® Gaudi® アクセラレーター全体の情報】
TensorBoard Viewer を使用すると、初期画面にはインテル® Gaudi® アクセラレーター全体の概要が表示され、デバイスの実行状況とホスト CPU 情報のどちらも確認できます。ホストとデバイス両方の使用率に加えて、セクションの最下部にデバッグの提案が表示されるため、パフォーマンス最適化のヒントとなるはずです。

【カーネルの情報】
カーネルのセクションでは、インテル® Gaudi® アクセラレーターのカーネルに関する具体的な情報が表示され、Tensor プロセシング・コア (TPC) と行列乗算エンジン (MME) の使用率を確認できます。

【メモリー・プロファイリング】
学習処理の実行中にインテル® Gaudi® アクセラレーターのメモリーを監視するには、torch.profiler.profile 関数の profile_memory 引数を True に設定します。
詳しい設定については、インテル® Gaudi® アクセラレーターの「プロファイラー・ユーザー・ガイド」を参照してください。
https://docs.habana.ai/en/latest/Profiling/index.html

![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/a65ccb6d-6ba0-4852-b6c0-42bb4bc462a1.png)

![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/574a97ca-4d75-41f6-bb6d-6fc98792350b.png)