# 機能設計書 62-SavedModel保存

## 概要

本ドキュメントは、TensorFlowにおける学習済みモデルをSavedModel形式で保存する機能の設計を記述する。

### 本機能の処理概要

SavedModel保存機能は、TensorFlowの学習済みモデル（変数、計算グラフ、シグネチャ、アセット等）を言語中立・プラットフォーム中立なSavedModel形式でディスクにシリアライズする機能である。保存されたモデルはPython、C++、JavaScript等の異なる言語ランタイムから読み込むことができ、TensorFlow Serving、TensorFlow Lite、TensorFlow.jsなど多様なデプロイメントターゲットで利用可能となる。

**業務上の目的・背景**：機械学習モデルの学習と推論は異なる環境で行われることが多い。学習環境で構築したモデルを本番推論環境にデプロイするためには、モデルの完全な状態（重み、グラフ構造、前処理/後処理ロジック）を標準化された形式で保存する必要がある。SavedModel形式はTensorFlowの公式モデル交換フォーマットであり、この課題を解決する。

**機能の利用シーン**：モデルの学習完了後のエクスポート、モデルバージョン管理のための定期保存、TensorFlow Servingへのデプロイ、TFLite変換のための中間フォーマットとしての保存、転移学習のためのベースモデル共有。

**主要な処理内容**：
1. Trackableオブジェクトグラフの走査と依存関係の解決
2. tf.functionのトレーシングとConcreteFunction（具象関数）のシリアライズ
3. 変数値のチェックポイントファイルへの保存
4. SignatureDefの構築とMetaGraphDefへの書き込み
5. アセットファイルのコピーとSavedModel protobufの書き出し
6. フィンガープリントの生成と保存

**関連システム・外部連携**：ファイルシステム（ローカル、GCS、S3等）への書き込み。チェックポイントシステムとの連携。

**権限による制御**：出力ディレクトリへの書き込み権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | 画像分類画面 | 補助機能 | tensorflow_inception_graph.pbモデルファイルの読み込み（事前保存済みモデルの利用） |
| 2 | 物体検出画面 | 補助機能 | ssd_mobilenet_v1等モデルファイルの読み込み |
| 3 | スタイル変換画面 | 補助機能 | stylize_quantized.pbモデルファイルの読み込み |
| 4 | 音声認識画面 | 補助機能 | conv_actions_frozen.pbモデルファイルの読み込み |

## 機能種別

データ連携（モデルシリアライゼーション）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| obj | Trackable | Yes | 保存対象のTrackableオブジェクト（モデル等） | Trackableインスタンスであること |
| export_dir | str | Yes | SavedModelの出力ディレクトリパス | 空でないディレクトリが存在しないこと |
| signatures | dict/ConcreteFunction | No | 入出力シグネチャの定義 | ConcreteFunctionまたはそのdict |
| options | SaveOptions | No | 保存オプション（namespace等） | SaveOptionsインスタンスであること |

### 入力データソース

Python上のTrackableオブジェクト（tf.Module、Kerasモデル、tf.Variableなど）のインメモリ状態。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| saved_model.pb | Protocol Buffer | SavedModelプロトコルバッファ（MetaGraphDef、SignatureDef等を含む） |
| variables/ | ディレクトリ | チェックポイントファイル（変数値） |
| assets/ | ディレクトリ | アセットファイル（語彙テーブル等） |
| fingerprint.pb | Protocol Buffer | SavedModelフィンガープリント |

### 出力先

指定されたexport_dirディレクトリ配下のファイルシステム。

## 処理フロー

### 処理シーケンス

```
1. 出力ディレクトリの検証と作成
   └─ ディレクトリが空であることを確認、存在しなければ作成
2. オブジェクトグラフの走査
   └─ _AugmentedGraphViewを構築し、全Trackableオブジェクトを列挙
3. シグネチャの処理
   └─ tf.functionをトレースしConcreteFunctionを取得、SignatureDefを構築
4. _SaveableViewの構築
   └─ チェックポイントのsave/restore関数を生成
5. ノードとConcreteFunction のシリアライズ
   └─ SavedObjectGraphプロトコルバッファの構築
6. 変数のチェックポイント保存
   └─ functionalSaverによるチェックポイント書き出し
7. MetaGraphDefの構築
   └─ GraphDef、SignatureDef、AssetFileDefを統合
8. SavedModel protobufの書き出し
   └─ saved_model.pbファイルへのシリアライズ
9. アセットファイルのコピー
   └─ 関連アセットをassets/ディレクトリにコピー
10. フィンガープリントの生成
    └─ fingerprint.pbの書き出し
```

### フローチャート

```mermaid
flowchart TD
    A[tf.saved_model.save 呼び出し] --> B[出力ディレクトリ検証・作成]
    B --> C[_AugmentedGraphView 構築]
    C --> D[シグネチャ処理・トレース]
    D --> E[_SaveableView 構築]
    E --> F[SavedObjectGraph 構築]
    F --> G[変数チェックポイント保存]
    G --> H[MetaGraphDef 構築]
    H --> I[saved_model.pb 書き出し]
    I --> J[アセットファイルコピー]
    J --> K[フィンガープリント生成]
    K --> L[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-62-01 | 空ディレクトリ制約 | 出力ディレクトリが存在する場合、空でなければならない | export_dirが既に存在する場合 |
| BR-62-02 | シグネチャ自動推論 | signaturesが未指定の場合、__call__メソッドから自動推論を試みる | signatures=None |
| BR-62-03 | 未トレース関数警告 | tf.functionが未トレースの場合、警告をログ出力する | トレースされていないtf.functionが存在する場合 |
| BR-62-04 | アセット重複除去 | 同名のアセットは最初のバージョンのみ保持する | 複数MetaGraphが同名アセットを含む場合 |

### 計算ロジック

該当なし。

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

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

データベース操作は行わない。ファイルシステムへの書き込みのみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AssertionError | ディレクトリ非空エラー | export_dirが既に存在し空でない | 別のディレクトリを指定するか既存を削除 |
| ValueError | 無効なキャプチャ | カスタム勾配で不正なキャプチャが検出された | キャプチャされたテンソルを修正 |
| ValueError | シグネチャエラー | ConcreteFunction以外がシグネチャとして指定された | 正しいConcreteFunctionを指定 |

### リトライ仕様

ファイルシステムエラー（一時的なI/Oエラー等）の場合、ユーザー側でリトライが必要。

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

SavedModelの保存はアトミックではない。書き出し途中でエラーが発生した場合、不完全なSavedModelが残る可能性がある。

## パフォーマンス要件

大規模モデル（数GB）の保存には数十秒～数分を要する場合がある。変数のチェックポイント書き出しが主要なボトルネック。

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

- 保存されたSavedModelには学習済み重みが含まれるため、モデルの知的財産保護が必要な場合はアクセス制御を設定する
- SavedModelにはPython実行可能なグラフが含まれるため、信頼できないソースからのモデル読み込み時には注意が必要

## 備考

- TF1ではSavedModelBuilder APIを使用、TF2ではtf.saved_model.save関数を使用する
- `_SAVE_V2_LABEL`メトリクスラベルでSavedModel保存の使用状況が追跡される

---

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

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

### 推奨読解順序

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

SavedModelのシリアライゼーションで中心的な役割を果たすProtocol Bufferメッセージとクラスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | saved_model_pb2 | `tensorflow/core/protobuf/saved_model.proto` | SavedModelプロトコルバッファの構造（MetaGraphDef、SavedObjectGraph等） |
| 1-2 | save_options.py | `tensorflow/python/saved_model/save_options.py` | SaveOptionsクラスの属性と既定値 |

**読解のコツ**: SavedModelのプロトコルバッファ構造を理解することが最も重要。`saved_model_pb2.SavedModel`はトップレベルのメッセージで、`meta_graphs`フィールドに複数の`MetaGraphDef`を含む。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | save.py | `tensorflow/python/saved_model/save.py` | `tf.saved_model.save()`のエントリーポイント。`@tf_export`デコレータで公開API |

**主要処理フロー**:
1. **87行目**: `_UNCOPIABLE_DTYPES`定義（resource、variantは直接コピー不可）
2. **90-91行目**: `_CapturedTensor`NamedTupleの定義（外部関数からキャプチャされたテンソルの管理）
3. **100-113行目**: `_AugmentedGraphView`クラスの初期化。キャッシュの構築

#### Step 3: オブジェクトグラフの走査

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | save.py | `tensorflow/python/saved_model/save.py` | `_AugmentedGraphView`クラス（100-251行目） |
| 3-2 | save.py | `tensorflow/python/saved_model/save.py` | `_SaveableView`クラス（254-348行目） |

**主要処理フロー**:
- **115-129行目**: `_AugmentedGraphView.__init__`でキャッシュを初期化
- **131-148行目**: `set_signature`でシグネチャをルートオブジェクトに付加
- **185-203行目**: `list_children`でTrackableオブジェクトの子要素を列挙（キャッシュ付き）
- **269-286行目**: `_SaveableView.__init__`でオブジェクトIDとスロット変数のマッピングを構築
- **302-325行目**: save/restore関数の初期化

#### Step 4: SavedModelBuilder（TF1互換）

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | builder_impl.py | `tensorflow/python/saved_model/builder_impl.py` | `_SavedModelBuilder`クラス（48-115行目） |

**主要処理フロー**:
- **94-107行目**: コンストラクタでexport_dirの検証と初期化
- **117-135行目**: `_save_and_write_assets`でアセット保存
- **137-150行目**: `_tag_and_add_meta_graph`でメタグラフのタグ付けと追加

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

```
tf.saved_model.save(obj, export_dir, signatures)
    │
    ├─ _AugmentedGraphView(root)
    │      ├─ list_children(obj)  [Trackableオブジェクト列挙]
    │      └─ set_signature(signature_map)  [シグネチャ付加]
    │
    ├─ _SaveableView(augmented_graph_view, options)
    │      ├─ _initialize_save_and_restore_functions()
    │      └─ _initialize_nodes_and_concrete_functions()
    │
    ├─ checkpoint保存  [functional_saver経由]
    │
    ├─ MetaGraphDef構築
    │      └─ SignatureDef統合
    │
    ├─ saved_model.pb 書き出し
    │
    └─ fingerprinting_utils  [フィンガープリント生成]
```

### データフロー図

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

Trackable obj ───────────────▶ _AugmentedGraphView ──▶ ObjectGraph
  (tf.Module,                   │
   Keras Model)                 ├─ _SaveableView ────▶ SavedObjectGraph proto
                                │
signatures (optional) ────────▶ SignatureDef構築 ─────▶ MetaGraphDef
                                │
Variables ──────────────────────▶ functional_saver ──▶ variables/checkpoint
                                │
Asset files ───────────────────▶ copy_assets ────────▶ assets/
                                │
                                └─ fingerprinting ──▶ fingerprint.pb

                                最終出力: saved_model.pb + variables/ + assets/
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| save.py | `tensorflow/python/saved_model/save.py` | ソース | SavedModel保存のメインロジック（TF2 API） |
| builder_impl.py | `tensorflow/python/saved_model/builder_impl.py` | ソース | SavedModelBuilder（TF1互換API） |
| save_options.py | `tensorflow/python/saved_model/save_options.py` | ソース | 保存オプションの定義 |
| signature_serialization.py | `tensorflow/python/saved_model/signature_serialization.py` | ソース | シグネチャのシリアライゼーション |
| function_serialization.py | `tensorflow/python/saved_model/function_serialization.py` | ソース | 関数のシリアライゼーション |
| fingerprinting_utils.py | `tensorflow/python/saved_model/fingerprinting_utils.py` | ソース | フィンガープリント生成ユーティリティ |
| path_helpers.py | `tensorflow/python/saved_model/path_helpers.py` | ソース | パス関連ヘルパー |
| functional_saver.py | `tensorflow/python/checkpoint/functional_saver.py` | ソース | チェックポイントの関数型保存 |
| graph_view.py | `tensorflow/python/checkpoint/graph_view.py` | ソース | オブジェクトグラフの走査 |
