Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ee0c008
Fix Cloud Run deployment: bypass DDP init, use /tmp for writes
claude Feb 7, 2026
25aabad
Fix model loading: use renamed .pth weight file and wav2vec2 config.json
claude Feb 7, 2026
9286246
Add gourmet-sp frontend with lip sync fixes
claude Feb 8, 2026
14f48e5
Add concierge.zip avatar (copy of p2-1.zip sample for testing)
claude Feb 8, 2026
c8af922
Fix avatar path: use concierge.zip instead of p2-1.zip
claude Feb 8, 2026
5772bae
Fix lip sync artifacts and reduce TTS-to-speech latency
claude Feb 8, 2026
448d8c4
Fix TTS playback blocked by expression API timeout
claude Feb 8, 2026
db3e205
Fix: make expression generation fully non-blocking (fire-and-forget)
claude Feb 8, 2026
8276013
Integrate audio2exp into backend TTS endpoint, remove frontend direct…
claude Feb 8, 2026
0194d02
Proxy architecture: TTS returns audio only, expression via fire-and-f…
claude Feb 8, 2026
678b30a
Fix lip sync: clear buffer per segment + pre-fetch expression for rem…
claude Feb 8, 2026
7ea0364
Expression in TTS response: zero-delay lip sync from frame 0
claude Feb 8, 2026
7fe6a06
Async expression: background thread + polling (TTS returns instantly)
claude Feb 8, 2026
96b0a4b
Sync expression + ack/LLM parallel: zero-delay lip sync with ~700ms f…
claude Feb 8, 2026
4ea78d1
Fix: skip unlockAudioParams when ack is playing (prevents ttsPlayer i…
claude Feb 8, 2026
fb7d439
Fix 2nd interaction TTS: resolve pendingAckPromise on pause + stopCur…
claude Feb 8, 2026
d9a11ed
Enlarge avatar display area for 512x512 avatar optimization
claude Feb 8, 2026
eb36e5b
Adjust camera to fill avatar head in canvas (reduce empty space above)
claude Feb 8, 2026
85bd7b9
Fix camera: lower lookAt target to show full face (head to chin)
claude Feb 8, 2026
8752cb8
Camera tweak: lower avatar 10% in frame + natural slight top-down angle
claude Feb 8, 2026
5272100
Add files via upload
mirai-gpro Feb 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 199 additions & 0 deletions ANALYSIS_REQUEST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# LAM_Audio2Expression 解析・実装依頼

## 依頼の背景

Audio2ExpressionサービスをGoogle Cloud Runにデプロイしようと48時間以上、40回以上試行したが、モデルが「mock」モードのままで正しく初期化されない。対症療法的な修正を繰り返しても解決できないため、根本的なアプローチの見直しが必要。

## 前任AIの反省点

**重要**: 前任AI(Claude)は以下の問題を抱えていた:

1. **古い知識ベースからの推論に依存**
- 一般的な「Cloud Runデプロイ」パターンを適用しようとした
- LAM_Audio2Expression固有の設計思想を理解できていなかった

2. **表面的なコード理解**
- コードを読んだが、なぜそのように設計されているかを理解していなかった
- 元々どのような環境・ユースケースを想定したコードなのかを考慮しなかった

3. **対症療法の繰り返し**
- ログからエラーを見つけ→修正→デプロイ→また別のエラー、の無限ループ
- 根本原因を特定せず、見えている症状だけを修正し続けた

4. **思い込み**
- 「モデルの読み込みや初期化がうまくいっていない」と決めつけていた
- 問題はそこではなく、もっと根本的なアプローチの誤りである可能性がある

**この解析を行う際は、上記の落とし穴にハマらないよう注意してください。**

## 解析対象コード

### 主要ファイル

**1. audio2exp-service/app.py** (現在のサービス実装)
- FastAPI を使用したWebサービス
- `/health`, `/debug`, `/api/audio2expression`, `/ws/{session_id}` エンドポイント
- `Audio2ExpressionEngine` クラスでモデル管理

**2. LAM_Audio2Expression/engines/infer.py**
- `InferBase` クラス: モデル構築の基底クラス
- `Audio2ExpressionInfer` クラス: 音声→表情推論
- `infer_streaming_audio()`: リアルタイムストリーミング推論

**3. LAM_Audio2Expression/models/network.py**
- `Audio2Expression` クラス: PyTorchニューラルネットワーク
- wav2vec2 エンコーダー + Identity Encoder + Decoder構成

**4. LAM_Audio2Expression/engines/defaults.py**
- `default_config_parser()`: 設定ファイル読み込み
- `default_setup()`: バッチサイズ等の設定計算
- `create_ddp_model()`: 分散データ並列ラッパー

## 具体的な解析依頼

### Q1: モデル初期化が完了しない根本原因

```python
# app.py での初期化
self.infer = INFER.build(dict(type=cfg.infer.type, cfg=cfg))
self.infer.model.eval()
```

この処理がCloud Run環境で正常に完了しない理由を特定してください。

考えられる原因:
- [ ] メモリ不足 (8GiBで足りない?)
- [ ] CPU環境での動作制限
- [ ] 分散処理設定が単一インスタンスで問題を起こす
- [ ] ファイルシステムの書き込み権限
- [ ] タイムアウト (コールドスタート時間)
- [ ] その他

### Q2: default_setup() の問題

```python
# defaults.py
def default_setup(cfg):
world_size = comm.get_world_size() # Cloud Runでは1
cfg.num_worker = cfg.num_worker if cfg.num_worker is not None else mp.cpu_count()
cfg.num_worker_per_gpu = cfg.num_worker // world_size
assert cfg.batch_size % world_size == 0 # 失敗する可能性?
```

推論時にこの設定が問題を起こしていないか確認してください。

### Q3: ロガー設定の問題

```python
# infer.py
self.logger = get_root_logger(
log_file=os.path.join(cfg.save_path, "infer.log"),
file_mode="a" if cfg.resume else "w",
)
```

Cloud Runのファイルシステムでログファイル作成が失敗する可能性を確認してください。

### Q4: wav2vec2 モデル読み込み

```python
# network.py
if os.path.exists(pretrained_encoder_path):
self.audio_encoder = Wav2Vec2Model.from_pretrained(pretrained_encoder_path)
else:
config = Wav2Vec2Config.from_pretrained(wav2vec2_config_path)
self.audio_encoder = Wav2Vec2Model(config) # ランダム重み!
```

- wav2vec2-base-960h フォルダの構成は正しいか?
- HuggingFaceからのダウンロードが必要なファイルはないか?

### Q5: 適切なデプロイ方法

Cloud Runが不適切な場合、以下の代替案を検討:
- Google Compute Engine (GPU インスタンス)
- Cloud Run Jobs (バッチ処理)
- Vertex AI Endpoints
- Kubernetes Engine

## 期待する成果

### 1. 分析結果
- 根本原因の特定
- なぜ40回以上の試行で解決できなかったかの説明

### 2. 修正されたコード
```
audio2exp-service/
├── app.py # 修正版
├── Dockerfile # 必要なら修正
└── cloudbuild.yaml # 必要なら修正
```

### 3. 動作確認方法
```bash
# ヘルスチェック
curl https://<service-url>/health
# 期待する応答: {"model_initialized": true, "mode": "inference", ...}

# 推論テスト
curl -X POST https://<service-url>/api/audio2expression \
-H "Content-Type: application/json" \
-d '{"audio_base64": "...", "session_id": "test"}'
```

## 技術スペック

### モデル仕様
| 項目 | 値 |
|------|-----|
| 入力サンプルレート | 24kHz (API) / 16kHz (内部) |
| 出力フレームレート | 30 fps |
| 出力次元 | 52 (ARKit blendshape) |
| モデルファイルサイズ | ~500MB (LAM) + ~400MB (wav2vec2) |

### デプロイ環境
| 項目 | 値 |
|------|-----|
| プラットフォーム | Cloud Run Gen 2 |
| リージョン | asia-northeast1 |
| メモリ | 8GiB |
| CPU | 4 |
| max-instances | 4 |

### 依存関係 (requirements.txt)
```
torch==2.0.1
torchaudio==2.0.2
transformers==4.30.2
librosa==0.10.0
fastapi==0.100.0
uvicorn==0.23.0
numpy==1.24.3
scipy==1.11.1
pydantic==2.0.3
```

## ファイルの場所

```bash
# プロジェクトルート
cd /home/user/LAM_gpro

# メインサービス
cat audio2exp-service/app.py

# 推論エンジン
cat audio2exp-service/LAM_Audio2Expression/engines/infer.py

# ニューラルネットワーク
cat audio2exp-service/LAM_Audio2Expression/models/network.py

# 設定
cat audio2exp-service/LAM_Audio2Expression/engines/defaults.py
cat audio2exp-service/LAM_Audio2Expression/configs/lam_audio2exp_config_streaming.py
```

---

以上、よろしくお願いいたします。
199 changes: 199 additions & 0 deletions LAM_Audio2Expression_HANDOFF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# LAM_Audio2Expression 引継ぎ・解析依頼文

## 1. プロジェクト概要

### 目的
Audio2Expressionサービスを Google Cloud Run にデプロイし、音声からARKit 52 blendshape係数をリアルタイムで生成するAPIを提供する。

### リポジトリ構成
```
/home/user/LAM_gpro/
├── audio2exp-service/
│ ├── app.py # FastAPI サービス本体
│ ├── Dockerfile # Dockerイメージ定義
│ ├── cloudbuild.yaml # Cloud Build設定
│ ├── requirements.txt # Python依存関係
│ ├── start.sh # 起動スクリプト
│ ├── models/ # モデルファイル格納
│ │ ├── LAM_audio2exp_streaming.tar # LAMモデル重み
│ │ └── wav2vec2-base-960h/ # wav2vec2事前学習モデル
│ └── LAM_Audio2Expression/ # LAMモデルソースコード
│ ├── configs/
│ │ └── lam_audio2exp_config_streaming.py
│ ├── engines/
│ │ ├── defaults.py # 設定パーサー・セットアップ
│ │ └── infer.py # 推論エンジン (Audio2ExpressionInfer)
│ ├── models/
│ │ ├── __init__.py
│ │ ├── builder.py # モデルビルダー
│ │ ├── default.py # DefaultEstimator
│ │ ├── network.py # Audio2Expression ニューラルネットワーク
│ │ └── utils.py # 後処理ユーティリティ
│ └── utils/
│ ├── comm.py # 分散処理ユーティリティ
│ ├── config.py # 設定管理
│ ├── env.py # 環境設定
│ └── logger.py # ロギング
```

## 2. コア技術アーキテクチャ

### Audio2Expression モデル (network.py)

```python
# 入力 → 出力フロー
input_audio_array (24kHz or 16kHz)
→ wav2vec2 audio_encoder (768次元特徴)
→ feature_projection (512次元)
→ identity_encoder (話者特徴 + GRU)
→ decoder (Conv1D + LayerNorm + ReLU)
→ output_proj (52次元)
→ sigmoid
→ ARKit 52 blendshape coefficients (0-1)
```

### 重要なパラメータ
- **内部サンプルレート**: 16kHz
- **出力フレームレート**: 30 fps
- **出力次元**: 52 (ARKit blendshape)
- **identity classes**: 12 (話者ID用)

### wav2vec2の読み込みロジック (network.py:40-44)
```python
if os.path.exists(pretrained_encoder_path):
self.audio_encoder = Wav2Vec2Model.from_pretrained(pretrained_encoder_path)
else:
# 警告: この場合、ランダム重みで初期化される
config = Wav2Vec2Config.from_pretrained(wav2vec2_config_path)
self.audio_encoder = Wav2Vec2Model(config)
```

### ストリーミング推論 (infer.py)

`infer_streaming_audio()` メソッド:
1. コンテキスト管理 (`previous_audio`, `previous_expression`, `previous_volume`)
2. 64フレーム最大長でバッファリング
3. 16kHzへリサンプリング
4. 後処理パイプライン:
- `smooth_mouth_movements()` - 無音時の口動き抑制
- `apply_frame_blending()` - フレーム間ブレンディング
- `apply_savitzky_golay_smoothing()` - 平滑化フィルタ
- `symmetrize_blendshapes()` - 左右対称化
- `apply_random_eye_blinks_context()` - 瞬き追加

## 3. 現在の問題

### 症状
- Cloud Runへのデプロイは成功する
- ヘルスチェック応答:
```json
{
"model_initialized": false,
"mode": "mock",
"init_step": "...",
"init_error": "..."
}
```
- 48時間以上、40回以上のデプロイ試行で解決できていない

### 試行した解決策(全て失敗)
1. gsutil でモデルダウンロード
2. Python GCSクライアントでモデルダウンロード
3. Cloud Storage FUSE でマウント
4. Dockerイメージにモデルを焼き込み
5. max-instances を 10 → 5 → 4 に削減(quota対策)
6. ステップ別エラー追跡を追加

### 重要な指摘
ユーザーからの指摘:
> 「キミは、モデルの読み込みや、初期化が上手く行ってないと、思い込んでるでしょ?そうじゃなく、根本的にやり方が間違ってるんだよ!」
> 「LAM_Audio2Expressionのロジックを本質的に理解できてないでしょ?」

つまり、問題は単なる「ファイルが見つからない」「初期化エラー」ではなく、**アプローチ自体が根本的に間違っている**可能性がある。

## 4. 解析依頼事項

### 4.1 根本原因の特定
1. **LAM_Audio2Expressionの設計思想**
- このモデルは元々どのような環境で動作することを想定しているか?
- GPU必須か?CPU動作可能か?
- リアルタイムストリーミング vs バッチ処理の制約は?

2. **Cloud Run適合性**
- コールドスタート時間の問題はないか?
- メモリ8GiBで十分か?
- CPUのみで実用的な速度が出るか?

3. **初期化プロセス**
- `default_setup(cfg)` のバッチサイズ計算が問題を起こしていないか?
- `create_ddp_model()` がシングルプロセス環境で正しく動作するか?
- ロガー設定がCloud Run環境で問題を起こしていないか?

### 4.2 app.py の問題点
現在の `app.py` の初期化フローを確認:
```python
# lifespan内で非同期初期化
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, engine.initialize)
```

- この初期化方法は正しいか?
- エラーが正しくキャッチ・伝播されているか?

### 4.3 設定ファイルの問題
`lam_audio2exp_config_streaming.py`:
```python
num_worker = 16 # Cloud Runで問題になる?
batch_size = 16 # 推論時も必要?
```

## 5. 期待する成果物

1. **根本原因の分析レポート**
- なぜ現在のアプローチが機能しないのか
- Cloud Runでこのモデルを動作させることは可能か

2. **正しい実装方針**
- 必要な場合、代替デプロイメント方法の提案
- app.py の正しい実装

3. **動作する実装コード**
- モデル初期化が成功する
- `/health` エンドポイントで `model_initialized: true` を返す
- `/api/audio2expression` でリアルタイム推論が機能する

## 6. 関連ファイル一覧

### 必読ファイル
| ファイル | 説明 |
|---------|------|
| `audio2exp-service/app.py` | FastAPIサービス本体 |
| `LAM_Audio2Expression/engines/infer.py` | 推論エンジン |
| `LAM_Audio2Expression/models/network.py` | ニューラルネットワーク定義 |
| `LAM_Audio2Expression/engines/defaults.py` | 設定パーサー |
| `LAM_Audio2Expression/configs/lam_audio2exp_config_streaming.py` | ストリーミング設定 |

### 補助ファイル
| ファイル | 説明 |
|---------|------|
| `LAM_Audio2Expression/models/utils.py` | 後処理ユーティリティ |
| `LAM_Audio2Expression/utils/comm.py` | 分散処理ユーティリティ |
| `LAM_Audio2Expression/models/builder.py` | モデルビルダー |

## 7. デプロイ環境

- **Cloud Run Gen 2**
- **メモリ**: 8GiB
- **CPU**: 4
- **max-instances**: 4
- **コンテナポート**: 8080
- **リージョン**: asia-northeast1

## 8. Git情報

- **ブランチ**: `claude/implementation-testing-w2xCb`
- **最新コミット**: `4ba662c Simplify deployment: bake models into Docker image`

---

作成日: 2026-02-07
Loading