mcpField
L
llm-pipeline-analysis

llm-pipeline-analysis

github.com/bbuf開発1.1k54 回インストール今日更新
リポジトリ

llm-pipeline-analysis について

LLM 推論の Chrome trace を分析するツール群です。モデル設定と境界カーネルを使ってカーネルをレイヤーに分類し、パスやレイヤー種別の比較に役立つ時間集計、カーネル詳細、Perfetto の移動範囲を出力します。

主な機能

  1. 01レイヤー別の時間とカーネル分類
  2. 02コールドスタートと定常パスの区別
  3. 03レイヤー間のカーネル詳細と差分
  4. 04Perfetto 移動用の時間範囲を出力

活用シーン

  1. 01時間を要するレイヤー種別の特定
  2. 02コールドスタートと定常パスの比較
  3. 03詳細分析する代表レイヤーの選定
  4. 04Perfetto で特定レイヤーへ移動

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bbuf/ai-infra-auto-driven-skills --skill llm-pipeline-analysis

インストール後、Claude Code で/llm-pipeline-analysisを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

scripts/
layer_kernel_breakdown.py
layer_timeline_analyzer.py
model_profiles.py
perfetto_time_mapper.py

詳細

LLM パイプライン分析

概要

トレース全体のプロファイラー概要では粗すぎる場合に使用します。スクリプトは Chrome-trace JSON ファイルを読み込み、層境界のアンカーカーネルを見つけ、 カーネルをフォワードパスと層にグループ化し、Perfetto でのナビゲーションや 詳細なタイミング分析に使えるタイミングテーブルを出力します。

使用する場面

  • どの層が最も大きな割合を占めるかを知る必要がある場合
  • モデルに交互に現れる層タイプがある場合(例:DeepSeek-V4 のように compress_ratios を持つモデル、または Qwen3.8-27B のようなハイブリッド GDN/GQA スタック)
  • コールドスタートと定常状態のフォワードパスを比較する必要がある場合
  • Perfetto UI で特定の層に移動する必要がある場合
  • 詳細分析の対象となる代表的な層を選ぶ必要がある場合

アーティファクトから入力を確認する

モデル設定、フェーズ、ランク/デバイス、TP/EP/DP を、実行マニフェスト、 サーバー引数、トレースから特定します。分析内容を変える不足情報のみを確認します。 TP-0 はランクを示すもので、TP のワールドサイズではありません。不明な実行を TP8/EP8 やデコード BS1 とみなさないでください。投機的リクエストの BS と ターゲット検証の M は異なります。設定がない場合は、明示的なプロファイルと 検証済みの層数を使用します。

モデルプロファイル

スクリプトは ModelProfile を使って、層境界の検出とカーネルの分類を行います。 プロファイルは config.json から自動推定するか、--profile で選択します。

プロファイルアンカーカーネルブロック数/層自動推定条件
dsv4_csa_hcamhc_pre_big_fuse2DeepSeek-V4、または圧縮へのフォールバック
dsv41明示的に検証されたアンカー1(サブレイヤー用に上書き)V4.1 のテキスト/ラッパーの識別情報、または KV ソース層
dsv3_mla明示的なバックエンドアンカー、または残差境界バックエンドに依存識別情報に基づくディスパッチ後の均質な MLA
mla_dsa検証済みの残差境界2GLM-5/5.2/5.3、V3.2、DSA MLA
kimi_k3明示的な attn_res_fused(SGLang)/attn_res_fwd_online_v2_kernel(vLLM)2 + 出力集約/パス 1 回K3/注意機構の残差を持つ Kimi linear
glm5_nextmhc_pre_big_fuse2GLM-5.3-Flash
hy_v4Triton フォールバックでの明示的な ihc_pre_stage2(hpc シンボルはトレース確認が必要)2Hy4
qwen4_exp明示的な grouped_gemma_rmsnorm2Qwen3.8-Flash-Next(vLLM では norm が融合される場合があります)
nemotron_h明示的な残差 norm1設定上、1 つの Mamba/注意機構/MoE ブロックが各層に対応
longcat_flash明示的な残差境界4LongCat-Flash アーキテクチャ
gemma4明示的な _gemma_qkv_rmsnorm_kernel(SGLang CUDA)1Gemma4 のテキスト/ラッパーの識別情報
generic_addnorm検証済みの fused-add RMSNorm または allreduce 融合2その他の設定済みモデル
generic明示的なアンカー。残差候補のみ1、残差候補の場合は 2設定がない場合のフォールバック

推定前に、ネストされた text_config、language_config、llm_config をフラット化します。 モデルの識別情報は kv_lora_rank より優先されます。K3、GLM-5 Next、 Hy4、dots3、LongCat を均質な V3 MLA として扱ってはいけません。 層数は設定から読み取ります。V4 Flash は 43 層、Pro は 61 層、V4.1 は 40 層です。 これらのアンカーファミリーは、バックエンドとフェーズに関する注意事項を含め、 SGLang/vLLM のソースで検証済みです。TensorRT-LLM/TokenSpeed の周期性については、 別途トレースによる根拠が必要です。

前提条件

  • Chrome-trace JSON 形式(.json または .json.gz)の torch.profiler トレース
  • モデルの config.json(プロファイル推定、compress_ratios などに使用)
  • トレースに、認識可能な層境界アンカーカーネルが含まれていること (プロファイルから自動検出するか、--anchor-kernel で指定します)

レイヤー境界の検出

スクリプトでは、アンカーとなるカーネルをレイヤー境界マーカーとして使用します。アンカーとレイヤー構造は、アクティブな ModelProfile によって決まります。

まず、ステージ境界におけるモデルの残差の種類を確認します。SGLang では、python/sglang/srt/layers/layer_boundary/factories.py を通じて、attention/FFN の境界(add-norm、gated、iHC、mHC、post-norm、stream)が定義されています。バックエンドのディスパッチによって、実際に見える境界カーネルが決まります。

V4 では現在、各ハーフの開始位置が mhc_pre_big_fuse* です。attention-pre と FFN-pre の順で、レイヤーあたり 2 つのアンカーがあります。post+pre の融合により、SGLang のトークン数が少ないトレースでは mhc_post_tilelang がなくなります。この古いアンカーは、未融合であることが確認済みのトレース、または 32 トークンを超えるパスに限って使用してください。V4.1 では前のサブレイヤーの pre-mix を使用し、レイヤー間のこの融合パスを無効にするため、常に明示的なアンカーの証拠が必要です。FlashMLA の flash_fwd_mla_combine はバックエンドと分割数に依存します。SM100 の SGLang V3 では、デフォルトで TRT-LLM MLA が使用されますが、DSA モデルでは DSA が使用されます。

すべてのスクリプトで、--blocks-per-layer K --anchor-offset I --pid PID --device D を指定できます。I は選択した GPU で検証済みの最初のレイヤーアンカーであり、カウントから推定した値ではありません。ランクやデバイスが混在する場合や、カウントを N*K で割った余りがある場合は拒否されます。カウントが割り切れることは必要条件ですが、十分条件ではありません。対象/ドラフトの各フェーズ、MTP/DSPARK のパス、TBO のマイクロバッチをあらかじめ分離してください。K3 の追加の出力集約については、これらのタイミング解析スクリプトでフェーズを絞り込んだトレースが必要です。レイヤー追跡ヘルパーでは、追加アンカーを明示的にサポートしています。選択した最後のパスは、選択した GPU イベントの境界で終了します。この境界自体が、完全なパスの終端であることを確認する必要があります。アンカーは移動の目安となる区間であり、別ストリームのカーネルがその区間と重なることがあります。

コンパイル済みの vLLM トレースでは、ノームが Inductor カーネルに変換される場合があります。明示的なノームのカスタムオペレーションまたは eager 実行を使用して短いマッピング用トレースを取得し、実際に測定したトレース上で attention/バックエンドのアンカーを確認してください。

ソース監査 2026-10-05:SGLang V4 ディスパッチ、 mHC カーネル、 vLLM mHC ディスパッチ。

スクリプト

1. layer_timeline_analyzer.py — レイヤーごとのタイムラインとクラスター統計
# Show all forward passes summary (cold-start vs steady-state)
python3 scripts/layer_timeline_analyzer.py \
  --trace /path/to/TP-0.trace.json.gz \
  --config /path/to/config.json \
  --show-all-passes

# Detailed per-layer breakdown for a specific forward pass
python3 scripts/layer_timeline_analyzer.py \
  --trace /path/to/TP-0.trace.json.gz \
  --config /path/to/config.json \
  --fwd-pass 5

# Auto-select the first relatively stable pass window
python3 scripts/layer_timeline_analyzer.py \
  --trace /path/to/TP-0.trace.json.gz \
  --config /path/to/config.json

スクリプトの出力:

  • レイヤーごとの実時間、合計時間、カテゴリ別の内訳(MLA、MoE、GEMM、NCCL、MHC、Hadamard)
  • 種類別(CSA_C4、HCA_C128、HASH など)にグループ化したレイヤークラスターの統計
  • コールドスタートから定常状態への推移を示す全パスの概要

定常状態の自動選択では、レイヤー 0 のタイミング変化が 5% 以内に収まる状態が 2 レイヤー連続することを条件とします。絶対レイテンシのしきい値は使用しないため、同じルールを異なるモデルサイズやアクセラレーターに適用できます。安定したウィンドウが見つからない場合は、--fwd-pass を明示的に選択してください。

2. layer_kernel_breakdown.py — レイヤーごとのカーネル詳細と計算フロー
# Single layer kernel dump
python3 scripts/layer_kernel_breakdown.py \
  --trace /path/to/TP-0.trace.json.gz \
  --config /path/to/config.json \
  --fwd-pass 5 --layer 3

# Compute flow format (with model architecture summary and category column)
python3 scripts/layer_kernel_breakdown.py \
  --trace /path/to/TP-0.trace.json.gz \
  --config /path/to/config.json \
  --fwd-pass 5 --layer 3 --format compute-flow

# JSON export
python3 scripts/layer_kernel_breakdown.py \
  --trace /path/to/TP-0.trace.json.gz \
  --config /path/to/config.json \
  --fwd-pass 5 --layer 3 --format json

# Compare two layers side-by-side
python3 scripts/layer_kernel_breakdown.py \
  --trace /path/to/TP-0.trace.json.gz \
  --config /path/to/config.json \
  --fwd-pass 5 --layer 2 --compare-layer 3

出力形式:

  • --format text(デフォルト):グループ化した概要と、簡略名および割合を含む、所要時間順の上位ホットカーネル
  • --format compute-flow:モデルアーキテクチャの概要と、Category、%、ts_rel(ms) の各列を含むカーネルごとのホット度テーブル
  • --format json:所要時間順の、機械可読な単一の JSON ドキュメント。--compare-layer を指定すると、primary、comparison、kernel_diff が含まれます
  • 2 つのレイヤーを比較する場合のカーネル差分(それぞれのレイヤーに固有のカーネル)
3. perfetto_time_mapper.py — Perfetto UI の時間ナビゲーション
# Show all forward pass time ranges in Perfetto
python3 scripts/perfetto_time_mapper.py \
  --trace /path/to/TP-0.trace.json.gz \
  --config /path/to/config.json

# Layer-level time ranges for a specific forward pass
python3 scripts/perfetto_time_mapper.py \
  --trace /path/to/TP-0.trace.json.gz \
  --config /path/to/config.json \
  --fwd-pass 5 --layers 2,3,38,42

スクリプトの出力:

  • Perfetto 相対秒単位のフォワードパスの時間範囲
  • compress_ratio ラベル付きのレイヤーごとの開始/終了時刻

ワークフロー

ステップ 1:定常状態のフォワードパスを特定する
python3 scripts/layer_timeline_analyzer.py \
  --trace $TRACE --config $CONFIG --show-all-passes

「all-passes」テーブルを確認します。最初のパスはコールドスタートです(トークン数が少ない状態)。 スクリプトで選択された最初の相対安定性ウィンドウを使用するか、計測時間が変化し続ける場合は パスを明示的に選択します。

ステップ 2:定常状態のパスにおけるレイヤーごとの内訳
python3 scripts/layer_timeline_analyzer.py \
  --trace $TRACE --config $CONFIG --fwd-pass 5

以下を特定します。

  • どのレイヤータイプが支配的か(CSA_C4、HCA_C128、HASH のいずれか)
  • レイヤータイプごとの MLA/MoE/GEMM/NCCL の割合
  • 次の最適化対象として最適なレイヤータイプ
ステップ 3:代表的なレイヤーの計算フロー

ボトルネックの種類ごとに 1 つずつ、代表的なレイヤーを 1〜2 個選択してから、次を実行します。

# Human-readable compute flow table
python3 scripts/layer_kernel_breakdown.py \
  --trace $TRACE --config $CONFIG \
  --fwd-pass 5 --layer 3 --format compute-flow

# JSON export
python3 scripts/layer_kernel_breakdown.py \
  --trace $TRACE --config $CONFIG \
  --fwd-pass 5 --layer 3 --format json > /tmp/layer3_detail.json

--format compute-flow の出力には、以下が含まれます。

  • 上部のモデルアーキテクチャの概要
  • カーネルのホット度をレイヤーごとに示すテーブル(# | Half | Category | Simplified Name | dur(us) | % | ts_rel(ms) | Input Dims)
  • デフォルトでは、行は dur(us) の降順に並びます。ts_rel(ms) を使うと、カーネルのトレース位置に移動できます。
ステップ 4:レイヤータイプを比較する(任意)
python3 scripts/layer_kernel_breakdown.py \
  --trace $TRACE --config $CONFIG \
  --fwd-pass 5 --layer 2 --compare-layer 3

2 つのレイヤータイプ間のカーネルの正確な違いが表示されます。

ステップ 5:Perfetto UI で移動する(任意)
python3 scripts/perfetto_time_mapper.py \
  --trace $TRACE --config $CONFIG \
  --fwd-pass 5 --layers 2,3,38,42

出力された時間範囲を使って、Perfetto 内の該当箇所に直接移動します。

レイヤータイプの分類

スクリプトは config.json のフィールドに基づいてレイヤーを分類します。

設定フィールド値レイヤータイプ説明
compress_ratios[i]0SWA_ONLYウィンドウのみのアテンション。コンプレッサー/インデクサーなし
compress_ratios[i]4CSA_C4コンプレッサー + Lightning インデクサー(Hadamard/paged-MQA/top-k)+ スパースアテンション
compress_ratios[i]128HCA_C128コンプレッサー + すべての圧縮済み行とウィンドウ。インデクサーなし
compress_ratios[i]2 / 1V41_C2 / V41_C1ソースレイヤーのコンプレッサー/インデクサー。他のレイヤーは KV/インデックスを共有
i < num_hash_layers—+HASH最初の N レイヤーにおけるハッシュルーティング。FIRST/FINAL と組み合わせ可能
i == 0 / N-1—+FIRST / +FINAL位置フラグ。アテンション/ルーティング処理を置き換えることはありません

V4 Flash/Pro は L0〜2 をハッシュルーティングします。V4.1 にはハッシュレイヤーがありません。KV ソースレイヤーは [2,8,14,20]、インデックスソースは [2,8,14,20,24,28,32,36]、候補ソースは 20、Engram レイヤーは [1,14] です。代表レイヤーを選ぶ際は、これらの役割フィールドを使います。 Pro は ratio-128 のレイヤーから始まるため、最初の 2 つが SWA だと仮定しないでください。 K3 の KDA レイヤー ID は 1 始まりですが、GLM-5 Next は 0 始まりの KDA ID を使用します。

カーネルカテゴリ

カーネルは、アクティブな ModelProfile のルールに基づいて分類されます。(DSv4)と記されたカテゴリは dsv4_csa_hca プロファイルに固有です。すべてのプロファイルには、共通カテゴリが含まれます。

カテゴリマッチパターンプロファイル典型的な割合(DSv4)
★ MLA アテンションflash_fwd_splitkv_mlaDSv4, DSv321-33%
★ MoE 融合fused_moe_kernelDSv4, DSv311-17%
● NCCL AllReduce大文字と小文字を区別しない allreduce、all_reduce、cross_device_reduce、reduce_scatter、NCCL/Lamportuniversal5-8%
GEMM fp8deep_gemmuniversal12-25%
GEMM bf16nvjetuniversal11-13%
Hadamard XformhadamardDSv40-2.4%
インデクサーキャッシュindexerDSv40-0.1%
Paged MQApaged_mqa_logitsDSv40-1.8%
MHCmhc_pre_gemm_sqrsum、mhc_pre_big_fuse、mhc_post_tilelangDSv410-15%
C4/C128 プリフィルc4_prefill、c128_prefillDSv40-0.3%
RMSNorm大文字と小文字を区別しない rms_?norm、layernormuniversal1-2%
FP8 量子化quant、Quantuniversal1-2%
TopKtopkuniversal0-0.7%
RoPEdeepseek_rope、fused_norm_ropeDSv4, DSv31-2%
アクティベーションsilu_mul_clamp、act_and_muluniversal0-0.5%
その他—universal2-5%

報告チェックリスト

以下を含めてください。

  1. トレースのメタデータ:トレースのパス、モデル設定のパス、GPU の種類、TP/EP
  2. モデルアーキテクチャの概要(config.json より):
    • モデル名、num_layers、hidden_size、num_attention_heads、num_key_value_heads、head_dim
    • アテンションの種類(例:csa_hca)、Q/O LoRA のランク
    • MoE の設定:num_experts、topk、num_shared_experts、intermediate_size
    • MHC の設定(該当する場合)
    • NSA の設定(該当する場合):index_n_heads、index_head_dim、index_topk、qk_rope_head_dim、sliding_window
    • compress_ratios の分布(CSA_C4 / HCA_C128 / SWA_ONLY / HASH レイヤーの数)
  3. バッチごとのフォワードパスの概要表(layer_timeline_analyzer.py --show-all-passes より):
    • 列:Fwd#、Start(s)、End(s)、Duration(ms)、Avg Layer(ms)、First Layer(ms)、Notes
    • コールドスタートと定常状態のパスを特定します
  4. 選択したフォワードパス:インデックスと選択理由(コールドスタートか定常状態か)
  5. レイヤーごとの実時間と合計所要時間の表(layer_timeline_analyzer.py --fwd-pass N より):
    • 列:L、c_r、Type、Wall(ms)、SumDur(ms)、MLA、MoE、GEMM、NCCL、MHC、Hadam、AR#、K#
    • 各行は 1 つのレイヤーを表し、レイヤーの種類を示すラベルを付けます
  6. レイヤークラスターの統計表(種類ごとにグループ化):
    • 列:Cluster、#、Avg Wall(ms)、Avg Sum(ms)、MLA%、MoE%、GEMM%、NCCL%、MHC%、Hadam%
    • ボトルネックとなるレイヤーの種類と、次に調査すべき対象を特定します
  7. 選択した代表的なレイヤーの計算フロー表:
    • layer_kernel_breakdown.py --format compute-flow によって生成されます
    • 列:# | Half | Category | Simplified Name | dur(us) | % | ts_rel(ms) | Input Dims
    • デフォルトでは、上位のホットカーネル(dur(us) の降順)に従って行を並べます
    • JSON へのエクスポートも可能です(--format json)
  8. 要求された場合は Perfetto UI の時間範囲
  9. 1 行の要約:ボトルネックとなるレイヤーの種類と、次に調査すべき対象

コメント