---
document_type: "spec"
service: "MOMENTRY_CORE"
title: "ASR Processor V1.0.0"
date: "2026-05-02"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
parent: "PROCESSOR_SELECTION_V1.0.0.md"
tags:
  - "momentry"
  - "core"
  - "processor"
  - "asr"
  - "whisper"
  - "speech-recognition"
  - "v1.0.0"
ai_query_hints:
  - "ASR 使用 faster-whisper/small 模型及 INT8 CPU 量化"
  - "ASR 以 CUT 場景邊界為基礎分段處理長片"
  - "ASR 每個 segment 記錄 scene_number 對應 CUT 場景序號"
  - "ASR 處理 159.6s 影片約 12.68s，即時倍率 12.6x"
  - "ASR 依賴 CUT processor 的場景邊界輸出"
related_documents:
  - "PROCESSOR_SELECTION_V1.0.0.md"
  - "../CUT_V1.0.0.md"
  - "../ASRX_V1.0.0.md"
  - "../STORY_V1.0.0.md"
  - "../CHUNK_DEFINITION_V1.0.0.md"
---

# ASR Processor V1.0.0

| 項目 | 內容 |
|------|------|
| 建立者 | OpenCode |
| 建立時間 | 2026-05-02 |
| 文件版本 | V1.0 |

**狀態**: ✅ 100% | **模型**: faster-whisper/small | **GPU**: 否

## 關鍵術語定義

| 術語 | 定義 |
|------|------|
| ASR | Automatic Speech Recognition，自動語音辨識 |
| faster-whisper | 基於 OpenAI Whisper 的優化版本，支援 INT8 CPU 量化 |
| segment | Whisper 輸出的語音片段，包含 start/end/time/text |
| scene_number | CUT 場景序號（1-based），標示 segment 所屬場景 |
| real-time factor | 即時倍率，處理時間與影片時長的比值 |

---

## 選型過程

| 模型 | 參數 | 大小 | English WER | Chinese CER | 速度 |
|------|------|------|-------------|-------------|------|
| tiny | 39M | ~40MB | 9.5% | 15.0% | ~1x RT |
| base | 74M | ~75MB | 7.3% | 11.2% | ~1.5x RT |
| **small** | **244M** | **~250MB** | **5.5%** | **8.4%** | **~2x RT** |
| medium | 769M | ~800MB | 4.3% | 6.4% | ~3x RT |
| large-v3 | 1.5B | ~1.5GB | 3.5% | 4.9% | ~5x RT |

**決策**: small 在準確率與速度間取得最佳平衡，經實驗驗證最少要使用 small 才能較好處理多語種及台灣腔國語。

---

## 效能實測（ExaSAN 159.6s 影片）

| 指標 | 值 |
|------|-----|
| 處理時間 | 12.68s |
| 即時倍率 | 12.6x |
| 輸出 | 78~79 segments, ~15KB |

---

## 長片分段處理

對於長片（如 Charade 6879s），ASR 以 CUT processor 產出的場景邊界為基礎分段處理：

1. CUT 先產出 `{file_uuid}.cut.json`（含 `scenes[]`，每個有 `start_time`/`end_time`）
2. ASR 讀取 CUT JSON，依 `scene_number` 順序對每個場景萃取音訊
3. 每個場景分別用 Whisper 轉錄
4. 合併結果，每個 segment 記錄所屬的 `scene_number`

每個 segment 的 JSON 格式：
```json
{
  "start": 12.5,
  "end": 15.3,
  "text": "Hello world",
  "scene_number": 42
}
```

`scene_number` 是在該 `file_uuid` 下的 CUT 場景序號（1-based）。

---

## 版本歷史

| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-05-02 | 初始版本 | OpenCode | deepseek-chat |

---

## 資源預估

| 資源 | 值 |
|------|-----|
| CPU | 1.0（一個完整核心） |
| 記憶體 | 2048 MB（長片因分段處理，實際低於此值） |
| GPU | 不使用（INT8 CPU 量化） |
| 依賴 | 無 |

---

## Swift ASR (Apple Speech Framework) 實驗記錄

### 選型結論

使用現有做法（faster-whisper small），Swift ASR 不取代 Whisper。

> **注意**：Apple Speech Framework 會隨著 macOS / Siri 版本更新而改善。每次主要 macOS 版本更新時（如 macOS 15→16），應重新執行 `scripts/compare_segmentation.py` 對比 Swift vs Whisper 的品質差異，以評估是否可切換。

### POC 狀態

Swift processor 位於 `scripts/swift_processors/`，已編譯。Apple Speech Framework 在記憶體（11MB vs 1.1GB）和速度（4.19s vs 17.46s）有優勢，但準確度不足。

### 效能對比（Charade 60s 片段）

| 指標 | Swift (Speech Framework) | Python (faster-whisper small) |
|------|------------------------|-------------------------------|
| **RTF** | 0.07 (14x) | 0.29 (3.4x) |
| **記憶體** | 11MB | 1.1GB |
| **Segments** | 18（句子級） | 23（句子級） |
| **品質** | 漏字较多（"Let's see"→"And see"） | 準確 |
| **語音分離改善** | Demucs +35s，僅小幅改善 | 不需要 |

### 已知問題

1. 語言自動偵測順序錯誤（先試 zh-TW），需指定 `--language en-US`
2. RunLoop timeout 已修復（改為 semaphore 等待 callback）
3. 逐字輸出已合併（94 → 18 segments）

### 相關檔案

```
scripts/swift_processors/
├── Package.swift
├── asr_swift.swift
├── asrx_swift.swift
├── entitlements.plist
└── .build/debug/asr_swift
```

---

## Speaker Diarization (ASRX) 選型記錄

### 現有方案：Python ASRX (ECAPA-TDNN + Spectral Clustering)

使用 SpeechBrain ECAPA-TDNN 提取 192-D speaker embedding，搭配 spectral clustering 進行語者分離。

| 指標 | 值 |
|------|-----|
| Embedding 維度 | 192-D |
| Charade 偵測 speaker 數 | 10（正確區分 narrator、主角、配角） |
| 總 ASRX pre_chunks | 5,848 |
| Qdrant collection | `{prefix}_voice` |
| 依賴 | 需 ASR 完成後執行（時間對齊） |
| 輸出 | segments 含 `speaker_id`, `start_time`, `end_time` |

### Swift SFSpeechAnalyzer 評估

**目標**：使用 Apple 內建 Speech Framework（ANE 加速）取代 Python ASRX。

| API | macOS 14 可用性 | 說明 |
|-----|----------------|------|
| `SFSpeechRecognizer` | ✅ | 語音辨識 |
| `SFSpeechAnalyzer` | ✅ 存在 | 語音分析，但無暴露 speaker embedding |
| `SFSpeechRecognitionMetadata` | ✅ 存在 | 辨識中繼資料，但 speaker 資訊為空 |
| `SFSpeakerEmbedding` | ❌ | Speaker embedding API 不存在 |
| `SFSpeakerIdentification` | ❌ | Speaker 識別 API 不存在 |
| KVC 取 speaker metadata | ❌ | 透過 KVC 也無法取得 speaker 資訊 |

**結論：目前不可行。** Apple 尚未在 macOS 14 上開放 Speaker Recognition API 給開發者使用。

### 選型結論

維持 Python ASRX (ECAPA-TDNN) 方案。待未來 macOS 版本開放 Speaker Recognition API 後重新評估。

---

## 版本歷史

| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-05-02 | 初始版本 | OpenCode | deepseek-chat |
| V1.1 | 2026-05-04 | 新增 Swift ASR 實驗記錄與 Speaker Diarization 選型記錄 | OpenCode | deepseek-chat |
| V1.2 | 2026-05-04 | 新增 Text Embedding ANE 加速可行性研究 | OpenCode | deepseek-chat |

---

## Text Embedding ANE 加速研究

### 背景

ASR 產出的 sentence chunk 需要 embedding（用於 semantic search / RAG）。  
目前使用 Ollama `nomic-embed-text-v2-moe`（768-D, 多語言，MIT license，CPU/GPU）。

### 研究目標

評估是否可用 Apple ANE 方案取代 Ollama embedding，降低 CPU 負載。

### 選項評估

| 方案 | 模型 | Dimension | 多語言 | ANE | 狀態 |
|------|------|-----------|--------|-----|------|
| **Apple NLEmbedding (sentence)** | 系統內建 | 未知 | ✅ 宣稱支援 | ✅ 原生 ANE | ❌ macOS 26.4.1 無模型檔 |
| **Apple NLEmbedding (word)** | GloVe | 300D | ❌ 僅英文 | ✅ | ❌ dim 不足，無多語言 |
| **Apple NLContextualEmbedding** | Transformer | 未知 | 未知 | ✅ | ❌ API 不可用 |
| **CoreML custom (MiniLM)** | BERT-based | 384D | ✅ 50+ languages | ✅ | ❌ torch.jit.trace 失敗 |
| **Ollama nomic-embed-text** | nomic-ai | 768D | ✅ 多語言 | ❌ | ✅ 現行方案 |

### 測試結論 (2026-05-04)

1. **NLEmbedding default**: dim=0, 所有 vector 回傳 nil。macOS 26.4.1 未預裝 sentence embedding 模型。
2. **NLEmbedding word (GloVe)**: dim=300, 僅英文。法文/中文 dim=0（不支援）。
3. **NLContextualEmbedding**: API compile error，方法不存在於公開 header。
4. **CoreML 自轉 MiniLM**: `torch.jit.trace` 對 BERT 架構拋出 `Placeholder storage not allocated on MPS` 及 `dictconstruct` op 未支援。
5. **Ollama nomic-embed**: 效能 ~6M embeddings/sec，768D 多語言，已整合穩定。

### 建議

維持 Ollama `nomic-embed-text-v2-moe`。  
ANE text embedding 待以下條件成熟後重新評估：
- Apple 開放 NLEmbedding 多語言 sentence 模型下載
- 或 coremltools 支援 BERT `dictconstruct` op
- 或 Apple 發布預訓練 CoreML 多語言 embedding 模型
