Spaces:
Running
Running
File size: 14,532 Bytes
5c4f7a1 7b3a08d 5c4f7a1 96a476a 5c4f7a1 59fa244 5c4f7a1 59fa244 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | ---
title: PID2Graph VLM Eval
emoji: 🔧
colorFrom: blue
colorTo: purple
sdk: gradio
sdk_version: 4.31.5
python_version: "3.10"
app_file: app.py
pinned: false
license: mit
short_description: Zero-shot P&ID graph extraction with Claude Opus 4.6
---
# PID2Graph × VLM Eval
P&ID(配管計装図)画像から VLM(Claude Opus 4.6)でグラフ構造(シンボル+接続関係)を抽出し、[PID2Graph](https://zenodo.org/records/14803338) データセットの正解と定量比較する実験。
> **⚠️ このデモを動かすには `ANTHROPIC_API_KEY` の設定が必要です。**
> HuggingFace Spaces では **Settings → Variables and secrets → New secret** から
> `ANTHROPIC_API_KEY` を登録してください(値は [Anthropic Console](https://console.anthropic.com/) で発行した API キー)。
> ローカル実行時は `pid2graph` 直下の `.env` に `ANTHROPIC_API_KEY=sk-ant-...` と書くか、
> シェルで `export ANTHROPIC_API_KEY=...` を設定してから `python app.py` を実行します。
>
> 1 サンプルあたりの Claude API コスト目安: single-shot 約 $0.08 / tiled 2×2 約 $0.34。
製造業の技術図面に対する VLM のゼロショット構造抽出性能を評価し、CV との**ハイブリッド戦略**の必要性を実データで検証した。
## 背景と目的
P&ID のデジタル化(画像 → 構造化データ)は、設備管理 DB への自動登録やシミュレーションモデルの自動生成に不可欠な技術である。従来は CNN ベースのシンボル検出+線検出+ルールベース接続推定というモジュラーパイプラインが主流だったが、顧客ごとに異なる図面規格への対応コストが課題だった。
本実験では、VLM のゼロショット能力を活用して **訓練データなし** でどこまで構造抽出が可能かを定量的に検証する。
## データセット
[PID2Graph](https://zenodo.org/records/14803338)(Stürmer et al., 2025)の **OPEN100** サブセットを使用。
- 12 枚の実 P&ID 画像(原子力プロジェクト OPEN100)
- 正解は `.graphml` 形式(ノード: シンボル種別 + bounding box、エッジ: 接続種別)
- 画像サイズ: 約 600×500 〜 2604×1744 ピクセル
## 手法
### Semantic Equipment フィルタリング
正解データには connector(配管接続点)225 個、crossing(交差)71 個など、線レベルのプリミティブが大量に含まれる。VLM のゼロショットでこれらを網羅的に検出するのは非現実的なため、**意味のある機器シンボルのみ** を抽出・評価対象とした。
| 対象(semantic) | 除外(primitive) |
|---|---|
| valve, instrumentation, tank, pump, inlet/outlet | connector, crossing, arrow, background, general |
GT 側も同じフィルタを適用し、primitive を経由するエッジは直接エッジに縮約(collapse)してフェアな比較を行った。
### 構造化出力
Claude API の `messages.parse()` に Pydantic スキーマ(`GraphOut`)を渡し、JSON スキーマ違反を SDK 側で検出。`temperature=0` で決定論的サンプリングを強制。
```json
{
"nodes": [
{"id": "n1", "type": "valve", "label": "TCV 1401", "bbox": [578, 930, 586, 944]}
],
"edges": [
{"source": "n1", "target": "n2", "label": "solid"}
]
}
```
### タイル分割(2×2)
大きな図面を 4 タイルに分割(10-20% オーバーラップ)し、各タイルごとに VLM で抽出した後、bbox 距離ベースで重複排除+マージ。
**Seam Filter:** タイル境界付近で配管の切れ端を inlet/outlet と誤検出する問題に対し、タイル内側境界 ±50px 以内かつ図面外縁でない inlet/outlet を FP として除去する後処理を追加。
## 実験結果
### 12 枚全件ベースライン
| 指標 | Precision | Recall | F1 | TP | FP | FN |
|------|-----------|--------|----|----|----|-----|
| **Nodes(single-shot)** | 0.941 | 0.699 | 0.802 | 527 | 33 | 227 |
| **Nodes(tiled + seam filter)** | 0.828 | 0.948 | 0.884 | 715 | 149 | 39 |
| Edges(single-shot) | 0.086 | 0.018 | 0.030 | 38 | 402 | 2033 |
### Single-shot vs Tiled(サイズ別比較)
| 図面 | GT nodes | Single F1 | Tiled F1 | ΔF1 | Tiled Precision | Tiled Recall |
|------|----------|-----------|----------|------|-----------------|--------------|
| **Small (#1, GT=27)** | 27 | 0.739 | 0.783 | +0.044 | 0.643 | 1.000 |
| **Medium (#3, GT=53)** | 53 | 0.796 | 0.955 | +0.159 | 0.914 | 1.000 |
| **Large (#0, GT=82)** | 82 | 0.706 | **0.964** | **+0.258** | 0.952 | 0.976 |
### カテゴリ別 Recall(12 枚集計、single-shot)
| type | GT | pred | Recall |
|---|---|---|---|
| instrumentation | 350 | 267 | 0.76 |
| valve | 257 | 128 | **0.50** ← 最大の失点 |
| inlet/outlet | 96 | 100 | 1.04 |
| tank | 35 | 43 | 1.23 |
| pump | 16 | 22 | 1.38 |
## 考察
### 1. VLM は「意味理解に強く、空間的な網羅性に弱い」
- **Precision 0.94:** VLM が検出したシンボルの種別判定はほぼ正確。「見えているものを正しく分類する」能力は非常に高い
- **Recall 0.70(single-shot):** 正解の 30% を見落とす。特に valve(Recall 0.50)は小さなシンボルが画像リサイズで潰れるため
これは理解力の問題ではなく **解像度の限界** である。
### 2. タイル分割で解像度問題を解決
図面が大きいほどタイル分割の効果が顕著:
- Small(GT=27): ΔF1 = +0.044(効果薄、FP 増加コスト)
- Medium(GT=53): ΔF1 = +0.159(Precision 維持しつつ Recall 1.000)
- **Large(GT=82): ΔF1 = +0.258**(Precision も 0.889→0.952 に向上)
Large では 1-shot 時に曖昧な小要素を「とりあえず出す」誤検出が、タイル分割で高解像度になることで消える。**実用的には図面サイズに応じた適応的モード切替が最適。**
### 3. エッジ抽出は VLM 単体では実用にならない
Edge F1 ≈ 0.03 は全条件で共通。VLM は配管の線形状を追跡しておらず、テキストタグの類似性から接続を推測している。これは **CV 的な線追跡ロジックとの組み合わせ** でしか解決できない。
### 4. BPMN 構造抽出論文(Deka & Devereux, 2026)との比較
同種のタスク(図面画像→構造化 JSON)で VLM を評価した SAC 2026 採択論文との対比:
| 観点 | BPMN 論文 | 本実験(P&ID) |
|---|---|---|
| ノード数/図面 | 数十個 | 数百個(1 桁多い) |
| Relation 抽出 | GPT-4.1 で F1 0.475 | Edge F1 ≈ 0.03 |
| OCR 補完効果 | 中位モデルで有効、上位モデルには逆効果 | 未検証(今後の課題) |
| 最有効プロンプト | DFS+BFS Hybrid | 今後検証予定 |
P&ID は BPMN より要素数が 1 桁多く、シンボル種類も工業規格(ISO 10628)に依存するため、難度が大幅に高い。
## 今後の課題:エッジ(接続関係)抽出の改善
今回の実験ではノード検出で F1 0.964 を達成したが、エッジ抽出は F1 ≈ 0.03 で実用にならなかった。接続関係の抽出は P&ID デジタル化の核心であり、最優先の研究課題である。
### アプローチ 1: モジュラーパイプライン(CV 主導)
従来の P&ID デジタル化で主流のアプローチ。
- **線検出:** 画像の二値化 → スケルトン化 → Hough 変換で配管ラインを検出(Moon et al., 2021)
- **接続推定:** 検出済みシンボルの bbox と線分端点の近接性からグラフ探索で接続を復元
- **課題:** モジュール間のエラー伝播。線の交差・分岐での追跡失敗が接続推定精度を大きく下げる
参考実装: [Azure P&ID Digitization](https://github.com/Azure-Samples/digitization-of-piping-and-instrument-diagrams)(Microsoft ISE, 2024)
### アプローチ 2: End-to-End Transformer(Relationformer)
PID2Graph 論文(Stürmer et al., 2025)が提案。シンボルと接続関係を同時に抽出する。
- Node AP 83.63%, Edge mAP 75.46%(モジュラー方式に対してエッジ検出で 25%以上の改善)
- 接続関係を直接推論するため、線検出のエラー伝播がない
- **課題:** 専用モデルの訓練が必要。新しい図面規格への汎化にはドメイン特化のファインチューニングが不可欠
### アプローチ 3: ハイブリッド(CV + VLM)← 提案する方向性
今回の実験結果と先行研究を踏まえた、最も有望なアプローチ。
```
[P&ID 画像]
│
├─ Stage 1: ノード検出(CV or VLM タイル分割)
│ → 今回の手法で Precision 0.95, Recall 0.95 を達成済み
│
├─ Stage 2: 線検出・追跡(CV)
│ → スケルトン化 + Hough 変換で配管ラインを抽出
│ → 検出済みノードの bbox を除去した画像に対して実行
│
├─ Stage 3: 接続関係の推論(VLM)
│ → 確定済みノード一覧 + 線検出結果 + 元画像を VLM に渡す
│ → "これらのノード間の接続関係を列挙せよ" と推論
│ → VLM を「審判(Judge)」として活用(Ghosh et al., 2025)
│
└─ Stage 4: 後処理・検証
→ グラフ整合性チェック(孤立ノード除去、双方向性確認)
→ ドメイン知識による制約(バルブは必ず 2 本の配管に接続、等)
```
**根拠となる先行研究:**
- **VLM as a Judge**(Ghosh et al., 2025): VLM を直接検出に使わず、CV の結果を VLM が評価・補完するフレームワーク。Gemini 2.5 で F1 0.876
- **Arrow-Guided VLM**(Spies et al., 2025): CV 検出器で矢印方向を特定してから VLM に座標付きプロンプトで渡す。QA 精度 +9pp
- **TextFlow**(Shukla et al., 2024): VLM の出力を構造化テキスト(Graphviz/Mermaid)に変換し、LLM で推論する 2 段階分離
- **Florence-2 ファインチューニング**(Khan et al., 2024): 0.23B パラメータの軽量 VLM で、GPT-4o の zero-shot 比 F1 +52.4%。ドメイン特化ファインチューニングの有効性を実証
### その他の改善課題
| 課題 | 期待効果 | 優先度 |
|------|---------|--------|
| IoU ベース dedup(タイルマージ時) | tank/pump の過検出を解消、Precision 向上 | 高 |
| 適応的タイル切替(GT サイズ推定→閾値判定) | 小図面での FP 削減 | 中 |
| DFS+BFS Hybrid プロンプト | BPMN 論文で最有効。P&ID での検証が必要 | 中 |
| Sonnet 4.6 との比較 | コスト 1/3 で精度差を測定 | 低 |
## デモ
Gradio ベースのインタラクティブデモ。P&ID 画像をアップロード → VLM でグラフ構造を抽出 → 正解 graphml と比較 → スコア表示 + NetworkX でグラフ可視化。
### 起動方法
```bash
git clone https://github.com/deepkick/pid2graph-vlm-eval.git
cd pid2graph-vlm-eval
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# .env に API キーを設定
echo "ANTHROPIC_API_KEY=sk-ant-..." > .env
# Gradio デモ起動
python app.py
# → http://127.0.0.1:7860
```
### CLI での評価実行
```bash
# 12 枚全件(single-shot)
python -m pid2graph_eval.cli \
--image-dir "PID2Graph/Complete/PID2Graph OPEN100" \
--gt-dir "PID2Graph/Complete/PID2Graph OPEN100" \
--semantic-only --output results.json
# タイル分割モード
python -m pid2graph_eval.cli \
--image-dir "PID2Graph/Complete/PID2Graph OPEN100" \
--gt-dir "PID2Graph/Complete/PID2Graph OPEN100" \
--semantic-only --tiled --output results_tiled.json
```
## プロジェクト構成
```
pid2graph-vlm-eval/
├── app.py # Gradio デモ UI
├── requirements.txt
├── .env # API キー(.gitignore 対象)
├── pid2graph_eval/
│ ├── schema.py # Pydantic モデル(GraphOut)
│ ├── gt_loader.py # graphml → 正規化ノード/エッジ
│ ├── extractor.py # Claude API 呼び出し(single / tiled)
│ ├── metrics.py # P/R/F1 算出(ノード / エッジ)
│ ├── tile.py # タイル分割・マージ・seam filter
│ └── cli.py # CLI エントリポイント
├── samples/ # OPEN100 から 3 枚(small/medium/large)
│ ├── open100_01_small.png
│ ├── open100_01_small.graphml
│ ├── open100_03_medium.png
│ ├── open100_03_medium.graphml
│ ├── open100_00_large.png
│ └── open100_00_large.graphml
└── results/ # 評価結果 JSON
```
## 使用技術
- **VLM:** Claude Opus 4.6(Anthropic API、構造化出力)
- **評価データ:** PID2Graph OPEN100(CC BY-SA 4.0)
- **ライブラリ:** NetworkX, Pydantic, Pillow, tqdm, Gradio, matplotlib
- **開発環境:** Claude Code + VS Code(Dev Container)
## 参考文献
| 論文 | 手法 | URL |
|------|------|-----|
| Stürmer et al., 2025 — PID2Graph | Relationformer(End-to-End) | [arXiv:2411.13929](https://arxiv.org/abs/2411.13929) |
| Ghosh et al., 2025 — VLM as a Judge | CV 検出 + VLM 品質評価 | [arXiv:2510.03376](https://arxiv.org/abs/2510.03376) |
| Shteriyanov et al., 2025 | OCR + VLM + マルチモーダルプロンプト | [Wiley](https://onlinelibrary.wiley.com/doi/abs/10.1002/smr.70072) |
| Deka & Devereux, 2026 — BPMN-VLM | VLM + OCR 補完 | [arXiv:2511.22448](https://arxiv.org/abs/2511.22448) |
| Spies et al., 2025 — Arrow-Guided VLM | 物体検出 + VLM 推論 | [arXiv:2505.07864](https://arxiv.org/abs/2505.07864) |
| Khan et al., 2024 | Florence-2 ファインチューニング | [arXiv:2411.03707](https://arxiv.org/abs/2411.03707) |
| Shukla et al., 2024 — TextFlow | VLM → 構造化テキスト → LLM 推論 | [arXiv:2412.16420](https://arxiv.org/abs/2412.16420) |
| Moon et al., 2021 | スケルトン化 + Hough 変換 | [MDPI](https://www.mdpi.com/2076-3417/11/21/10054) |
| Goldstein et al., 2025 | P&ID → Neo4j 知識グラフ → RAG | [arXiv:2502.18928](https://arxiv.org/abs/2502.18928) |
## License
MIT
|