profile-model について
PyTorch profilerのトレースファイルを分析し、GPU性能の問題を調べるスキルです。pandasで概要やデータを確認し、必要に応じてHTAでボトルネックを詳しく分析します。
主な機能
- 01JSONとgzip形式のトレース読み込み
- 02イベント数とカーネル時間の集計
- 03pandasによるトレースデータの検索
- 04計算・メモリ・通信のボトルネック分析
- 05HTAによる詳細分析(任意)
活用シーン
- 01処理時間の長いGPUカーネルの特定
- 02GPUアイドル時間やCPUボトルネックの調査
- 03通信と計算のオーバーラップ評価
- 04複数ランクのトレース性能確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ meta-pytorch/ skills --skill profile-modelインストール後、Claude Code で/profile-modelを入力して読み込まれたか確認します。
同梱ファイルevals/eval.yamlevals/fixtures/analyze_trace_basic/simple_trace.json
詳細
プロファイラーモデル
PyTorch プロファイラートレース(.json/.json.gz ファイル)を分析し、GPU パフォーマンスの問題を診断して、遅いカーネルを見つけ、ボトルネックを特定します。
ステップ 1:トレースのパスを取得する
ユーザーにトレースファイルのパスを尋ねます。トレースは通常、次の形式です。
- 単一ファイル:
/path/to/trace.jsonまたは/path/to/trace.json.gz - ディレクトリ(複数ランク):
rank0.json、rank1.jsonなどを含む/path/to/traces/
ステップ 2:トレースを DataFrame として読み込む
柔軟にクエリできるよう、トレースを pandas DataFrame に読み込みます。
⚠️ 重要:キャッシュする前にユーザーに確認してください。 自動でキャッシュしないでください。次のように尋ねます。
「このトレースを Parquet としてキャッシュして、今後の読み込みを高速化しますか?
/tmp/trace_cache/に保存され、次回以降の読み込みが速くなります。 (大きなトレースや、追加の質問をする予定がある場合におすすめです)」
ユーザーが同意した場合にのみ、キャッシュを行います。
DataFrame の構造:
- 標準の列:
name、cat、ph、ts、dur、pid、tid、id - Args は次のように展開されます:
args_device、args_stream、args_Input Dimsなど
読み込み手順:
- JSON/JSON.gz トレースファイルを解析する
- 各イベントを行に展開し、
args辞書をargs_*列に展開する tsとdurを数値に変換する
Parquet キャッシュに関する注意事項(ユーザーが同意した場合):
/tmp/trace_cache/{basename}.parquetにキャッシュする- ソースファイルと更新時刻を比較して、キャッシュが最新かどうかを確認する
- 型の混在に対処する:
args_*列には、型(int、str、None)が混在していることがよくあります。Parquet に保存する前に、型が混在している列を検出し、文字列に変換します。'nan'/'None'文字列はNoneに戻します。 - Parquet の保存に失敗した場合、すべての
args_*列を文字列にして再試行する - それでも失敗する場合は、キャッシュなしで続行する
ステップ 3:概要をすばやく確認する
読み込み後、概要をすばやく表示します。
- イベントの総数とカテゴリ別の内訳(
df["cat"].value_counts()) - カーネル数とカーネル時間の合計
- 実行時間が長いカーネルの上位
ステップ 4:DataFrame クエリで分析する
フィルタリングに使用する主な列の値:
- GPU カーネル:
cat == "kernel" - CPU 操作:
cat == "cpu_op" - NCCL/通信:
name.str.contains("nccl", case=False) - メモリ操作:
catに "mem" または "memcpy" が含まれる
タイムスタンプ(ts)と実行時間(dur)の単位は**マイクロ秒(μs)**です。
標準的な pandas 操作(groupby、filter、sort、aggregate)を使用して、ユーザーの質問に回答します。
ステップ 5:結果を解釈する
| 検出結果 | 考えられる問題 | 推奨事項 |
|---|---|---|
| 小さなカーネルが多数ある(平均 < 10μs) | カーネル起動のオーバーヘッド | torch.compile を使用し、操作を融合する |
| 1 つのカーネルが大部分を占める(>50%) | 計算律速で想定どおり | カーネルが最適化されているか確認する |
| メモリ操作が多数ある | メモリ律速 | コピーを減らし、ピン留めメモリを使用する |
| 通信時間が長い | 分散処理のオーバーヘッド | 通信と計算をオーバーラップさせる |
ステップ 6:HTA による詳細分析(任意)
ユーザーがより詳細な分析を希望する場合は、HTA(Holistic Trace Analysis)を使用します。
# Check if HTA is available
try:
from hta.trace_analysis import TraceAnalysis
except ImportError:
print("HTA not installed. Install with: pip install HolisticTraceAnalysis")
HTA 分析関数
| ユーザーの質問 | HTA 関数 | 戻り値 |
|---|---|---|
| 「GPU 時間を消費しているのは何ですか?」 | get_gpu_kernel_breakdown() | カーネル時間の分布 |
| 「クリティカルパスはどこですか?」 | critical_path_analysis() | 実行中のボトルネック経路 |
| 「GPU がアイドル状態なのはなぜですか?」 | get_idle_time_breakdown() | ホスト待ちとカーネル待ちの内訳 |
| 「通信と計算はオーバーラップしていますか?」 | get_comm_comp_overlap() | ランクごとのオーバーラップ率 |
| 「遅いランクはありますか?」 | get_potential_stragglers() | ストラグラーランクの特定 |
| 「全体の時間の内訳は?」 | get_temporal_breakdown() | アイドル/計算/非計算時間 |
HTA の使用例
from hta.trace_analysis import TraceAnalysis
# Load traces
analyzer = TraceAnalysis(trace_dir="/path/to/traces/")
# OR: analyzer = TraceAnalysis(trace_files={0: "/path/to/trace.json.gz"})
# GPU Kernel Breakdown
kernel_type_df, kernel_df = analyzer.get_gpu_kernel_breakdown(visualize=False)
# Temporal Breakdown (idle vs compute vs non-compute)
temporal_df = analyzer.get_temporal_breakdown(visualize=False)
# Idle Time Breakdown (why is GPU idle?)
idle_df, _ = analyzer.get_idle_time_breakdown(ranks=[0], visualize=False)
# Critical Path Analysis (for distributed training)
cp_graph, success = analyzer.critical_path_analysis(
rank=0, annotation="ProfilerStep", instance_id=1
)
if success:
analyzer.overlay_critical_path_analysis(
rank=0, critical_path_graph=cp_graph, output_dir="/tmp/cp_output"
)
# Communication-Computation Overlap
overlap_df = analyzer.get_comm_comp_overlap(visualize=False)
# Straggler Detection
stragglers = analyzer.get_potential_stragglers(num_candidates=2)
よくあるパフォーマンスの問題と修正方法
| 症状 | 診断 | 修正方法 |
|---|---|---|
| 小さなカーネルが多数ある | カーネル起動のオーバーヘッド | torch.compile、演算子の融合を使用する |
| アイドル時間(ホスト待ち)が長い | CPU がボトルネック | DataLoader の num_workers を増やし、pin_memory=True を使用する |
| アイドル時間(カーネル待ち)が長い | カーネル間に連続して発生する隙間 | 演算を融合し、同期を減らす |
| 通信と計算のオーバーラップが少ない | ブロッキング方式の集団通信 | 非同期の集団通信を使用し、計算とオーバーラップさせる |
| 処理の遅いワーカーが検出された | 負荷の不均衡 | データ分布とランク間のバッチサイズを確認する |
| メモリコピーのオーバーヘッド | 過剰なデータ移動 | インプレース演算を使用し、.cpu()/.cuda() の呼び出しを減らす |
出力形式
分析結果を報告するときは、次の形式に従います。
- 要約から始める - 主な結果を説明する1文
- 主な問題を示す - 実行時間と割合に基づく上位3~5件のカーネル/演算
- ボトルネックの種類を特定する - 計算律速、メモリ律速、通信律速、または CPU 律速
- 実行可能な推奨事項を提示する - ユーザーが実施できる具体的な変更
- 詳細な分析を提案する - さらに詳しく知りたい場合は HTA 分析を行うか尋ねる
出力例:
## Trace Analysis Summary
**Main Finding**: GPU is idle 40% of the time, primarily due to CPU bottleneck (host wait).
### Top GPU Kernels (by time)
| % Time | Calls | Avg (μs) | Kernel |
|--------|-------|----------|--------|
| 35.2% | 1000 | 450.3 | ampere_sgemm_128x64 |
| 22.1% | 1000 | 283.5 | volta_nccl_reduce_scatter |
| 15.8% | 2000 | 101.2 | elementwise_kernel |
### Bottleneck: CPU-Bound
The GPU is waiting for the CPU 40% of the time. This suggests data loading or preprocessing is slow.
### Recommendations
1. Increase DataLoader `num_workers` (currently appears to be 0 or 1)
2. Enable `pin_memory=True` in DataLoader
3. Move preprocessing to GPU if possible
**Want deeper analysis?** I can use HTA to get detailed idle time breakdown and critical path analysis.
ルール
- キャッシュする前に尋ねる - Parquet に自動でキャッシュしてはいけません。必ず先にユーザーに尋ねてください。
- 必ず簡易分析から始める - 依存関係は必要ありません
- インストールする前に尋ねる - HTA が利用可能だと決めつけず、使用するか尋ねてください
- 具体的にする - 正確な割合、カーネル名、推奨事項を提示してください
- 次のステップを提案する - さらに詳しい分析を希望するか、必ず尋ねてください
- エラーに適切に対処する - トレース形式が想定外の場合は、不足している内容を説明してください