# 通知設計書 22-ProfilerHook

## 概要

本ドキュメントは、TensorFlowの`tf.train.ProfilerHook`の通知設計について記載する。本フックは、トレーニング中にCPU/GPUプロファイリング情報を定期的に収集し、Chrome Trace形式のファイルとして保存するSessionRunHookである。

### 本通知の処理概要

ProfilerHookは、指定されたステップ数または秒数ごとにTensorFlowセッションの実行プロファイル情報を収集し、timeline JSONファイルおよびSummaryWriterへのメタデータとして出力する。

**業務上の目的・背景**：機械学習モデルのトレーニングにおいて、パフォーマンスのボトルネックを特定することは効率化の鍵である。ProfilerHookは、セッションの実行メタデータ（RunMetadata）を定期的にキャプチャし、Chrome DevToolsで可視化可能なトレース形式で保存することで、開発者がオペレーションレベルのパフォーマンス分析を行えるようにする。

**通知の送信タイミング**：`SecondOrStepTimer`により制御される。`save_steps`が設定されている場合はNステップごと、`save_secs`が設定されている場合はN秒ごとにプロファイル情報を収集する。最初のステップではタイマーの初期化のみ行い、実際のプロファイリングは2回目以降のステップから開始する。

**通知の受信者**：ファイルシステム上のtimelineファイル（`timeline-{step}.json`）およびSummaryWriterが受信者となる。TensorBoardやChrome DevToolsを使用する開発者・運用者が最終的な情報消費者である。

**通知内容の概要**：プロファイル情報にはオペレーションの実行時間、データフロー、メモリ使用量（オプション）が含まれる。Chrome Trace形式のJSONファイルとして保存され、ステップごとの実行メタデータがSummaryWriterにも記録される。

**期待されるアクション**：開発者はtimelineファイルをChrome DevTools（chrome://tracing）で開き、パフォーマンスボトルネックを分析する。TensorBoardのプロファイルタブでも実行メタデータを確認できる。

## 通知種別

ファイル出力（Chrome Trace JSON）/ TensorBoardサマリー（RunMetadata）/ ログ出力（INFO）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（session.run実行後に保存） |
| 優先度 | 中（パフォーマンス分析用） |
| リトライ | 無し |

### 送信先決定ロジック

出力先は固定で、コンストラクタで指定された`output_dir`に`timeline-{step}.json`形式でファイルが保存される。SummaryWriterも同じ`output_dir`に対して作成される。

## 通知テンプレート

### ファイル出力の場合

| 項目 | 内容 |
|-----|------|
| 出力先 | `{output_dir}/timeline-{step}.json` |
| 形式 | Chrome Trace Format (JSON) |
| SummaryWriter | `{output_dir}/` 配下にイベントファイル |

### 本文テンプレート

```json
{
  "traceEvents": [
    {"name": "op_name", "cat": "Op", "ph": "X", "ts": ..., "dur": ..., "pid": ..., "tid": ...},
    ...
  ],
  "metadata": {...}
}
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| timeline-{step}.json | JSON (Chrome Trace) | タイマートリガー時 | ステップごとのプロファイルデータ |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| step | グローバルステップ番号 | session.run(global_step_tensor) | Yes |
| step_stats | ステップ実行統計 | run_values.run_metadata.step_stats | Yes |
| show_dataflow | データフローイベント表示 | コンストラクタ引数（デフォルトTrue） | No |
| show_memory | メモリイベント表示 | コンストラクタ引数（デフォルトFalse） | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| SessionRunフック | before_run()/after_run() | SecondOrStepTimerの条件を満たした場合 | save_stepsまたはsave_secsで制御 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 最初のステップ | `_next_step`がNoneの場合（初回）はプロファイリングを行わず、タイマーの初期化のみ実行 |
| タイマー条件未満 | SecondOrStepTimerの条件（Nステップまたは秒）を満たしていない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[before_run発火] --> B{_next_step is not None?}
    B -->|No| C[_request_summary = False]
    B -->|Yes| D{timer.should_trigger?}
    D -->|Yes| E[_request_summary = True]
    D -->|No| C
    E --> F[RunOptions FULL_TRACE設定]
    C --> G[SessionRunArgs返却]
    F --> G
    G --> H[session.run実行]
    H --> I[after_run発火]
    I --> J{_next_step is None?}
    J -->|Yes| K[タイマー初期化]
    J -->|No| L{_request_summary?}
    L -->|Yes| M[global_step取得]
    M --> N[タイマー更新]
    N --> O[_save timeline JSON]
    O --> P[SummaryWriter.add_run_metadata]
    L -->|No| Q[_next_step更新]
    K --> Q
    P --> Q
```

## データベース参照・更新仕様

### 参照テーブル一覧

本フックはデータベースを直接参照しない。TensorFlowセッション内のグローバルステップテンソルおよびRunMetadataを参照する。

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| （なし） | - | TFグラフ内のglobal_stepテンソルとRunMetadataを使用 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| ファイルシステム | WRITE | timeline-{step}.jsonファイルの書き出し |
| SummaryWriter | WRITE | RunMetadataのイベント記録 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| RuntimeError | グローバルステップが作成されていない場合（begin()内） | "Global step should be created to use ProfilerHook."メッセージで例外送出 |
| ファイル書き込みエラー | output_dirが存在しないまたは書き込み権限がない場合 | gfile.Openが例外を送出 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| ステップ間隔 | save_stepsで指定（Nステップごと） |
| 時間間隔 | save_secsで指定（N秒ごと） |

### 配信時間帯

制限なし。トレーニング中に継続的に動作する。

## セキュリティ考慮事項

- プロファイルデータにはオペレーション名やテンソル形状が含まれるため、モデルアーキテクチャの情報が漏洩する可能性がある
- output_dirのアクセス権限を適切に設定する必要がある
- 本番環境での使用は推奨されない（パフォーマンスオーバーヘッドが大きい）

## 備考

- Chrome Trace形式の詳細は https://github.com/catapult-project/catapult/blob/master/tracing/README.md を参照
- FULL_TRACE RunOptionsを設定するため、プロファイリングステップの実行速度は通常ステップよりも遅くなる
- TensorFlow v1 APIに属する

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

プロファイリングに関わるデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | session_run_hook.py | `tensorflow/python/training/session_run_hook.py` | SessionRunArgsのoptions引数とSessionRunValuesのrun_metadataフィールド（行186-284） |
| 1-2 | config_pb2 | `tensorflow/core/protobuf/config.proto` | RunOptions.trace_level定義（FULL_TRACE等） |

**読解のコツ**: ProfilerHookはRunOptions.FULL_TRACEを設定することでsession.run()にメタデータ収集を依頼し、結果をrun_values.run_metadataから取得する。

#### Step 2: エントリーポイントを理解する

ProfilerHookの実装を読み解く。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | basic_session_run_hooks.py | `tensorflow/python/training/basic_session_run_hooks.py` | ProfilerHookクラス定義（行1012-1095） |

**主要処理フロー**:
1. **行1023-1052**: `__init__()` - output_file, file_writer, timer, show_dataflow, show_memoryの初期化
2. **行1054-1058**: `begin()` - global_step_tensorの取得
3. **行1060-1069**: `before_run()` - タイマー確認、FULL_TRACEオプション設定
4. **行1071-1086**: `after_run()` - プロファイルデータの保存とSummaryWriterへの記録
5. **行1088-1094**: `_save()` - timeline JSONファイルの書き出し

#### Step 3: タイマーメカニズムを理解する

SecondOrStepTimerの動作を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | basic_session_run_hooks.py | `tensorflow/python/training/basic_session_run_hooks.py` | SecondOrStepTimerクラス（行86-150） |

**主要処理フロー**:
- **行109-134**: `should_trigger_for_step()` - 時間またはステップに基づくトリガー判定

#### Step 4: タイムライン生成を理解する

Chrome Trace形式の生成メカニズムを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | timeline.py | `tensorflow/python/client/timeline.py` | Timelineクラスの`generate_chrome_trace_format()`メソッド |

### プログラム呼び出し階層図

```
MonitoredSession.run()
    |
    +-- ProfilerHook.begin()
    |       +-- training_util._get_or_create_global_step_read()
    |
    +-- ProfilerHook.before_run(run_context)
    |       +-- SecondOrStepTimer.should_trigger_for_step()
    |       +-- [トリガー時] config_pb2.RunOptions(FULL_TRACE)
    |       +-- SessionRunArgs(requests, options=opts)
    |
    +-- session.run(fetches, options=RunOptions.FULL_TRACE)
    |
    +-- ProfilerHook.after_run(run_context, run_values)
            +-- SecondOrStepTimer.update_last_triggered_step()
            +-- ProfilerHook._save()
            |       +-- timeline.Timeline(step_stats)
            |       +-- trace.generate_chrome_trace_format()
            |       +-- gfile.Open(save_path, "w")
            +-- SummaryWriterCache.add_run_metadata()
```

### データフロー図

```
[入力]                      [処理]                           [出力]

global_step_tensor ------> ProfilerHook -----------------> timeline-{step}.json
(TFグラフ)                  .before_run()                   (Chrome Trace JSON)
                            .after_run()
RunOptions.FULL_TRACE ---> session.run() ----------------> run_metadata
                                                            |
run_metadata.step_stats -> Timeline.generate_chrome_trace   +-> SummaryWriter
                            _format()                          (event file)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| basic_session_run_hooks.py | `tensorflow/python/training/basic_session_run_hooks.py` | ソース | ProfilerHookの実装（行1012-1095） |
| session_run_hook.py | `tensorflow/python/training/session_run_hook.py` | ソース | SessionRunHook基底クラス定義 |
| timeline.py | `tensorflow/python/client/timeline.py` | ソース | Chrome Trace形式のタイムライン生成 |
| config.proto | `tensorflow/core/protobuf/config.proto` | 設定 | RunOptions定義（trace_level） |
| summary_io.py | `tensorflow/python/training/summary_io.py` | ソース | SummaryWriterCacheの提供 |
| training_util.py | `tensorflow/python/training/training_util.py` | ソース | グローバルステップテンソルの取得 |
