# 機能設計書 66-SavedModelフィンガープリンティング

## 概要

本ドキュメントは、TensorFlowにおけるSavedModelの一意識別用フィンガープリント生成を提供する機能の設計を記述する。

### 本機能の処理概要

SavedModelフィンガープリンティング機能は、SavedModelの内容に基づいてハッシュベースのフィンガープリントを生成し、SavedModelの一意識別・変更検出を可能にする機能である。フィンガープリントはsaved_model_checksum、graph_def_program_hash、signature_def_hash、saved_object_graph_hash、checkpoint_hashの5つのハッシュ値で構成される。

**業務上の目的・背景**：モデル管理・運用において、SavedModelのバージョン管理や改ざん検出は重要な課題である。フィンガープリントにより、同一のSavedModelであることを効率的に検証でき、モデルレジストリでの重複検出やCI/CDパイプラインでの変更検知に利用できる。

**機能の利用シーン**：モデルバージョン管理でのSavedModel同一性検証、モデルデプロイメント時の改ざん検出、CI/CDパイプラインでのモデル変更検知、モデルレジストリでの重複排除。

**主要な処理内容**：
1. SavedModel保存時のフィンガープリント自動生成
2. fingerprint.pbファイルへのフィンガープリント書き出し
3. 既存SavedModelからのフィンガープリント読み取り
4. Singleprint（正規化されたフィンガープリントID）の生成
5. フィンガープリント間の等価比較

**関連システム・外部連携**：SavedModel保存機能（No.62）との統合。C++実装のpywrap_saved_model.fingerprintingとの連携。

**権限による制御**：SavedModelディレクトリへの読み取り権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに該当なし |

## 機能種別

計算処理（ハッシュ生成）/ データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| export_dir (読み取り時) | str | Yes | SavedModelディレクトリパス | fingerprint.pbが存在すること |
| saved_model_checksum | int (uint64) | No | SavedModel全体のチェックサム | Fingerprint作成時 |
| graph_def_program_hash | int (uint64) | No | GraphDefプログラムのハッシュ | Fingerprint作成時 |
| signature_def_hash | int (uint64) | No | SignatureDefのハッシュ | Fingerprint作成時 |
| saved_object_graph_hash | int (uint64) | No | SavedObjectGraphのハッシュ | Fingerprint作成時 |
| checkpoint_hash | int (uint64) | No | チェックポイントのハッシュ | Fingerprint作成時 |

### 入力データソース

ファイルシステム上のSavedModelディレクトリ内のfingerprint.pbファイル。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Fingerprint | Fingerprintオブジェクト | 5つのハッシュ値とバージョン情報を含むフィンガープリント |
| singleprint | str | 4つの正規化ハッシュを'/'で連結した文字列 |

### 出力先

Python上のFingerprintオブジェクト。保存時はfingerprint.pbファイル。

## 処理フロー

### 処理シーケンス

```
1. フィンガープリント読み取り（read_fingerprint）
   └─ 1-1. export_dirからfingerprint.pbを読み込み
   └─ 1-2. FingerprintDef protobufをパース
   └─ 1-3. Fingerprintオブジェクトを構築して返却
2. フィンガープリント生成（SavedModel保存時）
   └─ 2-1. SavedModelの各構成要素のハッシュを計算
   └─ 2-2. FingerprintDefプロトコルバッファを構築
   └─ 2-3. fingerprint.pbとして書き出し
3. Singleprint生成
   └─ graph_def_program_hash / signature_def_hash / saved_object_graph_hash / checkpoint_hash を'/'で連結
```

### フローチャート

```mermaid
flowchart TD
    A[SavedModel保存] --> B[各構成要素のハッシュ計算]
    B --> C[FingerprintDef構築]
    C --> D[fingerprint.pb書き出し]

    E[read_fingerprint呼び出し] --> F[fingerprint.pb読み込み]
    F --> G[FingerprintDef パース]
    G --> H[Fingerprintオブジェクト構築]

    H --> I{singleprint生成?}
    I -->|Yes| J[4ハッシュを/で連結]
    I -->|No| K[Fingerprint返却]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-66-01 | 等価比較 | Fingerprint同士の比較はsaved_model_checksumを除く4フィールドで行う（__eq__） | 2つのFingerprintを比較する場合 |
| BR-66-02 | Singleprint正規化 | Singleprintはsaved_model_checksumを除外した4つのハッシュで構成される | singleprint()呼び出し時 |
| BR-66-03 | FingerprintDef互換 | FingerprintはFingerprintDefプロトコルバッファとも比較可能 | __eq__でFingerprintDefが渡された場合 |
| BR-66-04 | バイト入力対応 | from_protoはbytes入力も受け付けてデシリアライズする | bytesが渡された場合 |

### 計算ロジック

Singleprint = `{graph_def_program_hash}/{signature_def_hash}/{saved_object_graph_hash}/{checkpoint_hash}`

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

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

データベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| FileNotFoundError | ファイル不存在 | fingerprint.pbが存在しない | SavedModelを再保存するか、フィンガープリント機能対応バージョンで保存 |
| RuntimeError | フィンガープリントエラー | fingerprint.pbのパースに失敗 | SavedModelの整合性を確認 |
| ValueError | デシリアライズエラー | from_protoに不正なprotoが渡された | 正しいFingerprintDefを指定 |
| ValueError | Singleprint構築エラー | フィンガープリントフィールドが無効 | 有効なフィンガープリント値を設定 |

### リトライ仕様

リトライ不要。

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

該当なし。読み取り専用操作（生成時はSavedModel保存のトランザクションに含まれる）。

## パフォーマンス要件

フィンガープリントの読み取り・比較は軽量な操作。ハッシュ計算はSavedModel保存時に1回実行される。

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

フィンガープリントはSavedModelの改ざん検出に利用可能だが、暗号学的なセキュリティを保証するものではない。

## 備考

- `tf.saved_model.experimental.Fingerprint`として実験的APIとして公開
- `tf.saved_model.experimental.read_fingerprint`でフィンガープリント読み取り
- C++側の実装は`pywrap_saved_model.fingerprinting`モジュールに存在

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | fingerprinting.py | `tensorflow/python/saved_model/fingerprinting.py` | `Fingerprint`クラスの属性定義（29-69行目） |

**読解のコツ**: Fingerprintクラスは6つの属性（saved_model_checksum、graph_def_program_hash、signature_def_hash、saved_object_graph_hash、checkpoint_hash、version）を持つ。__eq__ではsaved_model_checksumも比較対象だが、Singleprintでは除外される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | fingerprinting.py | `tensorflow/python/saved_model/fingerprinting.py` | `read_fingerprint`関数（151-178行目）：フィンガープリント読み取りのパブリックAPI |

**主要処理フロー**:
1. **172行目**: `fingerprinting_pywrap.ReadSavedModelFingerprint`でC++側の読み取り実行
2. **177-178行目**: `Fingerprint.from_proto`でPythonオブジェクトに変換

#### Step 3: Fingerprintクラスの主要メソッド

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fingerprinting.py | `tensorflow/python/saved_model/fingerprinting.py` | `from_proto`クラスメソッド（71-87行目） |
| 3-2 | fingerprinting.py | `tensorflow/python/saved_model/fingerprinting.py` | `__eq__`メソッド（89-101行目） |
| 3-3 | fingerprinting.py | `tensorflow/python/saved_model/fingerprinting.py` | `singleprint`メソッド（120-148行目） |

**主要処理フロー**:
- **74-75行目**: bytes入力をFingerprintDef.FromStringでデシリアライズ
- **93-98行目**: 5つのフィールドでの等価比較（saved_model_checksumも含む）
- **137-140行目**: 4つのハッシュでSingleprintを構築

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

```
tf.saved_model.experimental.read_fingerprint(export_dir)
    │
    ├─ fingerprinting_pywrap.ReadSavedModelFingerprint(export_dir)  [C++]
    │
    └─ Fingerprint.from_proto(fingerprint_pb2.FingerprintDef)
           │
           └─ Fingerprint(checksum, graph_hash, sig_hash, obj_hash, ckpt_hash, version)

Fingerprint.singleprint()
    │
    └─ fingerprinting_pywrap.Singleprint(graph_hash, sig_hash, obj_hash, ckpt_hash)  [C++]
```

### データフロー図

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

export_dir ─────────────────▶ ReadSavedModelFingerprint ──▶ bytes (proto)
                                │
bytes (proto) ───────────────▶ FingerprintDef.FromString ──▶ FingerprintDef
                                │
FingerprintDef ──────────────▶ Fingerprint.from_proto ──▶ Fingerprint object
                                │
Fingerprint ─────────────────▶ singleprint() ──▶ "hash1/hash2/hash3/hash4"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| fingerprinting.py | `tensorflow/python/saved_model/fingerprinting.py` | ソース | FingerprintクラスとAPIの定義 |
| fingerprinting_utils.py | `tensorflow/python/saved_model/fingerprinting_utils.py` | ソース | フィンガープリント生成ユーティリティ |
| fingerprint.proto | `tensorflow/core/protobuf/fingerprint.proto` | Proto定義 | FingerprintDefプロトコルバッファの定義 |
| pywrap_saved_model/fingerprinting | C++バインディング | ソース | C++側のフィンガープリント読み書き実装 |
