# 機能設計書 99-モデル分析

## 概要

本ドキュメントは、TensorFlowにおけるモデル分析（Model Analyzer）機能の設計を記述する。モデルのパラメータ数・FLOPs・メモリ使用量・実行時間の分析機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：モデルの最適化にあたり、パラメータ数、計算量（FLOPs）、メモリ使用量、各操作の実行時間を定量的に把握する必要がある。本機能は、TensorFlow 1.x向けのモデルプロファイリングAPIとして、計算グラフの構造分析、実行時メタデータに基づく性能分析、および自動アドバイス生成を提供する。

**機能の利用シーン**：モデルのパラメータ数確認、ボトルネックOp特定、メモリ使用量プロファイリング、タイムライン生成、自動パフォーマンスアドバイス取得などに使用される。

**主要な処理内容**：
1. `Profiler`クラス - マルチステッププロファイリング（グラフ分析、Op分析、名前スコープ分析、Python分析）
2. `profile()`関数 - ワンショットプロファイリング（scope, op, graph, code の4ビュー）
3. `advise()`関数 - 自動問題検出とアドバイス生成
4. `ProfileOptionBuilder` - プロファイルオプションの構築

**関連システム・外部連携**：RunMetadata、計算グラフ（tf.Graph）、TensorBoard、tfprof CLIと連携する。

**権限による制御**：1プロセスあたり1つのプロファイラインスタンスのみ作成可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はAPI機能であり、直接関連する画面はない |

## 機能種別

プロファイリング・分析処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| graph | tf.Graph | No | 分析対象のグラフ（Noneの場合デフォルトグラフ） | - |
| run_meta | RunMetadata | No | 実行時メタデータ（時間・メモリ情報） | - |
| op_log | OpLogProto | No | Op種別のカスタム定義 | - |
| cmd | string | Yes（profile） | 分析ビュー: "scope", "op", "graph", "code" | 4種のいずれか |
| options | dict | No | プロファイルオプション | - |
| step | int | Yes（add_step） | ステップID | - |

### 入力データソース

tf.Graph（計算グラフ構造）とRunMetadata（実行時統計）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| GraphNodeProto | protobuf | scope/graphビューの結果 |
| MultiGraphNodeProto | protobuf | op/codeビューの結果 |
| AdviceProto | protobuf | 自動アドバイス結果 |
| ProfileProto | binary | シリアライズされたプロファイルデータ |

### 出力先

stdout、ファイル、timeline.json（options['output']で指定）。

## 処理フロー

### 処理シーケンス

```
1. グラフ情報の収集
   └─ graph.as_graph_def(add_shapes=True)でグラフを文字列化
2. OpLog情報のマージ
   └─ tfprof_logger.merge_default_with_oplogで型情報をマージ
3. プロファイラ初期化（Profilerクラスの場合）
   └─ print_mdl.NewProfiler()でC++プロファイラを生成
4. ステップ情報の追加（マルチステップの場合）
   └─ print_mdl.AddStep()でRunMetadataを追加
5. プロファイル実行
   └─ print_mdl.Profile() or print_mdl.PrintModelAnalysis()
6. 結果のデシリアライズ
   └─ ProtoBufバイト列をGraphNodeProto/MultiGraphNodeProtoにパース
```

### フローチャート

```mermaid
flowchart TD
    A[グラフ + RunMetadata] --> B[OpLogマージ]
    B --> C{使用方法?}
    C -->|Profilerクラス| D[NewProfiler生成]
    D --> E[AddStepでステップ追加]
    E --> F{分析ビュー?}
    C -->|profile関数| G[PrintModelAnalysis呼出]
    F -->|scope| H[profile_name_scope]
    F -->|op| I[profile_operations]
    F -->|graph| J[profile_graph]
    F -->|code| K[profile_python]
    G --> L[結果ProtoBufパース]
    H --> L
    I --> L
    J --> L
    K --> L
    C -->|advise関数| M[自動アドバイス生成]
    M --> N[AdviceProtoパース]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-99-01 | v1 API | 本機能はTensorFlow v1 APIであり、`tf.compat.v1.profiler`配下 | 常時 |
| BR-99-02 | プロファイラ単一性 | 1プロセスにつき1つのプロファイラのみ作成可能 | 常時 |
| BR-99-03 | ビュー種別 | cmdは "scope", "op", "graph", "code" のいずれか | profile()使用時 |
| BR-99-04 | Eagerモード | Eager実行時はgraph=Noneで動作 | Eager Execution時 |

### 計算ロジック

プロファイルオプション構築（_build_options）:
- max_depth: 表示深度（デフォルト: 10）
- min_bytes, min_micros: フィルタリング閾値
- order_by: ソート基準（デフォルト: "name"）
- select: 表示フィールド選択
- output: 出力先（stdout, file, timeline等）

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgumentError | cmd不正 | cmdが "scope", "op", "graph", "code" のいずれでもない | 有効なcmdを指定 |
| DecodeError | パースエラー | 返却されたProtoBufのパースに失敗 | C++側の出力を確認 |

### リトライ仕様

リトライ不要。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- プロファイルデータの収集にはRunMetadataの取得が必要（FULL_TRACEモード）
- 大規模グラフの分析にはメモリと処理時間が必要

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

- プロファイルデータにモデル構造やOp名が含まれる
- dump_to_fileオプション使用時はファイルアクセス権限に注意

## 備考

- 自動アドバイス（advise）の4つのチェッカー：
  - ExpensiveOperationChecker: 高コストOp検出
  - AcceleratorUtilizationChecker: アクセラレータ利用率チェック
  - JobChecker: ジョブ設定チェック（内部専用）
  - OperationChecker: Op設定チェック
- serialize_to_string()でプロファイルデータをバイナリ保存し、オフライン分析に使用可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | tfprof_options_pb2.py | `tensorflow/core/profiler/tfprof_options_pb2.py` | OptionsProto, AdvisorOptionsProtoの構造 |
| 1-2 | tfprof_output_pb2.py | `tensorflow/core/profiler/tfprof_output_pb2.py` | GraphNodeProto, MultiGraphNodeProto, AdviceProtoの構造 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | model_analyzer.py | `tensorflow/python/profiler/model_analyzer.py` | `profile()`関数（311-382行目） |
| 2-2 | model_analyzer.py | `tensorflow/python/profiler/model_analyzer.py` | `advise()`関数（386-422行目） |

**主要処理フロー**:
1. **341-342行目**: `profile()` - デフォルトグラフの取得（Eager非対応時）
2. **348-349行目**: OpLogのマージ（add_trace=True for code view）
3. **352行目**: オプションのProtoBuf変換
4. **358-363行目**: op/codeビュー → MultiGraphNodeProto
5. **369-374行目**: graph/scopeビュー → GraphNodeProto
6. **380行目**: 不正cmd → InvalidArgumentError

#### Step 3: Profilerクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | model_analyzer.py | `tensorflow/python/profiler/model_analyzer.py` | `Profiler`クラス（122-307行目） |

**主要処理フロー**:
- **161-178行目**: `__init__` - グラフ文字列化、OpLogマージ、C++プロファイラ生成
- **183-199行目**: `add_step` - ステップ情報の追加
- **201-221行目**: `profile_python` - codeビュー分析
- **223-241行目**: `profile_operations` - opビュー分析
- **243-259行目**: `profile_name_scope` - scopeビュー分析
- **261-277行目**: `profile_graph` - graphビュー分析
- **279-292行目**: `advise` - 自動アドバイス

#### Step 4: オプションビルダーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | option_builder.py | `tensorflow/python/profiler/option_builder.py` | `ProfileOptionBuilder`クラス |

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

```
tf.compat.v1.profiler.profile(graph, run_meta, cmd, options)
    │
    ├─ tfprof_logger.merge_default_with_oplog(graph, op_log, run_meta)
    ├─ _build_options(options) → OptionsProto
    ├─ _graph_string(graph) → シリアライズ
    └─ print_mdl.PrintModelAnalysis(graph_str, run_meta_str, op_log_str, cmd, opts)
           └─ → GraphNodeProto / MultiGraphNodeProto

Profiler(graph, op_log)
    │
    ├─ __init__
    │      ├─ tfprof_logger.merge_default_with_oplog
    │      └─ print_mdl.NewProfiler(graph_str, op_log_str)
    │
    ├─ add_step(step, run_meta)
    │      └─ print_mdl.AddStep(step, graph_str, run_meta_str, op_log_str)
    │
    ├─ profile_name_scope / profile_operations / profile_graph / profile_python
    │      ├─ _build_options(options)
    │      └─ print_mdl.Profile(cmd, opts)
    │
    └─ advise(options)
           ├─ _build_advisor_options(options)
           └─ print_mdl.Profile('advise', opts)
```

### データフロー図

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

tf.Graph             ───▶  as_graph_def().Serialize()   ───▶  graph_str
RunMetadata          ───▶  Serialize()                  ───▶  run_meta_str
OpLogProto           ───▶  merge_default_with_oplog     ───▶  op_log_str
options (dict)       ───▶  _build_options()             ───▶  OptionsProto

graph_str + run_meta_str + op_log_str + cmd + opts
                     ───▶  PrintModelAnalysis (C++)     ───▶  ProtoBuf bytes
                     ───▶  ParseFromString()            ───▶  GraphNodeProto /
                                                               MultiGraphNodeProto /
                                                               AdviceProto
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| model_analyzer.py | `tensorflow/python/profiler/model_analyzer.py` | ソース | Profilerクラスとprofile/advise関数 |
| option_builder.py | `tensorflow/python/profiler/option_builder.py` | ソース | ProfileOptionBuilderクラス |
| tfprof_logger.py | `tensorflow/python/profiler/tfprof_logger.py` | ソース | OpLogマージユーティリティ |
| _pywrap_tfprof.py | `tensorflow/python/util/_pywrap_tfprof.py` | バインディング | C++ tfprofのPythonバインディング |
| tfprof_options_pb2.py | `tensorflow/core/profiler/tfprof_options_pb2.py` | ProtoBuf | オプション定義 |
| tfprof_output_pb2.py | `tensorflow/core/profiler/tfprof_output_pb2.py` | ProtoBuf | 出力定義 |
