cleanup: remove dead code and duplicate docs

- Remove session-ses_2f27.md (161KB raw session log)
- Remove 49 ROOT_* duplicate files across REFERENCE/
- Remove 14 duplicate files between REFERENCE/ root and history/
- Remove asr_legacy.rs (dead code, replaced by asr.rs)
- Remove src/core/worker/ (duplicate JobWorker)
- Remove src/core/layers/ (empty directory)
- Remove 4 .bak files in src/
- Remove 7 dead private methods in worker/processor.rs
- Remove backup directory from git tracking
This commit is contained in:
Warren
2026-05-04 01:31:21 +08:00
parent ee81e343ce
commit e75c4d6f07
3270 changed files with 35190 additions and 53367 deletions

View File

@@ -1,290 +0,0 @@
---
document_type: "revision_record"
service: "MOMENTRY_CORE"
title: "AI Processor Module Revision Records"
date: "2026-03-27"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "ai-processor"
- "revision"
- "standardization"
- "changelog"
ai_query_hints:
- "AI Processor 模組有哪些修訂紀錄?"
- "各 Processor 的標準化進度為何?"
- "ASR/OCR/YOLO/Face/Pose 模組改動了什麼?"
---
# AI Processor Module Revision Records
## Overview
This document tracks all revisions made to AI processor modules during the standardization effort based on the **AI-Driven Processor Contract**. Each processor has been updated to follow consistent patterns for configuration, error handling, monitoring, and AI Agent optimization.
## Revision Summary
| Processor | Version | Status | Lines (Old→New) | Compliance Score | Key Changes |
|-----------|---------|--------|----------------|------------------|-------------|
| **ASR** | v2.0 | ✅ Complete | 953 → 341 | 95% | Unified config, timeout handling, model caching |
| **OCR** | v1.0 | ✅ Complete | N/A → 621 | 92% | EasyOCR integration, config unification, frame processing |
| **YOLO** | v1.0 | ✅ Complete | 483 → 666 | 94% | YOLOv8 resume support, auto-save, COCO classes |
| **Face** | v1.0 | ✅ Complete | 154 → 621 | 90% | Haar/DNN methods, configurable parameters |
| **Pose** | v1.0 | ✅ Complete | 178 → 666 | 93% | YOLOv8 Pose, keypoint tracking, confidence thresholds |
| **ASRX** | v1.0 | ⏳ Pending | - | - | Needs standardization |
| **Caption** | v1.0 | ⏳ Pending | - | - | Needs standardization |
| **CUT** | v1.0 | ⏳ Pending | - | - | Needs standardization |
| **Story** | v1.0 | ⏳ Pending | - | - | Needs standardization |
## ASR Processor Revision (v2.0)
### Original State (`scripts/asr_processor.py`)
- **Lines**: 953
- **Issues**: Complex, fragmented configuration, no unified timeout handling
- **Configuration**: Mixed environment variables (`MOMENTRY_ASR_DIRECT_TIMEOUT`, `MOMENTRY_ASR_CHUNK_TIMEOUT`)
- **Monitoring**: Limited health checks, no performance metrics
### Revised State (`scripts/asr_processor_contract_v2.py`)
- **Lines**: 341 (64% reduction)
- **Improvements**:
1. **Unified Configuration**: Uses `MOMENTRY_ASR_TIMEOUT` (3600s) from Rust config
2. **Contract Compliance**: Follows AI-Driven Processor Contract specifications
3. **Model Caching**: Whisper model caching for performance
4. **Signal Handling**: Graceful degradation with timeout handling
5. **Health Checks**: Comprehensive health monitoring
6. **AI Agent Optimization**: Structured output for parsing
### Configuration Changes
```bash
# BEFORE (fragmented)
MOMENTRY_ASR_DIRECT_TIMEOUT=600
MOMENTRY_ASR_CHUNK_TIMEOUT=300
# AFTER (unified)
MOMENTRY_ASR_TIMEOUT=3600
MOMENTRY_ASR_PROCESS_TIMEOUT=1800
MOMENTRY_ASR_CHUNK_TIMEOUT=300
```
### Rust Integration
- **File**: `src/core/processor/asr.rs`
- **Changes**: Updated to use contract-compliant version
- **Configuration**: Added to `src/core/config.rs` ASR module
## OCR Processor Revision (v1.0)
### Original State (`scripts/ocr_processor.py`)
- **Lines**: Unknown (not standardized)
- **Issues**: No contract compliance, inconsistent configuration
### Revised State (`scripts/ocr_processor_contract_v1.py`)
- **Lines**: 621
- **Improvements**:
1. **Contract Compliance**: Full AI-Driven Processor Contract implementation
2. **EasyOCR Integration**: Model caching and language support
3. **Frame Processing**: Configurable frame extraction
4. **Configuration**: Unified environment variables
5. **Health Checks**: Comprehensive monitoring
### Configuration
```bash
MOMENTRY_OCR_TIMEOUT=1800
MOMENTRY_OCR_LANGUAGES=en
MOMENTRY_OCR_CONFIDENCE=0.7
MOMENTRY_OCR_GPU=false
```
### Rust Integration
- **File**: `src/core/config.rs` - Added OCR configuration module
- **File**: `src/core/processor/ocr.rs` - Needs update to use contract version
## YOLO Processor Revision (v1.0)
### Original State (`scripts/yolo_processor.py`)
- **Lines**: 483
- **Issues**: Limited resume support, no auto-save, inconsistent configuration
### Revised State (`scripts/yolo_processor_contract_v1.py`)
- **Lines**: 666
- **Improvements**:
1. **Resume Support**: Checkpoint-based resume functionality
2. **Auto-Save**: Configurable auto-save intervals (time and frames)
3. **COCO Classes**: Full COCO dataset class names
4. **Class Filtering**: Configurable class detection
5. **Contract Compliance**: Full AI-Driven Processor Contract implementation
### Configuration
```bash
MOMENTRY_YOLO_TIMEOUT=7200
MOMENTRY_YOLO_MODEL_SIZE=yolov8n.pt
MOMENTRY_YOLO_CONFIDENCE=0.25
MOMENTRY_YOLO_AUTO_SAVE_INTERVAL=30
MOMENTRY_YOLO_AUTO_SAVE_FRAMES=300
```
### Rust Integration
- **File**: `src/core/config.rs` - Added YOLO configuration module
- **File**: `src/core/processor/yolo.rs` - Updated to use contract version
## Face Processor Revision (v1.0)
### Original State (`scripts/face_processor.py`)
- **Lines**: 154
- **Issues**: Limited functionality, no configuration options
### Revised State (`scripts/face_processor_contract_v1.py`)
- **Lines**: 621
- **Improvements**:
1. **Multiple Methods**: Haar Cascade and DNN detection
2. **Configurable Parameters**: Size, confidence, scale factor
3. **GPU Support**: Optional GPU acceleration
4. **Contract Compliance**: Full AI-Driven Processor Contract implementation
5. **Frame Processing**: Efficient face detection pipeline
### Configuration
```bash
MOMENTRY_FACE_TIMEOUT=3600
MOMENTRY_FACE_METHOD=haar
MOMENTRY_FACE_CONFIDENCE=0.5
MOMENTRY_FACE_MIN_SIZE=30
MOMENTRY_FACE_MAX_SIZE=300
```
### Rust Integration
- **File**: `src/core/config.rs` - Added Face configuration module
- **File**: `src/core/processor/face.rs` - Updated to use contract version
## Pose Processor Revision (v1.0)
### Original State (`scripts/pose_processor.py`)
- **Lines**: 178
- **Issues**: Basic functionality, no keypoint tracking
### Revised State (`scripts/pose_processor_contract_v1.py`)
- **Lines**: 666
- **Improvements**:
1. **YOLOv8 Pose**: Advanced pose estimation
2. **Keypoint Tracking**: COCO keypoint names and confidence
3. **Multi-Person**: Configurable maximum persons detection
4. **Contract Compliance**: Full AI-Driven Processor Contract implementation
5. **Performance Metrics**: Detailed timing and accuracy metrics
### Configuration
```bash
MOMENTRY_POSE_TIMEOUT=7200
MOMENTRY_POSE_MODEL_SIZE=yolov8n-pose.pt
MOMENTRY_POSE_CONFIDENCE=0.25
MOMENTRY_POSE_KEYPOINT_CONFIDENCE=0.5
MOMENTRY_POSE_MAX_PERSONS=10
```
### Rust Integration
- **File**: `src/core/config.rs` - Added Pose configuration module
- **File**: `src/core/processor/pose.rs` - Updated to use contract version
## Compliance Verification Checklist
### AI-Driven Processor Contract Requirements
| Requirement | ASR v2.0 | OCR v1.0 | YOLO v1.0 | Face v1.0 | Pose v1.0 |
|-------------|----------|----------|-----------|-----------|-----------|
| **1. Unified Configuration** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **2. Timeout Handling** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **3. Signal Handling** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **4. Health Checks** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **5. Performance Metrics** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **6. Model Caching** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **7. Graceful Degradation** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **8. Structured Output** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **9. AI Agent Optimization** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **10. Documentation** | ✅ | ✅ | ✅ | ✅ | ✅ |
### Configuration Compliance
| Configuration Aspect | Status | Notes |
|---------------------|--------|-------|
| **Environment Variables** | ✅ Complete | All processors use unified env vars |
| **Rust Integration** | ✅ Complete | All configs added to `src/core/config.rs` |
| **Monitoring** | ✅ Complete | Health checks implemented |
| **Timeout Values** | ✅ Complete | Aligned with monitoring system |
| **Error Handling** | ✅ Complete | Consistent across all processors |
## Testing Results
### Configuration Tests
- **Total Tests**: 37
- **Passed**: 37 (100%)
- **Failed**: 0
### Processor Health Checks
- **ASR Health Check**: ✅ PASS
- **OCR Health Check**: ✅ PASS
- **YOLO Health Check**: ✅ PASS
- **Face Health Check**: ✅ PASS
- **Pose Health Check**: ✅ PASS
### Rust Compilation
- **Configuration Compilation**: ✅ PASS
- **Module Integration**: ✅ PASS (5/5 updated)
## Remaining Tasks
### High Priority
1. **Verify ASR processor compliance** - Detailed contract verification
2. **Verify OCR processor compliance** - Detailed contract verification
3. **Verify YOLO processor compliance** - Detailed contract verification
4. **Verify Face processor compliance** - Detailed contract verification
5. **Verify Pose processor compliance** - Detailed contract verification
### Medium Priority
1. **Update remaining processor modules**:
- ASRX (ASR with diarization)
- Caption (Caption generation)
- CUT (Video cutting)
- Story (Story generation)
2. **Create compliance report** - Summary of all verifications
3. **Update monitoring dashboards** - Reflect new configuration
### Low Priority
1. **Performance benchmarking** - Compare old vs new processors
2. **Documentation updates** - User guides for new processors
3. **Training materials** - For new standardized approach
## Impact Assessment
### Positive Impacts
1. **Reduced Complexity**: ASR processor reduced from 953 to 341 lines (64% reduction)
2. **Improved Maintainability**: Consistent patterns across all processors
3. **Better Monitoring**: Comprehensive health checks and metrics
4. **AI Agent Optimization**: Structured output for automated processing
5. **Configuration Unification**: Single source of truth for all settings
### Risk Mitigation
1. **Backward Compatibility**: Legacy processors preserved
2. **Gradual Rollout**: Contract-compliant versions can run alongside legacy
3. **Testing Coverage**: Comprehensive test suite ensures reliability
4. **Documentation**: Detailed revision records for audit trail
## Version History
| Date | Version | Changes | Author |
|------|---------|---------|--------|
| 2025-03-27 | 1.0 | Initial revision records created | OpenCode |
| 2025-03-27 | 1.1 | Added compliance checklist | OpenCode |
| 2025-03-27 | 1.2 | Added testing results and impact assessment | OpenCode |
## Next Steps
1. **Complete compliance verification** for all standardized processors
2. **Create detailed compliance report** with findings and recommendations
3. **Update remaining processor modules** to follow the same standardization pattern
4. **Integrate with monitoring system** to track performance of new processors
5. **Create user documentation** for the new standardized approach
## References
1. [AI-Driven Processor Contract](../REFERENCE/AI_DRIVEN_PROCESSOR_CONTRACT.md)
2. [Processor Standardization Template](../REFERENCE/PROCESSOR_STANDARDIZATION_TEMPLATE.md)
3. [ASR Configuration Unification](../REFERENCE/ASR_CONFIGURATION_UNIFICATION.md)
4. [AGENTS.md](../../AGENTS.md) - Updated configuration documentation

View File

@@ -1,108 +0,0 @@
# 處理器本地化修復總結
**日期**: 2026-04-09
**問題**: CAPTION 和 STORY 使用雲端 API違反本地處理原則
**狀態**: ✅ 已修復
---
## CAPTION 修復
### 移除的代碼
```python
# ❌ 雲端 API
def generate_caption_with_gpt4v(image_path, api_key):
from openai import OpenAI
client = OpenAI(api_key=api_key)
response = client.chat.completions.create(model="gpt-4o", ...)
```
### 新增的代碼
```python
# ✅ 本地 VLM (Moondream2)
def generate_caption_with_moondream(image_path, prompt):
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("vikhyatk/moondream2")
# ... 本地推理
```
### 備案方案
```python
# ✅ 元數據聚合 (無需 AI 模型)
def generate_caption_from_metadata(image_path, data):
# 整合 YOLO + OCR + Scene 結果
return "Objects: person, car | Text: STOP | Scene: street"
```
---
## STORY 修復
### 移除的代碼
```python
# ❌ OpenAI API
def generate_story_with_gpt4(asr_data, yolo_data):
from openai import OpenAI
response = client.chat.completions.create(model="gpt-4", ...)
```
### 新增的代碼
```python
# ✅ 模板化敘述生成
def generate_narrative(texts, objects, start, end):
# 基於本地數據組合敘述
return f"[{start}-{end}] Speech: {texts} | Visuals: {objects}"
```
---
## 安裝本地模型
### Moondream2 (CAPTION)
```bash
pip install transformers torch pillow
# Python 測試
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("vikhyatk/moondream2")
# 模型大小: ~1.8GB
# 自動下載到: ~/.cache/huggingface/
```
### 現有模型 (已安裝)
| 模型 | 用途 | 大小 | 位置 |
|------|------|------|------|
| Whisper | ASR | ~3GB | ~/.cache/huggingface/ |
| SpeechBrain | ASRX | ~200MB | ~/.cache/huggingface/ |
| YOLOv8 | YOLO/POSE | ~10MB | ~/.cache/ultralytics/ |
| EasyOCR | OCR | ~500MB | ~/.EasyOCR/ |
| Places365 | Scene | 43MB | ~/momentry/models/ |
---
## 測試命令
```bash
# 測試 CAPTION (本地)
python3 scripts/caption_processor.py video.mp4 output.caption.json --uuid test123
# 測試 STORY (本地)
python3 scripts/story_processor.py video.mp4 output.story.json --uuid test123
# 驗證無雲端依賴
grep -r "openai\|gpt-\|api_key" scripts/caption_processor.py scripts/story_processor.py
# 應該返回空
```
---
## 性能影響
| 模塊 | 原方案 | 新方案 | 速度 | 質量 |
|------|--------|--------|------|------|
| Caption | GPT-4o (2s/幀) | Moondream2 (5s/幀) | 稍慢 | 良好 |
| Story | GPT-4 (3s/塊) | 模板 (<0.1s/塊) | 極快 | 結構化 |
---
**結論**: 所有處理器現在完全本地運行,無需雲端 API。

File diff suppressed because it is too large Load Diff

View File

@@ -1,457 +0,0 @@
---
document_type: "test_doc"
service: "MOMENTRY_CORE"
title: "處理器效能評估報告"
date: "2026-04-01"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "處理器效能評估報告"
ai_query_hints:
- "查詢 處理器效能評估報告 的內容"
- "處理器效能評估報告 的主要目的是什麼?"
- "如何操作或實施 處理器效能評估報告?"
---
# 處理器效能評估報告
| 項目 | 內容 |
|------|------|
| 測試日期 | 2026-04-01 |
| 測試者 | OpenCode |
| 測試環境 | M4 Mac Mini 16GB |
| Python版本 | 3.9 |
| PyTorch加速 | MPS (Metal Performance Shaders) |
---
## 測試影片
### 短影片ExaSAN PCIe series
- **檔案**: `ExaSAN PCIe series - Director Ou Yu-Zhi Shares His Experience.mp4`
- **時長**: 159.6 秒 (2分40秒)
- **大小**: 6.5 MB
- **FPS**: 22.0
- **總幀數**: 3,512
- **解析度**: 未知
- **場景**: 辦公室/會議室環境
### 長影片Old_Time_Movie_Show_-_Charade_1963
- **檔案**: `Old_Time_Movie_Show_-_Charade_1963.HD.mov`
- **時長**: 6,879.3 秒 (114分39秒)
- **大小**: 2.2 GB
- **FPS**: 59.94
- **總幀數**: 412,343
- **解析度**: 1920x1080 (HD)
- **場景**: 電影(多場景)
---
## 處理器效能測試結果(短影片)
| 處理器 | 狀態 | 處理時間 | 加速比 | 備註 |
|--------|------|----------|--------|------|
| **ASR** | ✓ | 12.68s | 12.6x | 語音識別 |
| **OCR** | ✓ | 36.87s | 4.3x | 文字識別(全幀處理) |
| **YOLO** | ✓ | 65.72s | 2.4x | 物體檢測(全幀處理) |
| **Face** | ✓ | 1.22s | 130.5x | 人臉識別 |
| **Pose** | ✓ | 65.87s | 2.4x | 姿態檢測(全幀處理) |
| **CUT** | ✓ | 0.08s | 2036.5x | 鏡頭切換檢測 |
| **ASRX** | ✓ | 4.79s | 33.3x | 高級語音識別 |
| **Scene** | ✓ | 4.09s | 39.0x | 場景分類2秒取樣 |
---
## 長影片處理時間預估
基於短影片效能數據預估長影片114分鐘處理時間
| 處理器 | 短影片 (159.6s) | 長影片預估 (6879.3s) | 線性外推倍率 |
|--------|----------------|---------------------|-------------|
| **ASR** | 12.68s | ~547s (9.1分鐘) | 43x |
| **OCR** | 36.87s | ~1,588s (26.5分鐘) | 43x |
| **YOLO** | 65.72s | ~2,831s (47.2分鐘) | 43x |
| **Face** | 1.22s | ~53s (0.9分鐘) | 43x |
| **Pose** | 65.87s | ~2,838s (47.3分鐘) | 43x |
| **CUT** | 0.08s | ~3s | 43x |
| **ASRX** | 4.79s | ~206s (3.4分鐘) | 43x |
| **Scene** | 4.09s | ~176s (2.9分鐘) | 43x |
### 總處理時間預估
- **順序處理**: ~47 分鐘
- **並行處理**: ~47 分鐘(受限於 YOLO/Pose 最長處理時間)
- **實際測試**: 313.3s5.2分鐘Scene Classification
---
## 效能分析
### 快速處理器(加速比 > 10x
| 處理器 | 加速比 | 特點 |
|--------|--------|------|
| **CUT** | 2036.5x | 極快,基於幀差異檢測 |
| **Face** | 130.5x | 快速,使用優化算法 |
| **Scene** | 39.0x | 快速,採樣策略有效 |
| **ASRX** | 33.3x | 快速高級ASR模型 |
| **ASR** | 12.6x | 中等,依賴音頻長度 |
### 慢速處理器(加速比 < 10x
| 處理器 | 加速比 | 特點 |
|--------|--------|------|
| **OCR** | 4.3x | 較慢,全幀處理 |
| **YOLO** | 2.4x | 慢,深度學習推理 |
| **Pose** | 2.4x | 慢,深度學習推理 |
---
## 瓶頸分析
### 1. YOLO 和 Pose最慢
**原因**:
- 全幀處理(無採樣)
- 深度學習模型推理
- 無GPU加速使用MPS
**優化建議**:
- 添加採樣參數(如 `--sample-interval`
- 使用Core ML模型M4優化
- 實現批次處理
### 2. OCR次慢
**原因**:
- 全幀處理
- 文字檢測+識別兩階段
**優化建議**:
- 添加採樣參數
- 使用場景變化檢測CUT觸發OCR
- 區域ROI優化
---
## 處理策略建議
### 短影片 (< 5分鐘)
```bash
# 全處理器運行(總時間 ~3分鐘
順序運行所有處理器
```
### 中等影片 (5-30分鐘)
```bash
# 快速處理器 + 必要處理器
1. CUT鏡頭切換
2. ASR語音識別
3. Scene場景分類
4. Face人臉識別
# 可選處理器(採樣)
5. OCR每5秒採樣
6. YOLO每5秒採樣
```
### 長影片 (> 30分鐘)
```bash
# 分階段處理
Phase 1: 快速分析
- CUT鏡頭切換
- Scene場景分類5秒採樣
- ASR語音識別
Phase 2: 關鍵片段處理
- 根據CUT結果只處理場景變化點
- OCR/YOLO/Pose只在關鍵片段運行
預估時間:
- Phase 1: ~15分鐘
- Phase 2: 視關鍵片段數量而定
```
---
## 處理器詳細數據
### ASR語音識別
```json
{
"duration": 12.68,
"speedup": 12.6,
"model": "whisper",
"notes": "處理音頻長度159.6秒"
}
```
### OCR文字識別
```json
{
"duration": 36.87,
"speedup": 4.3,
"frame_count": 3512,
"fps": 22.0,
"notes": "全幀處理"
}
```
### YOLO物體檢測
```json
{
"duration": 65.72,
"speedup": 2.4,
"output_size": "4.3 MB",
"notes": "全幀處理,包含檢測結果"
}
```
### Face人臉識別
```json
{
"duration": 1.22,
"speedup": 130.5,
"frame_count": 3512,
"fps": 22.0,
"output_size": "12 KB",
"notes": "快速處理"
}
```
### Pose姿態檢測
```json
{
"duration": 65.87,
"speedup": 2.4,
"frame_count": 3512,
"fps": 22.0,
"output_size": "603 KB",
"notes": "全幀處理,深度學習推理"
}
```
### CUT鏡頭切換
```json
{
"duration": 0.08,
"speedup": 2036.5,
"output_size": "52 B",
"notes": "極快,基於幀差異"
}
```
### ASRX高級語音識別
```json
{
"duration": 4.79,
"speedup": 33.3,
"output_size": "40 B",
"notes": "快速,高級模型"
}
```
### Scene場景分類
```json
{
"duration": 4.09,
"speedup": 39.0,
"frame_count": 3512,
"fps": 22.0,
"sample_interval": "2.0s",
"samples": 79,
"notes": "採樣策略有效"
}
```
---
## 測試命令
### 短影片測試
```bash
# 運行所有處理器測試
python3 scripts/test_processor_performance.py
# 單個處理器測試
python3 scripts/asr_processor.py video.mp4 output.json
python3 scripts/ocr_processor.py video.mp4 output.json
python3 scripts/yolo_processor.py video.mp4 output.json
python3 scripts/face_processor.py video.mp4 output.json
python3 scripts/pose_processor.py video.mp4 output.json
python3 scripts/cut_processor.py video.mp4 output.json
python3 scripts/asrx_processor.py video.mp4 output.json
python3 scripts/scene_classifier.py video.mp4 output.json --sample-interval 2
```
### 長影片測試(優化參數)
```bash
# 場景分類5秒採樣
python3 scripts/scene_classifier.py long_video.mov output.json \
--sample-interval 5.0 \
--min-scene-duration 10.0
# ASR全音頻
python3 scripts/asr_processor.py long_video.mov output.json
```
---
## 硬體資源使用
### 記憶體使用
| 處理器 | 峰值記憶體 | 備註 |
|--------|-----------|------|
| ASR | ~2-3 GB | Whisper模型 |
| OCR | ~1-2 GB | 文字檢測+識別 |
| YOLO | ~2-3 GB | 深度學習模型 |
| Face | ~1-2 GB | 人臉檢測+識別 |
| Pose | ~2-3 GB | 深度學習模型 |
| CUT | ~500 MB | 幀差異計算 |
| ASRX | ~2-3 GB | 高級ASR模型 |
| Scene | ~2-3 GB | Places365模型 |
### GPU使用
- **MPS加速**: 啟用Metal Performance Shaders
- **GPU利用率**: 50-80%(深度學習處理器)
- **CPU利用率**: 20-40%I/O密集操作
---
## 效能優化建議
### 1. 添加採樣參數
為 YOLO、OCR、Pose 添加 `--sample-interval` 參數:
```python
parser.add_argument('--sample-interval', type=float, default=1.0,
help='取樣間隔(秒)')
```
**預期效果**:
- 5秒採樣處理時間減少 80%
- 10秒採樣處理時間減少 90%
### 2. 使用Core ML模型
將PyTorch模型轉換為Core ML
```bash
# 轉換YOLO模型
python3 scripts/convert_yolo_to_coreml.py
# 轉換Pose模型
python3 scripts/convert_pose_to_coreml.py
```
**預期效果**:
- M4 Mac加速 2-3x
- 功耗降低 50%
### 3. 批次處理
實現GPU批次推理
```python
# 批次處理(批次大小=8
batch_size = 8
frames_batch = []
for frame in frames:
frames_batch.append(frame)
if len(frames_batch) == batch_size:
results = model.predict_batch(frames_batch)
frames_batch = []
```
**預期效果**:
- YOLO加速 2x
- Pose加速 2x
### 4. 並行處理
使用多線程並行處理:
```python
import concurrent.futures
with ThreadPoolExecutor(max_workers=4) as executor:
futures = []
for processor in ['asr', 'ocr', 'yolo', 'face']:
futures.append(executor.submit(run_processor, processor))
for future in concurrent.futures.as_completed(futures):
print(future.result())
```
**預期效果**:
- 總時間減少 30-50%
---
## 結論
### ✅ 效能表現良好
- **快速處理器**: CUT、Face、Scene、ASRX
- **中速處理器**: ASR
- **慢速處理器**: OCR、YOLO、Pose
### ⚠️ 優化空間
- YOLO/Pose 需要採樣策略
- OCR 可以與CUT整合
- 長影片需要分階段處理
### 📋 下一步
1. 為YOLO/Pose/OCR添加採樣參數
2. 轉換為Core ML模型M4優化
3. 實現批次處理
4. 測試長影片處理策略
---
## 附錄:測試環境
```bash
# 系統信息
sw_vers
# ProductName: macOS
# ProductVersion: 15.3.2
# BuildVersion: 24D81
# 硬件信息
sysctl -n machdep.cpu.brand_string
# Apple M4
# Python版本
python3 --version
# Python 3.9.x
# PyTorch版本
python3 -c "import torch; print(torch.__version__)"
# 2.8.0
# MPS支持
python3 -c "import torch; print(torch.backends.mps.is_available())"
# True
```

View File

@@ -1,255 +0,0 @@
# Momentry Core Processors 快速参考
**更新日期**: 2026-04-28
---
## 完成度总览
| # | 模块 | 功能 | 完成度 | Python | Rust | API | 数据库 | 备注 |
|---|------|------|--------|--------|------|-----|--------|------|
| 1 | **ASR** | 语音识别 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | WhisperX |
| 2 | **ASRX** | 说话人分离 | ⚠️ 80% | ✅ | ✅ | ✅ | ✅ | **修复中** |
| 3 | **CUT** | 场景检测 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | PySceneDetect |
| 4 | **YOLO** | 物体检测 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | YOLOv8 |
| 5 | **OCR** | 文字识别 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | PaddleOCR |
| 6 | **Face** | 人脸检测 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | InsightFace ⭐ |
| 7 | **Pose** | 姿态估计 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | MediaPipe |
| 8 | **Scene** | 场景分类 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | **MIT Places365** ⭐ |
| 9 | **Caption** | 字幕生成 | ✅ 100% | ✅ | ✅ | ✅ | ⚠️ | GPT-4V (付费) |
| 10 | **Story** | 故事生成 | ✅ 100% | ✅ | ✅ | ✅ | ⚠️ | GPT-4 (付费) |
**统计**:
- ✅ 完成: 8/10 (80%)
- ⚠️ 修复中: 1/10 (10%)
- ⚠️ 待数据库: 2/10 (20%)
- 💰 付费 API: 2/10 (Caption, Story)
- ⭐ Benchmark完成: 4/10 (Face, YOLO, CUT, Scene)
---
## 快速参考
### ASR (语音识别)
```bash
# 使用
python3 scripts/asr_processor.py video.mp4 output.json
# API
curl http://localhost:3002/api/v1/asr/384b0ff44aaaa1f14cb2cd63b3fea966
# 示例
ExaSAN: 78 segments, 15KB
Charade: 1826 segments, 198KB
```
### ASRX (说话人分离) ⚠️
```bash
# 使用 (修复后)
python3 scripts/asrx_processor_custom.py video.mp4 output.json
# API
curl http://localhost:3002/api/v1/asrx/384b0ff44aaaa1f14cb2cd63b3fea966
# 测试结果
Charade: 1118 segments, 8 speakers, 99.82% match rate
```
**问题**: 原实现 (pyannote) 不可用
**修复**: 使用自定义 SpeechBrain 实现
**状态**: 已测试通过,待切换
### CUT (场景检测)
```bash
# 使用
python3 scripts/cut_processor.py video.mp4 output.json
# API
curl http://localhost:3002/api/v1/cut/384b0ff44aaaa1f14cb2cd63b3fea966
# 示例
Charade: 1331 scenes, 217KB
ExaSAN: 18 scenes, 2KB
```
### YOLO (物体检测)
```bash
# 使用
python3 scripts/yolo_processor.py video.mp4 output.json
# API
curl http://localhost:3002/api/v1/yolo/384b0ff44aaaa1f14cb2cd63b3fea966
# 示例
Charade: 127MB, 15234 objects, 80 classes
ExaSAN: 3.2MB, 456 objects
```
### OCR (文字识别)
```bash
# 使用
python3 scripts/ocr_processor.py video.mp4 output.json
# API
curl http://localhost:3002/api/v1/ocr/9760d0820f0cf9a7
# 示例
ExaSAN: 102 frames, 234 texts, 65KB
```
### Face (人脸检测)
```bash
# 使用
python3 scripts/face_processor.py video.mp4 output.json
# API
curl http://localhost:3002/api/v1/face/9760d0820f0cf9a7
# 示例
ExaSAN: 49 frames, 67 faces, 12KB
Charade: 1116 faces, 8 unique persons
```
### Pose (姿态估计)
```bash
# 使用
python3 scripts/pose_processor.py video.mp4 output.json
# API
curl http://localhost:3002/api/v1/pose/9760d0820f0cf9a7
# 示例
ExaSAN: 1853 frames, 2341 persons, 603KB
```
### Scene (场景分类) - MIT Places365
```bash
# 使用
python3 scripts/scene_classifier.py video.mp4 output.json
# API
curl http://localhost:3002/api/v1/scene/<uuid>
# 模型
ResNet18-Places365 (43MB)
365 scene categories
```
**类别示例**:
```
living_room, bedroom, kitchen, bathroom, restaurant,
gym, supermarket, basketball_court, park, beach, airport...
```
### Caption (字幕生成) 💰
```bash
# 使用
python3 scripts/caption_processor.py video.mp4 output.json
# API
curl http://localhost:3002/api/v1/caption/<uuid>
# 配置
export OPENAI_API_KEY="sk-..."
```
### Story (故事生成) 💰
```bash
# 使用
python3 scripts/story_processor.py video.mp4 output.json
# API
curl http://localhost:3002/api/v1/story/<uuid>
# 配置
export OPENAI_API_KEY="sk-..."
```
---
## 数据库表
### PostgreSQL
```sql
-- 通用 chunks 表
chunks (id, uuid, chunk_type, start_time, end_time, text, embedding)
-- Face 相关
face_detections (id, uuid, frame_number, face_id, bbox, confidence, embedding, cluster_id)
person_identities (id, uuid, person_name, actor_name, character_name, face_embedding)
person_appearances (id, uuid, person_identity_id, face_detection_id, asrx_segment_start, asrx_segment_end, confidence)
-- Jobs
jobs (id, uuid, processor_type, status, progress, error_message, created_at, started_at, completed_at)
```
### MongoDB
```javascript
// YOLO
db.yolo_frames.insertOne({uuid, frame_number, objects})
// OCR
db.ocr_frames.insertOne({uuid, frame_number, texts})
// Pose
db.pose_frames.insertOne({uuid, frame_number, persons})
// Story
db.story_chunks.insertOne({uuid, parent_chunks, child_chunks, stats})
```
---
## 批量处理
```bash
# 处理所有模块
cargo run -- process video.mp4 --modules all
# 处理指定模块
cargo run -- process video.mp4 --modules asr,cut,yolo
# 强制重新处理
cargo run -- process video.mp4 --modules asr --force
```
---
## 性能 (Apple Silicon M4)
| 模块 | 实时倍速 | FPS | 备注 |
|------|----------|-----|------|
| ASR | 10-20x | - | WhisperX |
| ASRX | 150x | - | SpeechBrain |
| CUT | 50-100x | - | PySceneDetect |
| YOLO | 20-40x | 100-200 | YOLOv8n |
| OCR | 30-50x | - | PaddleOCR |
| Face | 15-30x | - | RetinaFace |
| Pose | 25-40x | - | MediaPipe |
---
## 待办事项
### 高优先级
- [x] Scene: 添加数据库存储 ✅ (2026-04-28)
- [ ] ASRX: 切换到自定义 SpeechBrain 实现
- [ ] Caption: 添加数据库存储
- [ ] Story: 添加数据库存储
### 已完成 (2026-04-28)
- [x] **Scene Processor**: ProcessorType + store_scene_pre_chunks_batch + Benchmark测试
- [x] **CUT Processor**: PySceneDetect Benchmark测试 (2.54秒, 19场景)
- [x] **YOLO Processor**: CPU版本 Benchmark测试 (111.81秒, 8486物体, 26类)
- [x] **Face Processor**: InsightFace Benchmark测试 (7.04秒, 112人脸, 100%检测率) ⭐
### 中优先级
- [ ] 统一 API 错误处理
- [ ] 添加批量处理接口
- [ ] 优化 GPU/MPS 内存使用
---
**详细文档**: `docs/PROCESSOR_IMPLEMENTATION_STATUS.md`

View File

@@ -1,430 +0,0 @@
# YOLO Object Detection Processor 技术检讨报告
## 检讨日期
2026-04-28 02:00
---
## 一、版本概览
| 版本 | 脚本 | 技术栈 | 文件大小 | 状态 |
|------|------|--------|---------|------|
| **A** | yolo_processor.py | YOLOv8 (ultralytics) CPU | 14 KB | ✅ 默认使用 |
| **B** | yolo_processor_mps.py | YOLOv8 + Metal GPU (MPS) | 11 KB | ✅ MPS加速 |
| **C** | yolo_processor_contract_v1.py | YOLOv8 + Contract v1.0 | 23 KB | ✅ 标准化部署 |
---
## 二、Rust 配置
```rust
// src/worker/processor.rs Line 429-430
let script_path = std::env::var("MOMENTRY_YOLO_SCRIPT")
.unwrap_or_else(|_| format!("{}/yolo_processor.py", SCRIPTS_DIR.as_str()));
```
**默认使用**: yolo_processor.py ✅
---
## 三、技术栈分析
### 1. yolo_processor.py默认版本
#### 技术栈
| 项目 | 内容 |
|------|------|
| **引擎** | ultralytics YOLOv8 |
| **模型** | yolov8n.pt默认nano |
| **设备** | CPU |
| **Resume** | ✅ 已支持 |
| **类别数** | 80类COCO数据集 |
| **功能** | 物体检测 + 轨迹跟踪 |
#### 关键特性
| 特性 | 支持 |
|------|------|
| **Resume断点续传** | ✅ 已实现Line 124-140 |
| **Ctrl+C暂停保存** | ✅ 已实现Line 169-186 |
| **自动保存** | ✅ 定期保存默认30秒 |
| **Redis进度报告** | ✅ 支持 |
#### Resume 实现
```python
# yolo_processor.py Line 124-140
def load_existing_data(output_file: str) -> tuple[Optional[Dict], int]:
"""Load existing detection data. Returns (data, last_processed_frame)"""
if not os.path.exists(output_file):
return None, 0
frames = data.get("frames", {})
if frames:
last_frame = max(int(k) for k in frames.keys())
return data, last_frame # ✅ Resume起点
```
---
### 2. yolo_processor_mps.pyMPS版本
#### 技术栈
| 项目 | 内容 |
|------|------|
| **引擎** | ultralytics YOLOv8 |
| **模型** | yolov8n.pt默认nano |
| **设备** | MPSMetal GPU⭐⭐⭐ |
| **Resume** | ✅ 支持 |
| **类别数** | 80类COCO数据集 |
| **Batch处理** | ✅ 支持batch_size=8 |
#### MPS加速验证
```python
# yolo_processor_mps.py Line 110-117
def get_device() -> str:
"""Determine the best available device"""
if torch.backends.mps.is_available():
return "mps" # ✅ Apple Silicon Metal GPU
elif torch.cuda.is_available():
return "cuda"
else:
return "cpu"
```
#### MPS支持确认
```python
# Line 172-173
if device in ["mps", "cuda"]:
model.to(device) # ✅ 移动模型到GPU
```
---
### 3. yolo_processor_contract_v1.pyContract版本
#### 技术栈
| 项目 | 内容 |
|------|------|
| **引擎** | ultralytics YOLOv8 |
| **模型** | yolov8n.pt默认 |
| **设备** | CPU/GPU可选 |
| **Resume** | ✅ 支持 |
| **Contract** | ✅ Processor Contract v1.0 |
| **类别数** | 80类COCO数据集 |
#### Contract规范特性
```python
# yolo_processor_contract_v1.py Line 44-51
CONTRACT_VERSION = "1.0"
PROCESSOR_VERSION = "1.0.0"
MODEL_NAME = "yolov8n.pt"
MODEL_VERSION = "8.0"
```
#### 标准化功能
| 功能 | 支持 |
|------|------|
| **健康检查** | ✅ `--check-health` |
| **资源监控** | ✅ |
| **信号处理** | ✅ SIGTERM/SIGINT |
| **Redis进度** | ✅ |
| **标准化输出** | ✅ Contract规范 |
---
## 四、功能对比
### 功能矩阵
| 功能 | yolo_processor.py | yolo_processor_mps.py | yolo_processor_contract_v1.py |
|------|------------------|---------------------|----------------------------|
| **物体检测** | ✅ | ✅ | ✅ |
| **轨迹跟踪** | ✅ | ✅ | ✅ |
| **80类COCO** | ✅ | ✅ | ✅ |
| **Metal GPU加速** | ❌ | ✅ MPS ⭐⭐⭐ | ❌可选GPU |
| **Resume断点续传** | ✅ ⭐⭐⭐ | ✅ | ✅ |
| **Ctrl+C暂停** | ✅ ⭐⭐⭐ | ✅ | ✅ |
| **Batch处理** | ❌ | ✅ ⭐⭐ | ❌ |
| **Contract规范** | ❌ | ❌ | ✅ ⭐⭐⭐ |
| **Redis进度** | ✅ | ❌ | ✅ ⭐⭐⭐ |
| **健康检查** | ❌ | ❌ | ✅ ⭐⭐⭐ |
---
### Resume支持状态文档确认
```
// docs_v1.0/PROCESSORS/_CORE/PROCESSOR_UPGRADE_ANALYSIS.md Line 82
| yolo_processor.py | 已支持 Resume ✅ | ❌ 不需要升级 |
```
---
## 五、模型规格
### YOLOv8 模型对比
| 模型 | 参数量 | 输入尺寸 | 速度 | 精度 | 适用场景 |
|------|--------|---------|------|------|---------|
| **yolov8n**nano | 3.2M | 640 | **最快** ⭐⭐⭐ | 较低 | 实时检测 |
| yolov8ssmall | 11.2M | 640 | 快 ⭐⭐ | 中等 | 平衡方案 |
| yolov8mmedium | 25.9M | 640 | 中等 | 高 ⭐⭐ | 精度优先 |
| yolov8llarge | 43.7M | 640 | 慢 | 很高 ⭐⭐⭐ | 最高精度 |
| yolov8xextra | 68.2M | 640 | 最慢 ⚠️ | 最高 ⭐⭐⭐ | 研究用途 |
---
### 当前默认模型
| 版本 | 默认模型 | 模型大小 | 配置位置 |
|------|---------|---------|---------|
| yolo_processor.py | yolov8n | 6.2 MB | ultralytics自动下载 |
| yolo_processor_mps.py | yolov8n | 6.2 MB | Line 129: model_name="yolov8n" |
| yolo_processor_contract_v1.py | yolov8n | 6.2 MB | Line 155: MOMENTRY_YOLO_MODEL_SIZE |
---
### COCO 80类别列表部分
```
常见类别:
- person⭐⭐⭐
- car, truck, bus, motorcycle交通工具
- bicycle自行车
- dog, cat, bird动物
- chair, sofa, bed家具
- laptop, cell phone, tv电子设备
- bottle, cup, wine glass饮料容器
- book, clock日用品
```
---
## 六、输出格式对比
### yolo_processor.py 输出格式
```json
{
"metadata": {
"video_path": "...",
"fps": 29.97,
"total_frames": 4825,
"status": "completed",
"detection_method": "YOLOv8",
"last_saved_frame": 4825
},
"frames": {
"750": {
"frame_number": 750,
"time_seconds": 24.99,
"detections": [
{
"class_id": 0,
"class_name": "person",
"confidence": 0.85,
"bbox": [x1, y1, x2, y2],
"track_id": 1 // ⭐⭐ 轨迹ID
}
]
}
}
}
```
---
### yolo_processor_mps.py 输出格式
```json
{
"video_path": "...",
"model": "yolov8n",
"device": "mps",
"processed_at": "2026-04-28T...",
"frames": {
"750": {
"timestamp": 24.99,
"detections": [
{
"class_id": 0,
"class_name": "person",
"confidence": 0.85,
"bbox": [x, y, w, h]
}
]
}
},
"summary": {
"total_frames": 4825,
"total_detections": 1234,
"processing_time": 10.5
}
}
```
---
## 七、性能预期对比
### CPU vs MPS 性能差异
| 对比项 | CPU版本 | MPS版本预期| 差异 |
|--------|---------|--------------|------|
| **速度** | 基准 | **2-5倍快** ⭐⭐⭐ | MPS加速 |
| **内存** | 系统内存 | **统一内存** ⭐⭐ | Apple Silicon优化 |
| **Batch处理** | 单帧 | **多帧并行** ⭐⭐ | batch_size=8 |
---
### 模型大小影响
| 模型 | CPU速度 | MPS速度预期| 精度 |
|------|---------|--------------|------|
| yolov8n | 最快 ⭐⭐⭐ | **极快** ⭐⭐⭐⭐⭐ | 较低 |
| yolov8s | 快 ⭐⭐ | **快** ⭐⭐⭐⭐ | 中等 |
| yolov8m | 中等 | 中等 ⭐⭐⭐ | 高 ⭐⭐ |
---
## 八、场景推荐
### 推荐矩阵
| 场景 | 推荐版本 | 理由 |
|------|---------|------|
| **生产环境(默认)** | yolo_processor.py ⭐⭐⭐⭐⭐ | Resume已支持稳定可靠 |
| **Metal GPU加速** | yolo_processor_mps.py ⭐⭐⭐⭐⭐ | MPS加速 + Batch处理 |
| **标准化部署** | yolo_processor_contract_v1.py ⭐⭐⭐⭐⭐ | Contract规范 |
| **实时检测** | yolo_processor_mps.py + yolov8n ⭐⭐⭐⭐⭐ | 最快速度 |
---
### 模型选择建议
| 需求 | 推荐模型 | 理由 |
|------|---------|------|
| **实时检测** | yolov8n ⭐⭐⭐⭐⭐ | 最快速度 |
| **精度平衡** | yolov8s ⭐⭐⭐⭐ | 速度+精度平衡 |
| **精度优先** | yolov8m ⭐⭐⭐⭐ | 较高精度 |
---
## 九、关键发现
### Resume支持已确认 ✅
```
文档确认: yolo_processor.py 已支持 Resume ✅
实现位置: Line 124-186
功能:
- 加载已存在数据
- 断点续传
- Ctrl+C暂停保存
- 定期自动保存
```
---
### MPS版本支持 Metal GPU ✅
```
实现: torch.backends.mps.is_available()
设备: Apple Silicon Metal GPU
Batch: batch_size=8多帧并行
优势:
- 2-5倍速度提升预期
- 统一内存优化
```
---
### Contract版本标准化 ✅
```
Contract: Processor Contract v1.0
功能:
- 健康检查
- 资源监控
- 信号处理
- Redis进度报告
- 标准化输出
```
---
## 十、与 Face Processor 对比
### 关键差异
| 对比项 | YOLO | Face |
|--------|------|------|
| **检测对象** | 80类物体 | 人脸 |
| **Embedding** | ❌ 无 | ✅ InsightFace有512维 |
| **轨迹跟踪** | ✅ track_id ⭐⭐⭐ | ❌ 无 |
| **Resume** | ✅ 已支持 | ✅ InsightFace已支持 |
| **MPS支持** | ✅ yolo_processor_mps.py | ✅ face_processor_mps.py |
| **用途** | 物体检测/计数 | 人脸聚类/身份识别 |
---
### 功能对比矩阵
| 功能 | YOLO | Face (InsightFace) |
|------|------|-------------------|
| **检测** | ✅ 80类 | ✅ 人脸 |
| **Embedding** | ❌ | ✅ 512维 ⭐⭐⭐ |
| **轨迹跟踪** | ✅ track_id ⭐⭐⭐ | ❌ |
| **Age/Gender** | ❌ | ✅ ⭐⭐ |
| **Landmarks** | ❌ | ✅ 5点 ⭐⭐ |
| **Resume** | ✅ | ✅ |
| **MPS** | ✅ | ✅ |
---
## 十一、总结与建议
### 当前状态
| 项目 | 状态 |
|------|------|
| **Rust默认配置** | ✅ yolo_processor.py |
| **Resume支持** | ✅ 已实现 |
| **MPS版本** | ✅ 已实现Metal GPU |
| **Contract版本** | ✅ 已实现(标准化) |
| **默认模型** | yolov8nnano |
---
### 推荐方案
| 场景 | 推荐 | 优先级 |
|------|------|--------|
| **生产环境** | yolo_processor.py ⭐⭐⭐⭐⭐ | ✅ 当前默认 |
| **速度优化** | yolo_processor_mps.py ⭐⭐⭐⭐⭐ | 🟡 可选 |
| **标准化** | yolo_processor_contract_v1.py ⭐⭐⭐⭐⭐ | 🟡 可选 |
---
### 关键结论
| 结论 | 说明 |
|------|------|
| ✅ **YOLO Resume已支持** | 无需修复,已稳定 |
| ✅ **MPS版本可用** | Metal GPU加速已实现 |
| ✅ **功能完整** | 检测 + 轨迹跟踪 + Resume |
| ⚠️ **无Embedding** | 与Face不同YOLO无向量输出 |
---
**检讨完成日期**: 2026-04-28 02:00
**状态**: ✅ YOLO Processor 已完善,无需修复
**建议**: 保持当前配置yolo_processor.py或根据需求切换到MPS版本

View File

@@ -1,201 +0,0 @@
---
document_type: "specification"
service: "MOMENTRY_CORE"
title: "AI-Driven Processor Contract"
date: "2026-03-27"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "ai-processor"
- "contract"
- "standardization"
- "specification"
ai_query_hints:
- "AI Processor Contract 的規範內容是什麼?"
- "如何讓自定義 Processor 符合合約標準?"
- "AI Processor 的標準化介面定義為何?"
---
# AI-Driven Processor Contract
## Overview
This document defines the contract that all AI-driven processors in the Momentry system must follow to ensure consistency, reliability, and maintainability.
## Version
Contract Version: 1.0
Effective Date: 2025-03-27
## Core Principles
1. **Internal Standardization** Consistent implementation patterns across all processors
2. **External Communication** Standardized interfaces for integration with other system components
3. **Self-Monitoring** Built-in health checks and resource monitoring
4. **Graceful Degradation** Fallback strategies when optimal processing fails
5. **Performance Awareness** Adherence to performance constraints (≤5% overhead)
## Command-Line Interface
All processors must support the following command-line arguments:
### Required Arguments
- `video_path` Path to input video file
- `output_path` Path where JSON output should be written
### Optional Arguments
- `--uuid`, `-u` UUID for Redis progress reporting (default: empty string)
- `--check-health` Perform health check and exit (does not process video)
### Hidden/Configuration Arguments (can also be set via environment variables)
- Processor-specific configuration arguments should be hidden from help (`argparse.SUPPRESS`)
- Environment variable names should follow pattern: `MOMENTRY_{PROCESSOR}_*`
## Redis Progress Reporting
Processors must use the `RedisPublisher` class for progress reporting:
### Message Types
- `info` General information about processing stages
- `progress` Percentage completion for long-running tasks
- `warning` Non-fatal issues that don't stop processing
- `error` Fatal errors that cause processing to stop
- `complete` Final completion message with summary statistics
### Message Format
```json
{
"type": "info|progress|warning|error|complete",
"processor": "processor_name",
"message": "Human-readable message",
"timestamp": "ISO 8601 timestamp"
}
```
## Signal Handling
Processors must handle the following signals:
- `SIGTERM` Graceful shutdown request from system
- `SIGINT` User interrupt (Ctrl+C)
Signal handlers should:
1. Log the signal reception
2. Clean up temporary resources
3. Exit with appropriate exit code
## Health Checks
Processors must implement a health check mode (`--check-health`) that:
1. Verifies all required dependencies are available
2. Checks access to required external services (if any)
3. Returns a JSON structure with status and detailed information
4. Exits with code 0 for healthy, non-zero for unhealthy
Example health check output:
```json
{
"status": "healthy",
"dependencies": {
"faster_whisper": "available",
"psutil": "available"
},
"timestamp": "2025-03-27T10:30:00Z"
}
```
## Resource Monitoring
Processors should monitor their own resource usage during long-running operations:
- Sample CPU and memory usage at configurable intervals (default: 60 seconds)
- Log resource usage via Redis publisher when threshold exceeded
- Implement circuit breakers for excessive resource consumption
## Output JSON Schema
All processors must produce JSON output with the following base structure:
### Required Fields
- `processor_name` String identifying the processor (e.g., "asr", "yolo")
- `processor_version` Semantic version of the processor implementation
- `contract_version` Version of this contract (e.g., "1.0")
### Processor-Specific Fields
- Processor-specific data fields (e.g., `segments` for ASR, `frames` for OCR)
### Optional Metadata
- `processing_mode` How processing was performed (e.g., "direct", "chunked")
- `chunk_count` Number of chunks used (for chunked processing)
- `chunk_duration` Duration of each chunk in seconds
### Example ASR Output
```json
{
"processor_name": "asr",
"processor_version": "2.0.0",
"contract_version": "1.0",
"language": "en",
"language_probability": 0.95,
"segments": [
{
"start": 0.0,
"end": 2.5,
"text": "Hello world"
}
],
"processing_mode": "chunked",
"chunk_count": 7,
"chunk_duration": 600
}
```
## Error Handling
### Graceful Failure
- When processing fails, processors should clean up temporary resources
- Write error information to stderr with clear error messages
- Exit with non-zero exit code
### Fallback Strategies
- Implement fallback processing modes when optimal approach fails (e.g., direct → chunked transcription)
- Document fallback conditions and limitations
## Performance Constraints
### Overhead Limit
- Any optimization or additional functionality must not increase processing time by more than 5%
- Benchmark against baseline implementation to verify compliance
### Timeout Handling
- Respect timeout configurations from system configuration
- Implement progress-based timeout extensions where appropriate
## Checkpointing and Resume (Optional)
For long-running processors (> 5 minutes):
- Implement checkpointing to allow resuming from last saved state
- Save checkpoints at configurable intervals
- Provide mechanism to resume from checkpoint on subsequent runs
## Implementation Checklist
- [ ] Command-line interface compliant with specification
- [ ] Redis progress reporting implemented
- [ ] Signal handlers for SIGTERM and SIGINT
- [ ] Health check mode (`--check-health`)
- [ ] Resource monitoring (optional but recommended)
- [ ] Output JSON includes required base fields
- [ ] Error handling with graceful cleanup
- [ ] Performance overhead within 5% limit
- [ ] Documentation of processor-specific features
## Reference Implementation
The ASR processor (`scripts/asr_processor.py`) serves as the reference implementation for this contract, demonstrating all required and optional features.
## Changelog
### Version 1.0 (2025-03-27)
- Initial contract definition
- Based on ASR processor refactoring experience

View File

@@ -1,253 +0,0 @@
---
document_type: "checklist"
service: "MOMENTRY_CORE"
title: "AI Processor Compliance Checklist"
date: "2026-03-27"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "ai-processor"
- "compliance"
- "checklist"
- "quality-assurance"
ai_query_hints:
- "如何檢查 AI Processor 是否符合合約規範?"
- "各 Processor 的合規性狀態為何?"
- "AI Processor 合規檢查清單包含哪些項目?"
---
# AI Processor Compliance Checklist
## Overview
This checklist verifies compliance with the **AI-Driven Processor Contract v1.0**. All processors must pass all required checks to be considered contract-compliant.
## Compliance Status Summary
| Processor | Version | Contract | Compliance | Status | Last Verified |
|-----------|---------|----------|------------|--------|---------------|
| **ASR** | 2.1.0 | 1.0 | 100% | ✅ COMPLIANT | 2026-03-27 |
| **OCR** | 1.0.0 | 1.0 | 100% | ✅ COMPLIANT | 2026-03-27 |
| **YOLO** | 1.0.0 | 1.0 | 100% | ✅ COMPLIANT | 2026-03-27 |
| **Face** | 1.0.0 | 1.0 | 87.5% | ⚠️ PARTIAL | 2026-03-27 |
| **Pose** | 1.0.0 | 1.0 | 87.5% | ⚠️ PARTIAL | 2026-03-27 |
## Required Compliance Checks
### 1. Command-Line Interface ✅
**All processors PASS**
| Check | ASR | OCR | YOLO | Face | Pose |
|-------|-----|-----|------|------|------|
| `video_path` argument | ✅ | ✅ | ✅ | ✅ | ✅ |
| `output_path` argument | ✅ | ✅ | ✅ | ✅ | ✅ |
| `--uuid` or `-u` argument | ✅ | ✅ | ✅ | ✅ | ✅ |
| `--check-health` argument | ✅ | ✅ | ✅ | ✅ | ✅ |
| Hidden configuration args | ⚠️ | ⚠️ | ⚠️ | ⚠️ | ⚠️ |
**Notes**: All processors use environment variables for configuration (contract-compliant).
### 2. Health Check Mode ✅
**All processors PASS**
| Check | ASR | OCR | YOLO | Face | Pose |
|-------|-----|-----|------|------|------|
| Returns JSON output | ✅ | ✅ | ✅ | ✅ | ✅ |
| Includes `status` field | ✅ | ✅ | ✅ | ✅ | ✅ |
| Reports dependencies | ✅ | ✅ | ✅ | ✅ | ✅ |
| Includes timestamp | ⚠️ | ⚠️ | ✅ | ✅ | ✅ |
| Exit code 0 for healthy | ✅ | ✅ | ✅ | ✅ | ✅ |
**Notes**: ASR and OCR missing timestamp in health check (minor issue).
### 3. Signal Handling ✅
**All processors PASS**
| Check | ASR | OCR | YOLO | Face | Pose |
|-------|-----|-----|------|------|------|
| `signal` module imported | ✅ | ✅ | ✅ | ✅ | ✅ |
| SIGTERM handler | ✅ | ✅ | ✅ | ✅ | ✅ |
| SIGINT handler | ✅ | ✅ | ✅ | ✅ | ✅ |
| Graceful shutdown patterns | ✅ | ✅ | ✅ | ✅ | ✅ |
### 4. Redis Progress Reporting ✅
**All processors PASS** (Redis is optional)
| Check | ASR | OCR | YOLO | Face | Pose |
|-------|-----|-----|------|------|------|
| RedisPublisher import | ✅ | ✅ | ✅ | ✅ | ✅ |
| Progress reporting | ✅ | ✅ | ✅ | ✅ | ✅ |
| Message types | ✅ | ✅ | ✅ | ✅ | ✅ |
### 5. JSON Output Structure ⚠️
**ASR, OCR, YOLO PASS | Face, Pose FAIL**
| Check | ASR | OCR | YOLO | Face | Pose |
|-------|-----|-----|------|------|------|
| `processor_name` field | ✅ | ✅ | ✅ | ❌ | ❌ |
| `processor_version` field | ✅ | ✅ | ✅ | ✅ | ✅ |
| `contract_version` field | ✅ | ✅ | ✅ | ✅ | ✅ |
| JSON output patterns | ✅ | ✅ | ✅ | ✅ | ✅ |
**Critical Issues**: Face and Pose processors missing `processor_name` field in JSON output.
### 6. Error Handling ✅
**All processors PASS**
| Check | ASR | OCR | YOLO | Face | Pose |
|-------|-----|-----|------|------|------|
| Exception handling | ✅ | ✅ | ✅ | ✅ | ✅ |
| Graceful cleanup | ✅ | ✅ | ✅ | ✅ | ✅ |
| Exit codes | ✅ | ✅ | ✅ | ✅ | ✅ |
### 7. Unified Configuration ✅
**All processors PASS**
| Check | ASR | OCR | YOLO | Face | Pose |
|-------|-----|-----|------|------|------|
| `MOMENTRY_` env vars | ✅ | ✅ | ✅ | ✅ | ✅ |
| Timeout handling | ✅ | ✅ | ✅ | ✅ | ✅ |
## Critical Issues to Address
### 1. Face Processor - JSON Output Structure
- **Issue**: Missing `processor_name` field in JSON output
- **Impact**: Non-compliant with contract requirement
- **Priority**: HIGH
- **Fix**: Add `"processor_name": "face"` to all JSON return statements
### 2. Pose Processor - JSON Output Structure
- **Issue**: Missing `processor_name` field in JSON output
- **Impact**: Non-compliant with contract requirement
- **Priority**: HIGH
- **Fix**: Add `"processor_name": "pose"` to all JSON return statements
### 3. ASR/OCR Processors - Health Check Timestamp
- **Issue**: Missing timestamp in health check output
- **Impact**: Minor compliance issue
- **Priority**: LOW
- **Fix**: Add `"timestamp": datetime.now().isoformat()` to health check
## Performance Compliance
**Note**: Performance benchmarks (<5% overhead) have not been run yet. This is a separate verification step.
| Processor | Baseline Tested | Overhead Verified | Status |
|-----------|----------------|-------------------|--------|
| ASR | ❌ | ❌ | PENDING |
| OCR | ❌ | ❌ | PENDING |
| YOLO | ❌ | ❌ | PENDING |
| Face | ❌ | ❌ | PENDING |
| Pose | ❌ | ❌ | PENDING |
## Implementation Quality Assessment
### High Quality Implementations (95-100% compliance)
1. **ASR Processor v2.1.0** - Reference implementation
- Lines reduced from 953 to 341 (64% reduction)
- Comprehensive timeout handling
- Model caching for performance
- Excellent error handling
2. **OCR Processor v1.0.0** - Well-structured
- EasyOCR integration with caching
- Good frame processing logic
- Clear configuration structure
3. **YOLO Processor v1.0.0** - Feature-rich
- Resume support with checkpoints
- Auto-save functionality
- COCO class filtering
### Needs Improvement (80-90% compliance)
1. **Face Processor v1.0.0** - Incomplete implementation
- File appears truncated (257 vs expected 621 lines)
- Missing JSON structure fields
- Needs complete rewrite
2. **Pose Processor v1.0.0** - Incomplete implementation
- File appears truncated (291 vs expected 666 lines)
- Missing JSON structure fields
- Needs complete rewrite
## Verification Tools
### Automated Verification
```bash
# Verify all processors
python3 verify_processor_compliance.py
# Verify specific processor
python3 verify_processor_compliance.py --processor asr
# Generate report
python3 verify_processor_compliance.py --output report.md
```
### Manual Verification Steps
1. **CLI Test**: `python3 script.py --help`
2. **Health Check**: `python3 script.py dummy.mp4 dummy.json --check-health`
3. **Signal Test**: Run processor and send SIGINT (Ctrl+C)
4. **Output Test**: Process sample video and verify JSON structure
## Remediation Plan
### Phase 1: Critical Fixes (Immediate)
1. **Fix Face processor JSON output** - Add missing `processor_name` field
2. **Fix Pose processor JSON output** - Add missing `processor_name` field
3. **Complete Face processor implementation** - Rewrite from template
4. **Complete Pose processor implementation** - Rewrite from template
### Phase 2: Minor Improvements (Next 7 days)
1. Add timestamps to ASR/OCR health checks
2. Run performance benchmarks for all processors
3. Update documentation with compliance status
4. Integrate with monitoring system
### Phase 3: Remaining Processors (Next 14 days)
1. **ASRX Processor** - Standardize to contract
2. **Caption Processor** - Standardize to contract
3. **CUT Processor** - Standardize to contract
4. **Story Processor** - Standardize to contract
## Success Criteria
### Contract Compliance
- [x] 3/5 processors at 100% compliance (ASR, OCR, YOLO)
- [ ] 5/5 processors at 100% compliance (Face, Pose pending)
- [ ] All processors pass performance benchmarks (<5% overhead)
### Documentation
- [x] AI-Driven Processor Contract defined
- [x] Processor Standardization Template created
- [x] Revision Records documented
- [x] Compliance Checklist created
- [ ] User guides updated
### Integration
- [x] Unified configuration in Rust
- [ ] Monitoring integration complete
- [ ] Performance dashboards operational
## Next Steps
1. **Immediate**: Fix Face and Pose processor JSON output structure
2. **Short-term**: Complete Face and Pose processor implementations
3. **Medium-term**: Standardize remaining processors (ASRX, Caption, CUT, Story)
4. **Long-term**: Performance benchmarking and optimization
## References
1. [AI-Driven Processor Contract](../REFERENCE/AI_DRIVEN_PROCESSOR_CONTRACT.md)
2. [Processor Standardization Template](../REFERENCE/PROCESSOR_STANDARDIZATION_TEMPLATE.md)
3. [AI Processor Module Revision Records](../REFERENCE/AI_PROCESSOR_MODULE_REVISION_RECORDS.md)
4. [ASR Configuration Unification](../REFERENCE/ASR_CONFIGURATION_UNIFICATION.md)
## Changelog
### Version 1.0 (2026-03-27)
- Initial compliance checklist created
- 3/5 processors at 100% compliance
- Automated verification tool created
- Comprehensive documentation structure established

View File

@@ -1,242 +0,0 @@
---
document_type: "architecture_design"
service: "MOMENTRY_CORE"
title: "Momentry Core 處理器產出規範 (Pre-Chunk & Frame) (v1.0)"
date: "2026-04-21"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "momentry"
- "core"
- "處理器產出規範"
ai_query_hints:
- "查詢 Momentry Core 處理器產出規範 (Pre-Chunk & Frame) (v1.0) 的內容"
- "Momentry Core 處理器產出規範 (Pre-Chunk & Frame) (v1.0) 的主要目的是什麼?"
- "如何操作或實施 Momentry Core 處理器產出規範 (Pre-Chunk & Frame) (v1.0)"
---
# Momentry Core 處理器產出規範 (Pre-Chunk & Frame) (v1.0)
| 項目 | 內容 |
|------|------|
| 建立者 | OpenCode |
| 建立時間 | 2026-04-21 |
| 文件版本 | V1.0 |
---
## 版本歷史
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-04-21 | 定義處理器產出 JSON 之 Pre-chunk 與 Frame 結構標準 | OpenCode | OpenCode / Qwen3.6-Plus |
---
## 0. 設計原則
為確保所有處理器ASR, OCR, Face, YOLO, Cut產出的時間軸精確且一致本規範定義以下核心原則
1. **幀為本位 (Frame-Based)**
* 所有時間計算的**唯一權威來源**是幀編號 (`frame_number`)。
* 開始時間、結束時間、長度皆以幀為單位 (`start_frame`, `end_frame`, `length_frames`)。
2. **秒數為參考 (Timestamp is Derived)**
* 秒數 (`timestamp_sec`, `start_time_sec`) 僅供人類閱讀與外部 API 參考。
* 計算公式:`time = frame / fps`
* FPS 資訊必須與 `ffprobe` 探針結果嚴格一致。
3. **結構統一**
* 產出分為兩大層級:**Frame (單幀檢測)** 與 **Pre-Chunk (時間區間聚合)**
---
## 1. 核心資料結構
### 1.1 Frame (幀級資料)
適用於需要逐幀記錄空間座標或逐幀屬性的任務 (如 OCR, Face, YOLO)。
```json
{
"frame_number": 12345,
"timestamp_sec": 411.91,
"fps": 29.97,
"processor": "face_detection",
"data": {
"faces": [
{
"box": { "x": 100, "y": 50, "w": 60, "h": 60 },
"identity": null,
"confidence": 0.98
}
]
}
}
```
| 欄位 | 類型 | 說明 | 計算方式 |
|:---|:---|:---|:---|
| `frame_number` | `int` | **主鍵**,物理幀編號 | 從 0 開始計數 |
| `timestamp_sec` | `float` | 時間戳記 (秒) | `frame_number / fps` |
| `fps` | `float` | 幀率 | 來自 `ffprobe` 探針結果 |
| `data` | `object` | 偵測結果負載 | 依處理器類型定義 |
### 1.2 Pre-Chunk (預切片資料)
適用於具有持續時間的語意片段 (如 ASR 語句、鏡頭切換、OCR 持續文字)。
```json
{
"pre_chunk_id": "pc_001",
"type": "asr_segment",
"start_frame": 1200,
"end_frame": 1500,
"duration_frames": 300,
"start_time_sec": 40.04,
"end_time_sec": 50.05,
"fps": 29.97,
"data": {
"text": "這是一個非常長的句子...",
"speaker": "SPEAKER_00"
}
}
```
| 欄位 | 類型 | 說明 | 計算方式 |
|:---|:---|:---|:---|
| `start_frame` | `int` | **起始幀** | - |
| `end_frame` | `int` | **結束幀** | - |
| `duration_frames` | `int` | 持續幀數 | `end_frame - start_frame + 1` |
| `start_time_sec` | `float` | 起始秒數 | `start_frame / fps` |
| `end_time_sec` | `float` | 結束秒數 | `end_frame / fps` |
| `data` | `object` | 內容負載 | 依處理器類型定義 |
---
## 2. 處理器產出規範 (JSON Spec)
### 2.1 ASR (語音識別) -> Pre-Chunk
ASR 產出主要是文字片段,因此歸類為 `Pre-Chunk`
* **輸出檔名**: `{uuid}_asr.json`
* **結構**: Array of Pre-Chunk
```json
[
{
"start_frame": 0,
"end_frame": 149,
"start_time_sec": 0.0,
"end_time_sec": 5.0,
"data": {
"text": "Hello world, this is a test.",
"speaker": "SPEAKER_00",
"language": "en"
}
},
...
]
```
### 2.2 Face (人臉偵測) -> Frame
人臉位置可能每幀微動,因此以 `Frame` 記錄最精確。
* **輸出檔名**: `{uuid}_faces.json`
* **結構**: Object containing Array of Frames
```json
{
"info": {
"fps": 29.97,
"total_frames": 5000
},
"frames": [
{
"frame_number": 10,
"timestamp_sec": 0.33,
"data": {
"faces": [
{ "box": { "x": 10, "y": 10, "w": 50, "h": 50 }, "confidence": 0.99 }
]
}
}
]
}
```
### 2.3 OCR (文字辨識) -> Frame
通常以抽樣 (Sample) 方式進行 (如每 30 幀抽 1 幀)。
* **輸出檔名**: `{uuid}_ocr.json`
* **結構**: Array of Frames
```json
[
{
"frame_number": 1200,
"timestamp_sec": 40.04,
"data": {
"texts": [
{ "text": "CAST", "bbox": [100, 100, 200, 50] },
{ "text": "Cary Grant", "bbox": [100, 150, 200, 30] }
]
}
}
]
```
### 2.4 Cut (鏡頭切割) -> Pre-Chunk
鏡頭切割定義了場景的邊界,是典型的 Pre-Chunk。
* **輸出檔名**: `{uuid}_cuts.json`
* **結構**: Array of Pre-Chunk
```json
[
{
"start_frame": 0,
"end_frame": 299,
"start_time_sec": 0.0,
"end_time_sec": 10.0,
"data": {
"scene_type": "indoor",
"cut_score": 0.95
}
}
]
```
---
## 3. 數據一致性檢查
為確保產出符合規範,寫入資料庫前需執行以下檢查:
1. **FPS 校驗**: JSON 中的 `fps` 必須等於 `assets` 表中 `media_info->fps` 的值。誤差允許範圍 `±0.01`
2. **幀邊界**: `start_frame` 必須 `>= 0``end_frame` 必須 `<= total_frames`
3. **時間換算驗證**:
* `abs(timestamp_sec - (frame_number / fps)) < 0.001`
---
## 4. 與 Chunk 系統的關聯
Processor 產出的是 **Raw Data (Pre-chunk / Frames)**
後續的 **Chunk Strategy (Rule 1/2/3)** 會讀取這些 Raw Data 並進行聚合,生成最終的 `chunks` 表記錄。
* **Input**: 多個 Pre-chunks / Frames
* **Process**: 合併 (Merge)、摘要 (Summarize)、嵌入 (Embedding)
* **Output**: `chunks` 表 (具備語意向量)
```mermaid
graph LR
A[ASR Pre-Chunk] --> C(Chunk Aggregator)
B[OCR Frame] --> C
D[Cut Pre-Chunk] --> C
C --> E[Final Chunk with Vector]
```
此設計確保了**原始物理資訊 (幀)** 的完整保留,同時允許上層邏輯進行靈活的語意組裝。

View File

@@ -1,493 +0,0 @@
---
document_type: "reference_doc"
service: "MOMENTRY_CORE"
title: "Processor Standardization Template"
date: "2026-04-25"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "processor"
- "template"
- "standardization"
ai_query_hints:
- "查詢 Processor Standardization Template 的內容"
- "Processor Standardization Template 的主要目的是什麼?"
- "如何操作或實施 Processor Standardization Template"
---
# Processor Standardization Template
## Overview
This template provides a standardized approach for creating contract-compliant processor modules based on the AI-Driven Processor Contract. Use this template when creating new processors or updating existing ones.
## Template Structure
### 1. Python Processor Script Template
```python
#!/opt/homebrew/bin/python3.11
"""
{PROCESSOR_NAME} Processor - AI-Driven Processor Contract Version {VERSION}
Compliant with AI-Driven Processor Contract v1.0
Effective Date: {DATE}
Features:
1. Standardized command-line interface
2. Redis progress reporting
3. Signal handling (SIGTERM, SIGINT)
4. Health check mode
5. Resource monitoring
6. Contract-compliant JSON output
7. Unified configuration
"""
import sys
import json
import os
import argparse
import signal
import tempfile
import time
import subprocess
import traceback
import threading
from datetime import datetime
from pathlib import Path
from typing import Dict, Any, List, Optional, Tuple
import atexit
# Redis Publisher for progress reporting
try:
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from redis_publisher import RedisPublisher
REDIS_AVAILABLE = True
except ImportError:
REDIS_AVAILABLE = False
print(
f"WARNING: RedisPublisher not available, progress reporting disabled",
file=sys.stderr,
)
# Contract version
CONTRACT_VERSION = "1.0"
PROCESSOR_NAME = "{processor_name}" # e.g., "ocr", "yolo", "face", "pose"
PROCESSOR_VERSION = "{version}" # e.g., "1.0.0"
# Unified configuration defaults
DEFAULT_TIMEOUT = 3600 # 1 hour
# Add processor-specific defaults here
# Signal handling with timeout support
class SignalHandler:
"""Handle system signals for graceful shutdown"""
# ... (same as ASR template)
# Timeout manager
class TimeoutManager:
"""Manage processing timeouts"""
# ... (same as ASR template)
# Health check functions
def check_environment() -> Dict[str, Any]:
"""Check environment and dependencies"""
checks = []
# Check 1: Processor-specific dependencies
try:
# Import processor-specific libraries
# e.g., import cv2, import pytesseract, etc.
checks.append({
"name": "{dependency_name}",
"status": "available",
"version": "x.x.x" # Get actual version
})
except ImportError:
checks.append({"name": "{dependency_name}", "status": "missing", "version": None})
# Check 2: FFmpeg/FFprobe (if needed)
# ... (same as ASR template)
# Check 3: Redis (optional)
# ... (same as ASR template)
# Check 4: Python version
# ... (same as ASR template)
return {"status": "healthy", "dependencies": checks}
# Main processor class
class {ProcessorClass}Processor:
"""{PROCESSOR_NAME} Processor compliant with AI-Driven Processor Contract"""
def __init__(
self,
video_path: str,
output_path: str,
uuid: Optional[str] = None,
check_health: bool = False,
):
self.video_path = video_path
self.output_path = output_path
self.uuid = uuid or ""
self.check_health = check_health
# Get unified configuration from environment
self.timeout = int(os.environ.get(f"MOMENTRY_{PROCESSOR_NAME.upper()}_TIMEOUT", str(DEFAULT_TIMEOUT)))
# Add processor-specific configuration here
# Initialize components
self.publisher = None
if REDIS_AVAILABLE and self.uuid:
try:
self.publisher = RedisPublisher(self.uuid)
except Exception as e:
print(f"[{PROCESSOR_NAME}] Failed to initialize Redis publisher: {e}", file=sys.stderr)
self.timeout_manager = TimeoutManager(self.timeout, self.timeout, self.timeout)
self.signal_handler = SignalHandler()
self.start_time = time.time()
self.cleanup_files = []
# Set up signal handling
self.signal_handler.setup()
atexit.register(self.cleanup)
def publish(self, msg_type: str, message: str, progress: Optional[float] = None):
"""Publish message to Redis if available"""
# ... (same as ASR template)
def validate_input(self) -> Tuple[bool, str]:
"""Validate input file"""
if not os.path.exists(self.video_path):
return False, f"Video file not found: {self.video_path}"
# Add processor-specific validation
# e.g., check video format, resolution, etc.
return True, "Input validation passed"
def process(self) -> Dict[str, Any]:
"""Main processing method"""
self.publish("info", f"Starting {PROCESSOR_NAME} processing: {self.video_path}")
# Validate input
is_valid, validation_msg = self.validate_input()
if not is_valid:
raise RuntimeError(f"Input validation failed: {validation_msg}")
self.publish("info", "Input validation passed")
# Start timeout monitoring
self.timeout_manager.start_overall_timer()
# Processor-specific processing logic
# This is where the actual processing happens
try:
result = self._process_core()
except Exception as e:
raise RuntimeError(f"Processing failed: {e}")
# Check for timeout
timeout_reached, timeout_msg = self.timeout_manager.check_timeout("processing")
if timeout_reached:
raise RuntimeError(f"Processing {timeout_msg}")
# Prepare final result
final_result = {
"processor_name": PROCESSOR_NAME,
"processor_version": PROCESSOR_VERSION,
"contract_version": CONTRACT_VERSION,
"video_path": self.video_path,
"timestamp": datetime.utcnow().isoformat() + "Z",
"processing_time_seconds": time.time() - self.start_time,
"configuration": {
"timeout_seconds": self.timeout,
# Add processor-specific configuration
},
**result, # Include processor-specific results
}
self.publish("progress", f"{PROCESSOR_NAME} processing complete", 1.0)
self.publish("complete", f"{PROCESSOR_NAME} processing completed successfully in {final_result['processing_time_seconds']:.1f}s")
return final_result
def _process_core(self) -> Dict[str, Any]:
"""Core processing logic - implement in subclass"""
raise NotImplementedError("Subclasses must implement _process_core")
def cleanup(self):
"""Clean up temporary resources"""
# ... (same as ASR template)
def main():
"""Main entry point"""
parser = argparse.ArgumentParser(
description=f"{PROCESSOR_NAME} Processor - AI-Driven Processor Contract Version {PROCESSOR_VERSION}"
)
# Required arguments
parser.add_argument("video_path", help="Path to input video file")
parser.add_argument("output_path", help="Path where JSON output should be written")
# Optional arguments
parser.add_argument("--uuid", "-u", default="", help="UUID for Redis progress reporting")
parser.add_argument("--check-health", action="store_true", help="Perform health check and exit")
# Hidden configuration arguments (following contract)
parser.add_argument("--timeout", type=int, help=argparse.SUPPRESS)
# Add processor-specific hidden arguments
args = parser.parse_args()
# Health check mode
if args.check_health:
health_result = check_environment()
print(json.dumps(health_result, indent=2))
sys.exit(0 if health_result["status"] == "healthy" else 1)
# Create processor
processor = {ProcessorClass}Processor(
video_path=args.video_path,
output_path=args.output_path,
uuid=args.uuid if args.uuid else None,
check_health=args.check_health,
)
try:
# Process video
result = processor.process()
# Write output
with open(args.output_path, "w", encoding="utf-8") as f:
json.dump(result, f, indent=2, ensure_ascii=False)
print(f"[{PROCESSOR_NAME}] Processing completed successfully")
print(f"[{PROCESSOR_NAME}] Output written to: {args.output_path}")
sys.exit(0)
except RuntimeError as e:
error_msg = f"{PROCESSOR_NAME} processing failed: {e}"
processor.publish("error", error_msg)
print(f"[{PROCESSOR_NAME}] ERROR: {error_msg}", file=sys.stderr)
sys.exit(1)
except KeyboardInterrupt:
processor.publish("warning", "Processing interrupted by user")
print(f"[{PROCESSOR_NAME}] Processing interrupted by user", file=sys.stderr)
sys.exit(130) # Standard exit code for SIGINT
except Exception as e:
error_msg = f"Unexpected error: {e}\n{traceback.format_exc()}"
processor.publish("error", error_msg)
print(f"[{PROCESSOR_NAME}] CRITICAL ERROR: {error_msg}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
```
### 2. Rust Configuration Template
```rust
// Add to src/core/config.rs
pub mod {processor_name} { // e.g., ocr, yolo, face, pose
use super::*;
// Unified configuration
pub static TIMEOUT_SECS: Lazy<u64> = Lazy::new(|| {
env::var(format!("MOMENTRY_{}_TIMEOUT", {PROCESSOR_NAME_UPPER}))
.unwrap_or_else(|_| "3600".to_string())
.parse()
.unwrap_or(3600)
});
// Add processor-specific configuration
// e.g., model paths, confidence thresholds, etc.
}
```
### 3. Rust Processor Module Template
```rust
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::time::Duration;
use super::executor::PythonExecutor;
use crate::core::config::{processor, {processor_name}};
#[derive(Debug, Serialize, Deserialize)]
pub struct {ProcessorClass}Result {
// Define processor-specific result structure
}
pub async fn process_{processor_name}(
video_path: &str,
output_path: &str,
uuid: Option<&str>,
) -> Result<{ProcessorClass}Result> {
let executor = PythonExecutor::new()?;
let script_path = executor.script_path("{processor_name}_processor_contract.py");
tracing::info!("[{PROCESSOR_NAME_UPPER}] Starting processing: {}", video_path);
executor
.run(
"{processor_name}_processor_contract.py",
&[video_path, output_path],
uuid,
"{PROCESSOR_NAME_UPPER}",
Some(Duration::from_secs(*{processor_name}::TIMEOUT_SECS)),
)
.await
.with_context(|| format!("Failed to run {:?}", script_path))?;
let json_str = std::fs::read_to_string(output_path)
.context("Failed to read {PROCESSOR_NAME} output")?;
let result: {ProcessorClass}Result =
serde_json::from_str(&json_str).context("Failed to parse {PROCESSOR_NAME} output")?;
tracing::info!("[{PROCESSOR_NAME_UPPER}] Processing completed successfully");
Ok(result)
}
```
## Implementation Steps
### Step 1: Analyze Existing Processor
1. Review current Python script (`scripts/{processor_name}_processor.py`)
2. Identify dependencies and requirements
3. Understand input/output formats
4. Note any configuration needs
### Step 2: Create Contract-Compliant Version
1. Copy template to `scripts/{processor_name}_processor_contract.py`
2. Fill in processor-specific details:
- `PROCESSOR_NAME` and `PROCESSOR_VERSION`
- Dependencies in `check_environment()`
- Configuration defaults
- Core processing logic in `_process_core()`
- Result structure
### Step 3: Update Rust Configuration
1. Add configuration module to `src/core/config.rs`
2. Define environment variables and defaults
### Step 4: Update Rust Processor Module
1. Update or create `src/core/processor/{processor_name}.rs`
2. Use contract-compliant script
3. Pass configuration via environment variables
### Step 5: Test and Validate
1. Create test script
2. Verify health check mode
3. Test basic processing
4. Validate contract compliance
5. Test configuration unification
## Processor-Specific Considerations
### OCR Processor
- **Dependencies**: Tesseract, OpenCV, PIL
- **Configuration**: Language models, confidence thresholds
- **Output**: Text with bounding boxes, confidence scores
### YOLO Processor
- **Dependencies**: Ultralytics YOLO, OpenCV
- **Configuration**: Model path, confidence threshold, classes
- **Output**: Detected objects with bounding boxes, classes, confidence
### Face Processor
- **Dependencies**: face_recognition, dlib, OpenCV
- **Configuration**: Model paths, encoding methods
- **Output**: Face locations, encodings, landmarks
### Pose Processor
- **Dependencies**: MediaPipe, OpenCV
- **Configuration**: Model complexity, confidence thresholds
- **Output**: Pose keypoints, connections, confidence scores
## Configuration Variables
Each processor should support:
- `MOMENTRY_{PROCESSOR}_TIMEOUT` - Overall timeout
- `MOMENTRY_{PROCESSOR}_MODEL_PATH` - Model file path (if applicable)
- `MOMENTRY_{PROCESSOR}_CONFIDENCE` - Confidence threshold (if applicable)
- Processor-specific configuration
## Testing Checklist
- [ ] Health check mode works
- [ ] Basic processing with sample video
- [ ] Configuration loading from environment
- [ ] Signal handling (SIGINT, SIGTERM)
- [ ] Timeout handling
- [ ] Redis progress reporting (if Redis available)
- [ ] Output JSON follows contract schema
- [ ] Error handling and graceful degradation
## Migration Strategy
1. **Phase 1**: Create contract-compliant version alongside existing
2. **Phase 2**: Update Rust module to use new version
3. **Phase 3**: Test thoroughly
4. **Phase 4**: Remove old version (keep as backup)
## Example: OCR Processor Implementation
### Configuration (config.rs)
```rust
pub mod ocr {
use super::*;
pub static TIMEOUT_SECS: Lazy<u64> = Lazy::new(|| {
env::var("MOMENTRY_OCR_TIMEOUT")
.unwrap_or_else(|_| "1800".to_string())
.parse()
.unwrap_or(1800)
});
pub static LANGUAGE: Lazy<String> = Lazy::new(|| {
env::var("MOMENTRY_OCR_LANGUAGE")
.unwrap_or_else(|_| "eng".to_string())
});
pub static CONFIDENCE_THRESHOLD: Lazy<f32> = Lazy::new(|| {
env::var("MOMENTRY_OCR_CONFIDENCE")
.unwrap_or_else(|_| "0.7".to_string())
.parse()
.unwrap_or(0.7)
});
}
```
### Python Script
- `PROCESSOR_NAME = "ocr"`
- `PROCESSOR_VERSION = "1.0.0"`
- Dependencies: `pytesseract`, `opencv-python`, `PIL`
- Core logic: Extract frames, run OCR, return text with positions
## Success Criteria
1. **Contract Compliance**: Follows AI-Driven Processor Contract
2. **Configuration Unification**: Uses unified configuration system
3. **Backward Compatibility**: Existing workflows continue to work
4. **Improved Maintainability**: Clean, standardized code
5. **Better Observability**: Consistent logging and monitoring
---
*Template Version: 1.0*
*Last Updated: 2026-03-27*
*Based on: AI-Driven Processor Contract v1.0*

View File

@@ -1,621 +0,0 @@
---
document_type: "architecture_design"
service: "MOMENTRY_CORE"
title: "ASRX 取代 ASR - Mac Studio 硬體升級評估"
date: "2026-04-01"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "asrx"
- "硬體升級評估"
- "studio"
ai_query_hints:
- "查詢 ASRX 取代 ASR - Mac Studio 硬體升級評估 的內容"
- "ASRX 取代 ASR - Mac Studio 硬體升級評估 的主要目的是什麼?"
- "如何操作或實施 ASRX 取代 ASR - Mac Studio 硬體升級評估?"
---
# ASRX 取代 ASR - Mac Studio 硬體升級評估
| 項目 | 內容 |
|------|------|
| 分析日期 | 2026-04-01 |
| 部署模式 | 邊緣 AI本地運行 |
| 現有硬體 | M4 Mac Mini 16GB |
| **未來硬體** | **Mac Studio** |
| 目標 | 評估硬體升級後的處理器架構 |
---
## 執行摘要
### ✅ 強烈建議統一為 ASRX
**Mac Studio 優勢**
- ✅ 記憶體更大32-128GB
- ✅ GPU 更強M4 Max/M2 Ultra
- ✅ 可運行大型模型無壓力
- ✅ 並行處理能力提升
- ✅ 完全消除效能瓶頸
**新架構建議**
- 統一使用 ASRX
- 預設 large-v3 模型
- 所有影片類型適用
---
## Mac Studio 規格分析
### 預期硬體配置
| 機型 | 晶片 | 記憶體 | GPU 核心數 | 價格區間 |
|------|------|--------|-----------|---------|
| **Mac Studio** | M4 Max | 32-64GB | 30-40 | $1,999-$3,199 |
| **Mac Studio** | M2 Ultra | 64-128GB | 60-76 | $3,999-$5,499 |
| **Mac Studio** | M4 Ultra (預期) | 128-192GB | 80+ | $6,999+ |
### 記憶體對比
```
M4 Mac Mini 16GB:
├─ 系統保留: 2-3 GB
├─ 資料庫: 2 GB
├─ API Server: 0.5 GB
└─ 可用於處理器: 10-11 GB ⚠️
Mac Studio 32GB:
├─ 系統保留: 2-3 GB
├─ 資料庫: 2 GB
├─ API Server: 0.5 GB
└─ 可用於處理器: 26-27 GB ✅
Mac Studio 64GB:
├─ 系統保留: 3-4 GB
├─ 資料庫: 2 GB
├─ API Server: 0.5 GB
└─ 可用於處理器: 57-58 GB ✅✅
Mac Studio 128GB:
├─ 系統保留: 4-5 GB
├─ 資料庫: 2 GB
├─ API Server: 0.5 GB
└─ 可用於處理器: 116-119 GB ✅✅✅
```
---
## 效能提升預估
### ASRX Large-v3 處理時間對比
| 硬體 | 短影片 (159.6s) | 中影片 (10分鐘) | 長影片 (114分鐘) |
|------|----------------|----------------|-----------------|
| **M4 Mini 16GB** | 150s | 600s | 5,400s (90分鐘) |
| **Mac Studio 32GB** | **75s** ✅ | **300s** ✅ | **2,700s (45分鐘)** ✅ |
| **Mac Studio 64GB** | **45s** ✅✅ | **180s** ✅✅ | **1,620s (27分鐘)** ✅✅ |
| **Mac Studio 128GB** | **30s** ✅✅✅ | **120s** ✅✅✅ | **1,080s (18分鐘)** ✅✅✅ |
**加速比**
- Mac Studio 32GB: **2x** 提升
- Mac Studio 64GB: **3.3x** 提升
- Mac Studio 128GB: **5x** 提升
### 多處理器並行運行
```
M4 Mini 16GB:
├─ 記憶體限制: 只能串行運行
└─ 並行風險: 記憶體溢位 ❌
Mac Studio 64GB:
├─ 可並行: 4-6 個處理器
└─ 總時間: 減少 60-70% ✅
Mac Studio 128GB:
├─ 可並行: 8-10 個處理器
└─ 總時間: 減少 80-85% ✅✅
```
---
## 新架構設計Mac Studio 優化)
### 統一處理器架構
```python
class UnifiedAudioProcessor:
"""
Mac Studio 優化版統一音頻處理器
預設配置:
- 模型: large-v3
- 說話人分離: 啟用
- 時間戳對齊: 啟用
- 裝置: MPS (Metal Performance Shaders)
- 精度: float16
"""
DEFAULT_CONFIG = {
"model": "large-v3", # 最高準確度
"diarization": True, # 說話人分離
"alignment": True, # 詞級時間戳
"device": "mps", # Mac GPU
"compute_type": "float16", # FP16 加速
"batch_size": 16, # 批次處理
"num_workers": 4 # 並行工作進程
}
```
### 記憶體管理策略
```python
class MemoryManager:
"""Mac Studio 記憶體管理"""
# 根據硬體自動調整
MEMORY_LIMITS = {
32: {"max_usage": 26000, "cleanup_threshold": 22000},
64: {"max_usage": 57000, "cleanup_threshold": 50000},
128: {"max_usage": 116000, "cleanup_threshold": 100000}
}
def __init__(self):
import psutil
self.total_memory = psutil.virtual_memory().total // (1024 * 1024)
self.config = self._get_config()
def _get_config(self):
"""根據記憶體大小自動配置"""
for mem_size, config in sorted(self.MEMORY_LIMITS.items(), reverse=True):
if self.total_memory >= mem_size * 1024:
return config
return self.MEMORY_LIMITS[32]
```
### 並行處理架構
```python
import concurrent.futures
from typing import List, Dict
class ParallelProcessor:
"""Mac Studio 並行處理器"""
def __init__(self, max_workers: int = None):
# 根據記憶體自動決定並行數
if max_workers is None:
import psutil
total_gb = psutil.virtual_memory().total // (1024**3)
self.max_workers = min(total_gb // 8, 8) # 每 8GB 一個 worker
else:
self.max_workers = max_workers
def process_videos(self, video_paths: List[str], configs: List[Dict]):
"""並行處理多個影片"""
with concurrent.futures.ThreadPoolExecutor(max_workers=self.max_workers) as executor:
futures = []
for video_path, config in zip(video_paths, configs):
future = executor.submit(
self._process_single,
video_path,
config
)
futures.append(future)
results = []
for future in concurrent.futures.as_completed(futures):
results.append(future.result())
return results
```
---
## Mac Studio 專屬優化
### 1. Metal Performance Shaders (MPS) 加速
```python
import torch
class MPSOptimizer:
"""Mac Studio MPS 優化"""
@staticmethod
def optimize_model(model):
"""優化模型以使用 MPS"""
if torch.backends.mps.is_available():
# 使用 Mac GPU
device = torch.device("mps")
model = model.to(device)
# 啟用 FP16Mac Studio 支援)
model = model.half()
# 啟用記憶體優化
torch.mps.empty_cache()
return model
return model
@staticmethod
def get_device_info():
"""取得裝置資訊"""
if torch.backends.mps.is_available():
return {
"device": "mps",
"available": True,
"built": torch.backends.mps.is_built()
}
return {"device": "cpu", "available": False}
```
### 2. 批次處理優化
```python
class BatchProcessor:
"""Mac Studio 批次處理優化"""
def __init__(self, batch_size: int = 16):
self.batch_size = batch_size
self.device = torch.device("mps")
def process_batch(self, audio_chunks):
"""批次處理音頻片段"""
# Mac Studio 有足夠記憶體進行大批次處理
batches = [
audio_chunks[i:i + self.batch_size]
for i in range(0, len(audio_chunks), self.batch_size)
]
results = []
for batch in batches:
# 批次推理(充分利用 GPU
batch_tensor = torch.stack(batch).to(self.device)
with torch.no_grad():
outputs = self.model(batch_tensor)
results.extend(outputs.cpu())
return results
```
### 3. 模型預載入與快取
```python
class ModelCache:
"""Mac Studio 模型快取"""
_instance = None
_models = {}
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
# Mac Studio 有足夠記憶體,預載入所有常用模型
cls._preload_all_models()
return cls._instance
@classmethod
def _preload_all_models(cls):
"""預載入所有模型到記憶體"""
models_to_load = [
("tiny", whisperx.load_model("tiny", device="mps")),
("base", whisperx.load_model("base", device="mps")),
("small", whisperx.load_model("small", device="mps")),
("medium", whisperx.load_model("medium", device="mps")),
("large-v3", whisperx.load_model("large-v3", device="mps")),
]
for name, model in models_to_load:
cls._models[name] = model
print(f"[ModelCache] Loaded {name} model")
print(f"[ModelCache] Total models loaded: {len(cls._models)}")
def get_model(self, name: str):
"""取得模型(已預載入)"""
return self._models.get(name)
```
---
## 處理時間對比(實際預估)
### 場景 1會議記錄30分鐘
```
M4 Mini 16GB:
ASR tiny: 120s
ASRX base: 300s
ASRX large: 900s (15分鐘)
Mac Studio 64GB:
ASR tiny: 60s
ASRX base: 150s
ASRX large: 270s (4.5分鐘) ✅
Mac Studio 128GB:
ASR tiny: 40s
ASRX base: 100s
ASRX large: 180s (3分鐘) ✅✅
```
### 場景 2完整影片處理管道
```
影片: 30分鐘
處理器: ASR + OCR + YOLO + Face + Pose + Scene
M4 Mini 16GB (串行):
總時間: ~45分鐘
Mac Studio 64GB (並行):
總時間: ~15分鐘 ✅ (3x 提升)
Mac Studio 128GB (並行):
總時間: ~8分鐘 ✅✅ (5.6x 提升)
```
---
## 成本效益分析
### 硬體投資回報
| 項目 | M4 Mini 16GB | Mac Studio 64GB | 差異 |
|------|--------------|----------------|------|
| **硬體成本** | $699 | $3,199 | +$2,500 |
| **處理能力** | 基準 | 3.3x | +230% |
| **並行能力** | 無 | 4-6 個處理器 | ✅ |
| **大型模型** | 受限 | 完全支援 | ✅ |
| **用戶體驗** | 等待 | 即時 | ✅ |
### 使用壽命分析
```
假設每日處理量: 20 部影片(平均 30分鐘
M4 Mini 16GB:
每日處理時間: 15小時
硬體壽命: 3-4年
Mac Studio 64GB:
每日處理時間: 5小時
硬體壽命: 5-6年負載低
投資回報:
2.5年內回本(時間價值 + 用戶體驗)
```
---
## 最終建議
### ✅ 強烈建議統一為 ASRXMac Studio
**新架構**
```python
# config/audio_processor_config.json
{
"hardware": "mac_studio",
"default_profile": "professional",
"profiles": {
"fast": {
"model": "tiny",
"diarization": false,
"description": "快速預覽(緊急情況)"
},
"standard": {
"model": "base",
"diarization": false,
"description": "標準轉錄(向下兼容)"
},
"professional": {
"model": "large-v3",
"diarization": true,
"description": "專業處理(預設)"
}
},
"optimization": {
"device": "mps",
"compute_type": "float16",
"batch_size": 16,
"num_workers": 4,
"preload_models": ["large-v3", "base"]
}
}
```
### 實施步驟
#### Phase 1Mac Studio 部署準備(立即)
```bash
# 1. 創建統一處理器
scripts/audio_processor_unified.py
# 2. Mac Studio 優化配置
config/mac_studio_optimizations.json
# 3. 模型預下載腳本
scripts/download_all_models.py
```
#### Phase 2統一處理器實現第一週
```python
# 替代現有的 ASR 和 ASRX
class UnifiedAudioProcessor:
"""
Mac Studio 優化版
預設使用 large-v3 + 說話人分離
"""
def __init__(self):
self.model = self._load_model("large-v3")
self.diarization = True
self.alignment = True
```
#### Phase 3並行處理優化第二週
```python
# Mac Studio 多處理器並行
class ParallelVideoProcessor:
def process_all(self, file_uuid):
# 同時運行所有處理器
with ThreadPoolExecutor(max_workers=8) as executor:
futures = {
"audio": executor.submit(self.run_asrx, file_uuid),
"ocr": executor.submit(self.run_ocr, file_uuid),
"yolo": executor.submit(self.run_yolo, file_uuid),
"face": executor.submit(self.run_face, file_uuid),
"pose": executor.submit(self.run_pose, file_uuid),
"scene": executor.submit(self.run_scene, file_uuid)
}
return {k: f.result() for k, f in futures.items()}
```
#### Phase 4API 更新(第三週)
```bash
# 新 API 端點
POST /api/v1/process
{
"file_uuid": "...",
"processors": ["audio"], # 統一使用 ASRX large
"mode": "auto" # 或 "fast" / "professional"
}
# 向下兼容
POST /api/v1/process
{
"file_uuid": "...",
"processors": ["asr"] # 自動映射到 "standard" profile
}
```
---
## Mac Studio 部署清單
### 硬體建議
```
推薦配置: Mac Studio M4 Max 64GB
├─ CPU: 14核心
├─ GPU: 30核心
├─ 記憶體: 64GB Unified Memory
├─ 儲存: 1TB SSD
└─ 價格: ~$3,199
理由:
✅ 64GB 記憶體足夠運行所有大型模型
✅ M4 Max GPU 性能強大
✅ 可並行 4-6 個處理器
✅ 價格合理
```
### 軟體環境
```bash
# macOS 版本
macOS 15.0+ (Sequoia)
# Python 環境
Python 3.11+
PyTorch 2.0+ (MPS support)
whisperx 3.1+
# 系統配置
ulimit -n 65536 # 提高文件描述符限制
sudo sysctl -w vm.loadavg=0 # 優化記憶體管理
```
### 模型儲存
```
/Users/accusys/momentry/models/
├── audio/
│ ├── whisperx_tiny.pt (75MB)
│ ├── whisperx_base.pt (150MB)
│ ├── whisperx_small.pt (500MB)
│ ├── whisperx_medium.pt (1.5GB)
│ ├── whisperx_large_v3.pt (3GB)
│ ├── alignment_model_zh.pt (350MB)
│ ├── alignment_model_en.pt (350MB)
│ └── diarization_model.pt (500MB)
├── scene/
│ └── resnet18_places365.pth.tar (43MB)
├── yolo/
│ └── yolov8x.pt (200MB)
└── pose/
└── pose_model.pt (100MB)
總計: ~6.5GB
```
---
## 性能基準測試計劃
### Mac Studio 到達後立即測試
```bash
# 1. 記憶體測試
python3 scripts/test_memory_capacity.py
# 2. MPS 加速測試
python3 scripts/test_mps_acceleration.py
# 3. 並行處理測試
python3 scripts/test_parallel_processing.py
# 4. 完整管道測試
python3 scripts/test_full_pipeline_mac_studio.py
# 5. 長時間穩定性測試
python3 scripts/test_stability_24h.py
```
---
## 總結
### Mac Studio 改變了什麼?
| 因素 | M4 Mini 16GB | Mac Studio 64GB |
|------|--------------|----------------|
| **記憶體限制** | ⚠️ 限制大型模型 | ✅ 無限制 |
| **處理速度** | ⚠️ 較慢 | ✅ 3-5x 提升 |
| **並行能力** | ❌ 無 | ✅ 4-6 個處理器 |
| **用戶體驗** | ⚠️ 需等待 | ✅ 接近即時 |
| **維護複雜度** | ⚠️ 需優化 | ✅ 簡化 |
### 最終決策
**✅ Mac Studio 到達後,統一為 ASRX**
**理由**
1. ✅ 硬體資源充足64GB+ RAM
2. ✅ 效能提升 3-5 倍
3. ✅ 可並行處理
4. ✅ 功能完整(說話人分離)
5. ✅ 用戶體驗極佳
6. ✅ 維護簡化(單一處理器)
**時間表**
- **立即**:準備統一處理器架構
- **Mac Studio 到達**:部署新架構
- **第一週**:性能測試與優化
- **第二週**:全面啟用 ASRX large-v3
**預期效果**
- 處理速度:提升 3-5 倍
- 用戶等待時間:減少 70-80%
- 維護成本:降低 50%
- 功能完整性100%(所有功能啟用)

View File

@@ -1,505 +0,0 @@
---
document_type: "architecture_design"
service: "MOMENTRY_CORE"
title: "自實作 ASRX說話人分離可行性分析"
date: "2026-04-02"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
ai_query_hints:
- "查詢 自實作 ASRX說話人分離可行性分析 的內容"
- "自實作 ASRX說話人分離可行性分析 的主要目的是什麼?"
- "如何操作或實施 自實作 ASRX說話人分離可行性分析"
---
# 自實作 ASRX說話人分離可行性分析
**分析日期**: 2026-04-02
**目標**: 使用聲紋特徵提取實現說話人分離
---
## 🎯 目標定義
**輸入**: 影片音頻(已通過 ASR 轉錄)
**輸出**: 每個語音段的說話人 ID
**準確度目標**: 85%+
**處理時間**: < 5 分鐘114 分鐘影片)
---
## 📊 技術方案比較
### 方案 1: 聲紋嵌入Speaker Embedding
**原理**:
```
音頻 → 聲紋特徵提取 → 嵌入向量 → 聚類 → 說話人 ID
```
**常用模型**:
- **ECAPA-TDNN** (SOTA, 準確度最高)
- **x-vector** (經典,穩定)
- **d-vector** (Google, 輕量)
- **ResNet34** (簡單,快速)
**優點**:
- ✅ 準確度高85-95%
- ✅ 成熟方案
- ✅ 有預訓練模型
**缺點**:
- ⚠️ 需要額外模型50-100MB
- ⚠️ 需要聚類算法
**實施難度**: ⭐⭐⭐ (中)
---
### 方案 2: 音頻特徵 + 機器學習
**原理**:
```
音頻 → MFCC/Mel 頻譜 → 特徵向量 → ML 模型 → 說話人 ID
```
**特徵提取**:
- MFCC (Mel-frequency cepstral coefficients)
- Mel Spectrogram
- Chroma features
- Spectral contrast
**分類模型**:
- GMM (Gaussian Mixture Model)
- HMM (Hidden Markov Model)
- K-Means 聚類
- DBSCAN 聚類
**優點**:
- ✅ 不需要深度學習模型
- ✅ 輕量級
- ✅ 可解釋性強
**缺點**:
- ❌ 準確度較低70-80%
- ❌ 需要手動設計特徵
**實施難度**: ⭐⭐ (低中)
---
### 方案 3: 端到端說話人分離
**原理**:
```
音頻 → 神經網絡 → 說話人標籤(序列到序列)
```
**模型**:
- **SpeakerNet**
- **DiarizationNet**
- **EEND** (End-to-End Neural Diarization)
**優點**:
- ✅ 準確度最高90%+
- ✅ 端到端訓練
- ✅ 可處理重疊說話
**缺點**:
- ❌ 模型大200MB+
- ❌ 需要大量訓練數據
- ❌ 實施複雜
**實施難度**: ⭐⭐⭐⭐⭐ (高)
---
## 🔍 推薦方案:聲紋嵌入 + 聚類
### 技術架構
```
音頻輸入
[1] 語音活動檢測 (VAD)
[2] 語音片段提取 (1-3 秒/段)
[3] 聲紋特徵提取 (ECAPA-TDNN)
[4] 嵌入向量 (192-512 維)
[5] 降維 (PCA, 可選)
[6] 聚類 (Spectral Clustering / Agglomerative)
[7] 說話人 ID 分配
輸出結果
```
---
### 核心組件
#### 1. 語音活動檢測 (VAD)
**選項**:
- **WebRTC VAD** (快速,準確)
- **pyannote VAD** (準確,慢)
- **Silero VAD** (準確,快速) ⭐
**推薦**: Silero VAD
- GitHub: https://github.com/snakers4/silero-vad
- 模型大小:~2MB
- 準確度95%+
- 速度:實時
---
#### 2. 聲紋特徵提取
**選項**:
- **speechbrain** (ECAPA-TDNN) ⭐
- **resemblyzer** (輕量)
- **TorchAudio** (內建模組)
**推薦**: SpeechBrain ECAPA-TDNN
- GitHub: https://github.com/speechbrain/speechbrain
- 模型大小:~80MB
- 嵌入維度192 維
- 準確度90%+ (VoxCeleb1)
**程式碼範例**:
```python
from speechbrain.inference.speaker import EncoderClassifier
# 載入模型
classifier = EncoderClassifier.from_hparams(
source="speechbrain/spkrec-ecapa-voxceleb"
)
# 提取聲紋嵌入
embeddings = classifier.encode_batch(audio_waveform)
# 輸出:[batch_size, 192]
```
---
#### 3. 聚類算法
**選項**:
- **Spectral Clustering** (準確度高) ⭐
- **Agglomerative Clustering** (穩定)
- **DBSCAN** (自動決定聚類數)
- **K-Means** (需要指定 K)
**推薦**: Spectral Clustering
- 準確度高
- 自動決定聚類數
- 適合聲紋數據
**程式碼範例**:
```python
from sklearn.cluster import SpectralClustering
# 計算相似度矩陣
similarity_matrix = cosine_similarity(embeddings)
# 譜聚類
clustering = SpectralClustering(
n_clusters=None, # 自動決定
affinity='precomputed',
assign_labels='kmeans'
)
speaker_labels = clustering.fit_predict(similarity_matrix)
```
---
## 💻 實作計畫
### 階段 1: 基礎架構2-3 小時)
**任務**:
1. 安裝依賴
```bash
pip install speechbrain silero-vad scikit-learn
```
2. 創建基礎腳本
- `vad_processor.py` - 語音活動檢測
- `speaker_encoder.py` - 聲紋特徵提取
- `speaker_cluster.py` - 聚類算法
3. 測試短影片2-3 分鐘)
---
### 階段 2: 整合測試2-3 小時)
**任務**:
1. 整合 VAD + 聲紋 + 聚類
2. 測試長影片114 分鐘)
3. 優化效能
**預期結果**:
- 準確度80-85%
- 處理時間:< 10 分鐘
---
### 階段 3: 優化與驗證2-3 小時)
**任務**:
1. 調整聚類參數
2. 添加後處理(平滑說話人標籤)
3. 與 pyannote.audio 比較準確度
**預期結果**:
- 準確度85%+
- 處理時間:< 5 分鐘
---
## 📊 預期效能
### 準確度預估
| 場景 | 預期準確度 | 說明 |
|------|-----------|------|
| **雙人對話** | 90-95% | 清晰區分 |
| **三人會議** | 85-90% | 良好區分 |
| **多人會議** | 80-85% | 基本區分 |
| **重疊說話** | 70-80% | 較困難 |
---
### 處理時間預估
**114 分鐘影片**:
| 階段 | 預估時間 | 說明 |
|------|---------|------|
| VAD | ~2 分鐘 | 實時處理 |
| 聲紋提取 | ~5 分鐘 | GPU 加速 |
| 聚類 | ~1 分鐘 | 快速 |
| **總計** | **~8 分鐘** | 7.6x 實時 |
**優化後**(並行處理):
- **總計**: ~5 分鐘13x 實時)
---
## 🔧 實作細節
### 腳本結構
```
scripts/
├── asrx_self/
│ ├── __init__.py
│ ├── vad.py # 語音活動檢測
│ ├── speaker_encoder.py # 聲紋特徵提取
│ ├── speaker_cluster.py # 聚類算法
│ ├── post_process.py # 後處理
│ └── main.py # 主流程
├── test_asrx_self.py # 測試腳本
└── compare_asrx.py # 與 pyannote 比較
```
---
### 主流程程式碼
```python
#!/opt/homebrew/bin/python3.11
"""
自實作 ASRX - 說話人分離
使用聲紋嵌入 + 譜聚類
"""
import torch
import numpy as np
from speechbrain.inference.speaker import EncoderClassifier
from silero_vad import load_silero_vad, read_audio
from sklearn.cluster import SpectralClustering
from sklearn.metrics.pairwise import cosine_similarity
class SelfASRX:
def __init__(self):
# 載入 VAD 模型
self.vad = load_silero_vad()
# 載入聲紋模型
self.speaker_encoder = EncoderClassifier.from_hparams(
source="speechbrain/spkrec-ecapa-voxceleb"
)
def process(self, audio_path):
"""處理音頻文件"""
# 1. VAD - 提取語音片段
speech_segments = self.extract_speech_segments(audio_path)
# 2. 聲紋特徵提取
embeddings = []
for segment in speech_segments:
emb = self.speaker_encoder.encode_batch(segment)
embeddings.append(emb)
embeddings = np.vstack(embeddings) # [n_segments, 192]
# 3. 譜聚類
similarity = cosine_similarity(embeddings)
# 自動決定聚類數(使用特徵值間隙)
n_speakers = self.estimate_n_speakers(similarity)
clustering = SpectralClustering(
n_clusters=n_speakers,
affinity='precomputed',
random_state=42
)
speaker_labels = clustering.fit_predict(similarity)
# 4. 後處理(平滑標籤)
speaker_labels = self.smooth_labels(speaker_labels)
return speaker_labels, n_speakers
def extract_speech_segments(self, audio_path):
"""使用 VAD 提取語音片段"""
# 實作 VAD 邏輯
pass
def estimate_n_speakers(self, similarity):
"""估計說話人數量"""
# 使用特徵值間隙方法
pass
def smooth_labels(self, labels, window=3):
"""平滑說話人標籤"""
# 中值濾波
pass
if __name__ == "__main__":
asrx = SelfASRX()
labels, n_speakers = asrx.process("audio.wav")
print(f"檢測到 {n_speakers} 個說話人")
print(f"標籤:{labels}")
```
---
## 📈 與現有方案比較
| 方案 | 準確度 | 處理時間 | 模型大小 | 實施難度 |
|------|--------|---------|---------|---------|
| **pyannote.audio** | 90-95% | ~10 分鐘 | ~100MB | ⭐ (簡單) |
| **自實作 (ECAPA)** | 85-90% | ~5 分鐘 | ~80MB | ⭐⭐⭐ (中) |
| **自實作 (MFCC)** | 70-80% | ~3 分鐘 | ~10MB | ⭐⭐ (低中) |
| **Face + ASR** | 66% | ~2 分鐘 | 無額外 | ⭐ (簡單) |
---
## ✅ 可行性評估
### 技術可行性:✅ 高
- ✅ 有成熟開源模型
- ✅ 有預訓練權重
- ✅ 技術文檔完善
### 經濟可行性:✅ 高
- ✅ 開源免費
- ✅ 不需要雲端 API
- ✅ 本地運行
### 時間可行性:⚠️ 中
- ⏱️ 實施時間6-9 小時
- ⏱️ 測試時間2-3 小時
- ⏱️ 優化時間2-3 小時
- **總計**: 10-15 小時
### 準確度可行性:✅ 高
- ✅ 預期 85-90%
- ✅ 接近 pyannote.audio90-95%
- ✅ 遠勝 Face+ASR66%
---
## 🎯 最終建議
### 推薦實施
**理由**:
1. ✅ 準確度可達 85-90%
2. ✅ 處理時間 5-8 分鐘
3. ✅ 不需要 HuggingFace token
4. ✅ 完全本地運行
5. ✅ 可自定義優化
**實施步驟**:
1. 安裝 speechbrain + silero-vad
2. 創建基礎腳本
3. 測試短影片
4. 優化長影片
5. 與 pyannote 比較
---
### 不推薦的情況
**如果**:
- ❌ 需要 95%+ 準確度
- ❌ 需要處理重疊說話
- ❌ 時間非常緊張(<1 小時)
**建議**: 使用 pyannote.audio需 HuggingFace token
---
## 📋 下一步行動
### 立即實施
```bash
# 1. 安裝依賴
pip install speechbrain silero-vad scikit-learn
# 2. 創建目錄結構
mkdir -p scripts/asrx_self
# 3. 創建基礎腳本
# (見上方程式碼範例)
# 4. 測試
python3 scripts/asrx_self/main.py test_audio.wav
```
### 預期時間表
| 時間 | 任務 | 交付 |
|------|------|------|
| 第 1-2 小時 | 安裝 + 基礎架構 | 可運行腳本 |
| 第 3-4 小時 | 整合測試 | 短影片結果 |
| 第 5-6 小時 | 長影片測試 | 長影片結果 |
| 第 7-8 小時 | 優化 + 文檔 | 完整報告 |
---
**結論**: ✅ **建議實施**
自實作 ASRX 在技術、經濟、準確度上都可行,預期可達 85-90% 準確度,處理時間 5-8 分鐘,是值得投入的改進方向。
---
**報告完成**: 2026-04-02
**建議**: 立即開始實施

View File

@@ -1,328 +0,0 @@
---
document_type: "architecture_design"
service: "MOMENTRY_CORE"
title: "自實作 ASRX 長影片測試報告"
date: "2026-04-02"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "長影片測試報告"
- "asrx"
ai_query_hints:
- "查詢 自實作 ASRX 長影片測試報告 的內容"
- "自實作 ASRX 長影片測試報告 的主要目的是什麼?"
- "如何操作或實施 自實作 ASRX 長影片測試報告?"
---
# 自實作 ASRX 長影片測試報告
**測試日期**: 2026-04-02
**測試影片**: Charade 1963 (114.7 分鐘)
---
## 📊 測試結果摘要
| 指標 | 結果 | 評分 |
|------|------|------|
| **影片時長** | 114.7 分鐘 (6879 秒) | - |
| **語音片段數** | 1118 段 | ✅ |
| **檢測到說話人** | 2 人 | ✅ |
| **處理時間** | 45.30 秒 | ✅ |
| **實時比** | **151.86x** | ✅✅✅ |
| **VAD 時間** | 15.83 秒 (35%) | ✅ |
| **聲紋提取時間** | 29.28 秒 (65%) | ✅ |
| **聚類時間** | 0.14 秒 (<1%) | ✅ |
---
## 🎯 處理流程時間分解
| 步驟 | 時間 | 百分比 | 說明 |
|------|------|--------|------|
| **VAD 語音檢測** | 15.83s | 35.0% | Silero VAD |
| **聲紋特徵提取** | 29.28s | 64.6% | ECAPA-TDNN (1118 片段) |
| **相似度計算** | 0.01s | 0.0% | 餘弦相似度 |
| **譜聚類** | 0.14s | 0.3% | 使用 fallback |
| **後處理** | 0.04s | 0.1% | 標籤平滑 |
| **總計** | **45.30s** | **100%** | **151.86x 實時** |
---
## 📈 說話人統計
| 說話人 | 片段數 | 總時長 | 百分比 |
|--------|--------|--------|--------|
| **SPEAKER_0** | 559 段 | 1413.8s | 20.6% |
| **SPEAKER_1** | 559 段 | 1586.9s | 23.1% |
| **靜音/背景** | - | 3878.6s | 56.4% |
**觀察**:
- 兩個說話人片段數相同(各 559 段)
- SPEAKER_1 說話時間稍長1586.9s vs 1413.8s
- 56.4% 是靜音或背景音(電影正常現象)
---
## 🔍 與短影片比較
### 短影片 vs 長影片
| 指標 | 短影片 (2.6min) | 長影片 (114.7min) | 倍率 |
|------|----------------|------------------|------|
| **語音片段** | 26 段 | 1118 段 | 43x |
| **處理時間** | 1.66s | 45.30s | 27x |
| **實時比** | 96x | 152x | **1.6x 更快** ✅ |
| **說話人數** | 2 人 | 2 人 | 相同 |
**觀察**:
- 長影片處理效率更高152x vs 96x
- 線性擴展良好43x 片段 → 27x 時間)
- 系統穩定性良好
---
## ⚠️ 技術問題與解決方案
### 問題 1: 相似度矩陣 NaN 值
**現象**:
```
RuntimeWarning: invalid value encountered in matmul
ValueError: Input contains NaN.
```
**原因**:
- 大量嵌入向量計算時產生數值不穩定
- 矩陣乘法溢出
**解決方案**:
```python
# 清洗數據
embeddings = np.nan_to_num(embeddings, nan=0.0, posinf=0.0, neginf=0.0)
similarity_matrix = np.nan_to_num(similarity_matrix, nan=0.5)
np.fill_diagonal(similarity_matrix, 1.0)
similarity_matrix = np.clip(similarity_matrix, -1.0, 1.0)
```
---
### 問題 2: 譜聚類失敗
**現象**:
```
[Clustering] Spectral clustering failed: Input contains NaN.
```
**解決方案**:
```python
# Fallback: 簡單分配
speaker_labels = np.array(
[0] * (n_segments // 2) +
[1] * (n_segments - n_segments // 2)
)
```
**影響**:
- ⚠️ 說話人標籤是隨機分配(前一半 SPEAKER_0後一半 SPEAKER_1
- ✅ 系統仍然完成處理
- ✅ 檢測到正確說話人數量2 人)
---
## 📊 性能分析
### 實時比分析
**短影片**: 96x 實時
**長影片**: 152x 實時
**原因**:
1. **模型載入只一次**: 固定成本攤薄
2. **批次處理效率**: 大量數據更有效率
3. **記憶體優化**: 長影片更能體現優化效果
---
### 瓶頸分析
| 組件 | 時間 | 瓶頸 | 優化空間 |
|------|------|------|---------|
| **VAD** | 15.83s | CPU | ⚠️ 中 |
| **聲紋提取** | 29.28s | CPU | ✅ 大 (GPU 加速) |
| **相似度** | 0.01s | - | ❌ 無 |
| **聚類** | 0.14s | - | ❌ 無 |
**主要瓶頸**: 聲紋提取 (64.6%)
**優化建議**:
1. GPU 加速(預計 5-10x 提升)
2. 批次處理優化
3. 模型量化INT8
---
## 🎯 準確度評估
### VAD 準確度
**檢測到 1118 個語音片段**
**觀察**:
- 114.7 分鐘電影 → 1118 段對話
- 平均每段 6.2 秒
- 合理(電影對話節奏)
---
### 說話人分離準確度
**使用 fallback 分配**:
**優點**:
- ✅ 系統完成處理
- ✅ 檢測到正確說話人數量
**缺點**:
- ❌ 標籤是隨機分配
- ❌ 無法準確區分說話者
- ⚠️ 需要修復譜聚類
---
## 💡 改進建議
### 短期(立即實施)
1. **修復譜聚類 NaN 問題**
- 添加更多數值穩定性檢查
- 使用更穩定的聚類算法
2. **添加日誌記錄**
- 記錄每個步驟的詳細資訊
- 方便除錯和優化
3. **添加進度條**
- 長影片處理時顯示進度
- 提升用戶體驗
---
### 中期1-2 週)
1. **GPU 加速**
- 聲紋提取 GPU 化
- 預計 5-10x 速度提升
2. **模型優化**
- 使用更輕量的聲紋模型
- 模型量化INT8
3. **重疊說話檢測**
- 添加重疊說話識別
- 提升準確度
---
### 長期1 個月+
1. **端到端優化**
- 整合 VAD + 聲紋 + 聚類
- 減少數據複製
2. **分散式處理**
- 多 GPU 並行
- 雲端部署
3. **準確度驗證**
- 與 pyannote.audio 對比
- 人工標註驗證
---
## 📋 測試檔案
### 輸入檔案
```
/tmp/charade_audio.wav
- 大小209.9 MB
- 時長114.7 分鐘
- 採樣率16kHz
- 單聲道
```
### 輸出檔案
```
/tmp/asrx_charade_result.json
- 大小:~200 KB
- 內容1118 個語音片段
- 說話人2 人
```
### 日誌檔案
```
/tmp/asrx_charade_log.txt
- 完整處理日誌
- 包含所有警告和錯誤
```
---
## ✅ 測試結論
### 成功項目
-**處理完成**: 114.7 分鐘影片成功處理
-**速度極快**: 152x 實時45.3 秒)
-**穩定性**: 系統崩潰後自動恢復
-**擴展性**: 長影片效率更高
---
### 待改進項目
- ⚠️ **譜聚類 NaN**: 需要修復數值穩定性
- ⚠️ **Fallback 分配**: 需要準確的聚類算法
- ⚠️ **準確度驗證**: 需要與 ground truth 對比
---
### 最終評分
| 項目 | 評分 | 說明 |
|------|------|------|
| **速度** | ⭐⭐⭐⭐⭐ | 152x 實時,極快 |
| **穩定性** | ⭐⭐⭐⭐ | 有 fallback 機制 |
| **準確度** | ⭐⭐⭐ | Fallback 分配,待驗證 |
| **擴展性** | ⭐⭐⭐⭐⭐ | 長影片效率更高 |
| **易用性** | ⭐⭐⭐⭐ | 簡單,無需 token |
**總評**: ⭐⭐⭐⭐ (4/5)
---
## 📁 創建的文件
```
scripts/asrx_self/
├── vad.py # VAD 語音檢測
├── speaker_encoder.py # 聲紋提取(已修復 NaN
├── speaker_cluster.py # 譜聚類(已添加 fallback
└── main.py # 主流程
docs_v1.0/ARCHITECTURE/
├── ASRX_SELF_LONG_MOVIE_TEST_REPORT.md # 本報告 ⭐
── ASRX_SELF_VS_PYANNOTE_COMPARISON.md # 短影片比較
└── ASRX_SELF_IMPLEMENTATION_FEASIBILITY.md # 可行性分析
```
---
**測試完成**: 2026-04-02
**狀態**: ✅ 長影片測試通過152x 實時)
**下一步**: 修復譜聚類 NaN 問題,提升準確度

View File

@@ -1,275 +0,0 @@
---
document_type: "architecture_design"
service: "MOMENTRY_CORE"
title: "自實作 ASRX 長影片測試報告(修復版)"
date: "2026-04-02"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "asrx"
ai_query_hints:
- "查詢 自實作 ASRX 長影片測試報告(修復版) 的內容"
- "自實作 ASRX 長影片測試報告(修復版) 的主要目的是什麼?"
- "如何操作或實施 自實作 ASRX 長影片測試報告(修復版)?"
---
# 自實作 ASRX 長影片測試報告(修復版)
**測試日期**: 2026-04-02
**測試影片**: Charade 1963 (114.7 分鐘)
**修復內容**: 譜聚類 NaN 問題 → 層次聚類
---
## 📊 測試結果摘要
| 指標 | 結果 | 評分 |
|------|------|------|
| **影片時長** | 114.7 分鐘 (6879 秒) | - |
| **語音片段數** | 1118 段 | ✅ |
| **檢測到說話人** | **8 人** | ✅✅✅ |
| **處理時間** | 45.39 秒 | ✅ |
| **實時比** | **151.58x** | ✅✅✅ |
---
## 🎯 說話人分佈(修復後)
| 說話人 | 片段數 | 總時長 | 百分比 | 角色推測 |
|--------|--------|--------|--------|---------|
| **SPEAKER_0** | 654 段 | 1764.4s | 25.6% | 主要演員(如 Cary Grant |
| **SPEAKER_1** | 403 段 | 1119.4s | 16.3% | 主要演員(如 Audrey Hepburn |
| **SPEAKER_2** | 49 段 | 65.7s | 1.0% | 配角 |
| **SPEAKER_4** | 3 段 | 44.1s | 0.6% | 配角 |
| **SPEAKER_3,5,6,7** | 2-3 段 | <3s | <0.1% | 臨時演員/背景 |
**觀察**:
- ✅ 2 個主要說話人SPEAKER_0 + SPEAKER_1佔 41.9%
- ✅ 1 個配角SPEAKER_2佔 1.0%
- ✅ 其他為臨時演員或背景對話
- ✅ 符合電影實際情況
---
## 🔍 修復前後比較
### 問題:譜聚類 NaN
**修復前**:
```
檢測到說話人2 人(錯誤)
SPEAKER_0: 559 段 (50%)
SPEAKER_1: 559 段 (50%)
```
**問題**: 簡單將片段分成兩半,完全不準確
---
**修復後**:
```
檢測到說話人8 人(合理)
SPEAKER_0: 654 段 (58.5%)
SPEAKER_1: 403 段 (36.0%)
SPEAKER_2: 49 段 (4.4%)
...其他配角
```
**改進**: 使用層次聚類,準確檢測多個說話人
---
## 📈 技術改進
### 改進 1: 層次聚類代替譜聚類
**原因**:
- 譜聚類:數值不穩定,容易產生 NaN
- 層次聚類:穩定可靠,適合聲紋數據
**算法**:
```python
from sklearn.cluster import AgglomerativeClustering
clustering = AgglomerativeClustering(
n_clusters=n_speakers,
metric='cosine',
linkage='average' # 平均連接
)
```
---
### 改進 2: 自動估計說話人數量
**方法**: 距離閾值估計
**原理**:
```
1. 計算所有樣本的最近鄰距離
2. 使用平均距離的 1.5 倍作為閾值
3. 距離小於閾值的視為同一人
```
**結果**:
- 自動估計8 個說話人
- 符合電影實際情況
---
### 改進 3: 數據清洗與正規化
**流程**:
```python
# 1. 清洗 NaN/Inf
embeddings = np.nan_to_num(embeddings, nan=0.0)
# 2. L2 正規化
embeddings = normalize(embeddings, norm='l2')
# 3. 再次清洗
embeddings = np.nan_to_num(embeddings, nan=0.0)
```
**效果**: 完全避免 NaN 問題
---
## 🎬 Charade 1963 電影分析
### 實際演員陣容
**主要演員**:
- Cary Grant男主角
- Audrey Hepburn女主角
- Walter Matthau配角
- James Coburn配角
- George Kennedy配角
**預期說話人分佈**:
- 2 個主要演員:~40-50%
- 3-5 個配角:~10-20%
- 其他:~30-40%(背景、臨時演員)
---
### 檢測結果對比
| 說話人 | 檢測百分比 | 預期百分比 | 匹配度 |
|--------|-----------|-----------|--------|
| SPEAKER_0 | 25.6% | ~20-25% | ✅ 良好 |
| SPEAKER_1 | 16.3% | ~15-20% | ✅ 良好 |
| SPEAKER_2 | 1.0% | ~5-10% | ⚠️ 偏低 |
| 其他 | 1.1% | ~5% | ⚠️ 偏低 |
**觀察**:
- ✅ 主要演員檢測準確
- ⚠️ 配角可能被歸類到主要演員
- ⚠️ 需要更細緻的聚類
---
## 📊 性能比較
### 修復前 vs 修復後
| 指標 | 修復前 | 修復後 | 改進 |
|------|--------|--------|------|
| **說話人數** | 2錯誤 | 8合理 | ✅ |
| **準確度** | 50%(隨機分配) | 85%+(估計) | ✅ |
| **處理時間** | 45.30s | 45.39s | 無影響 |
| **實時比** | 151.86x | 151.58x | 無影響 |
| **穩定性** | ⚠️ 會崩潰 | ✅ 穩定 | ✅ |
---
## 💡 使用建議
### 參數調整
**一般對話**(會議、訪談):
```bash
python3 main_fixed.py audio.wav --max-speakers 5
```
**電影/電視劇**:
```bash
python3 main_fixed.py movie.wav --max-speakers 10
```
**多人會議**:
```bash
python3 main_fixed.py meeting.wav --max-speakers 15
```
---
### 準確度優化
**提高準確度**:
1. 降低 `max_speakers`(避免過度聚類)
2. 調整距離閾值(從 1.5 倍改為 1.2 倍)
3. 使用更長的語音片段min_speech_duration
**提高召回率**:
1. 增加 `max_speakers`
2. 提高距離閾值(從 1.5 倍改為 2.0 倍)
3. 使用更短的語音片段
---
## ✅ 測試結論
### 成功項目
-**修復 NaN 問題**: 使用層次聚類
-**準確檢測說話人**: 8 人(符合電影實際)
-**保持高速**: 152x 實時
-**穩定性**: 無崩潰
-**主要演員識別**: SPEAKER_0 (25.6%) + SPEAKER_1 (16.3%)
---
### 待改進項目
- ⚠️ **配角識別**: 可能被歸類到主要演員
- ⚠️ **準確度驗證**: 需要 ground truth 對比
- ⚠️ **重疊說話**: 尚未支援
---
### 最終評分
| 項目 | 評分 | 說明 |
|------|------|------|
| **速度** | ⭐⭐⭐⭐⭐ | 152x 實時 |
| **準確度** | ⭐⭐⭐⭐ | 85%+(估計) |
| **穩定性** | ⭐⭐⭐⭐⭐ | 無崩潰 |
| **靈活性** | ⭐⭐⭐⭐⭐ | 參數可調 |
| **易用性** | ⭐⭐⭐⭐⭐ | 無需 token |
**總評**: ⭐⭐⭐⭐⭐ (5/5) - **修復完成!**
---
## 📁 創建的文件
```
scripts/asrx_self/
├── vad.py # VAD 語音檢測
├── speaker_encoder.py # 聲紋提取(已修復 NaN
├── speaker_cluster.py # 譜聚類(舊版)
├── speaker_cluster_fixed.py # 層次聚類(新版)⭐
├── main.py # 舊版主流程
└── main_fixed.py # 新版主流程 ⭐
docs_v1.0/ARCHITECTURE/
├── ASRX_SELF_LONG_MOVIE_TEST_REPORT.md # 舊版報告
└── ASRX_SELF_LONG_MOVIE_TEST_REPORT_FIXED.md # 新版報告 ⭐
```
---
**測試完成**: 2026-04-02
**狀態**: ✅ 修復完成,準確檢測 8 個說話人
**下一步**: 與 pyannote.audio 準確度對比,添加重疊說話檢測

View File

@@ -1,240 +0,0 @@
---
document_type: "architecture_design"
service: "MOMENTRY_CORE"
title: "自實作 ASRX vs pyannote.audio 比較報告"
date: "2026-04-02"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "asrx"
- "比較報告"
ai_query_hints:
- "查詢 自實作 ASRX vs pyannote.audio 比較報告 的內容"
- "自實作 ASRX vs pyannote.audio 比較報告 的主要目的是什麼?"
- "如何操作或實施 自實作 ASRX vs pyannote.audio 比較報告?"
---
# 自實作 ASRX vs pyannote.audio 比較報告
**測試日期**: 2026-04-02
**測試影片**: ExaSAN PCIe series (2 分 39 秒)
---
## 📊 測試結果摘要
| 指標 | 自實作 ASRX | pyannote.audio | 差異 |
|------|------------|----------------|------|
| **檢測到說話人** | 2 人 | - | - |
| **語音片段數** | 26 段 | - | - |
| **處理時間** | 1.66 秒 | ~10 秒 | **快 6x** ✅ |
| **實時比** | 96.25x | ~16x | **快 6x** ✅ |
| **模型大小** | ~80MB | ~100MB | 小 20% ✅ |
| **需要 Token** | ❌ 不需要 | ✅ 需要 | 更方便 ✅ |
---
## 🎯 自實作 ASRX 詳細結果
### 系統架構
```
音頻 → VAD (Silero) → 聲紋嵌入 (ECAPA-TDNN) → 譜聚類 → 說話人 ID
```
### 處理流程時間分解
| 步驟 | 時間 | 百分比 |
|------|------|--------|
| VAD 語音檢測 | 0.41s | 24.7% |
| 聲紋特徵提取 | 1.15s | 69.3% |
| 相似度計算 | 0.00s | 0.0% |
| 譜聚類 | 0.10s | 6.0% |
| **總計** | **1.66s** | **100%** |
---
### 說話人統計
| 說話人 | 片段數 | 總時長 | 百分比 |
|--------|--------|--------|--------|
| **SPEAKER_0** | 15 段 | 92.9s | 58.2% |
| **SPEAKER_1** | 11 段 | 28.2s | 17.7% |
| **未分類** | - | 38.5s | 24.1% |
**觀察**:
- SPEAKER_0 是主要說話者58.2%
- SPEAKER_1 是次要說話者17.7%
- 24.1% 是靜音或背景音
---
### 語音片段分佈
**前 10 段**:
```
段 0: 0.3s - 14.7s (14.4s) SPEAKER_0 ← 開場介紹
段 1: 15.1s - 18.5s (3.4s) SPEAKER_0
段 2: 18.8s - 25.9s (7.1s) SPEAKER_0
段 3: 26.3s - 27.6s (1.3s) SPEAKER_0
段 4: 28.1s - 29.8s (1.7s) SPEAKER_1 ← 第二位說話者
段 5: 30.1s - 32.0s (1.9s) SPEAKER_1
段 6: 32.4s - 34.4s (2.0s) SPEAKER_1
段 7: 35.2s - 37.5s (2.3s) SPEAKER_1
段 8: 38.2s - 40.9s (2.7s) SPEAKER_1
段 9: 41.4s - 43.2s (1.8s) SPEAKER_1
```
**觀察**:
- 前 26 秒SPEAKER_0 獨白(介紹)
- 28-49 秒SPEAKER_1 說話(可能是訪談)
- 49 秒後SPEAKER_0 繼續
---
## 🔍 技術細節
### VAD (語音活動檢測)
**模型**: Silero VAD
**準確度**: 95%+
**處理時間**: 0.41s (實時)
**參數**:
- 最小語音持續時間500ms
- 最小靜音持續時間300ms
**結果**: 檢測到 26 個語音片段
---
### 聲紋嵌入 (Speaker Embedding)
**模型**: ECAPA-TDNN (SpeechBrain)
**嵌入維度**: 192
**準確度**: EER 0.80% (VoxCeleb1)
**處理時間**: 1.15s (26 片段)
**技術來源**:
- 論文Desplanques et al. (2020), Interspeech
- 連結https://arxiv.org/abs/2005.07143
---
### 譜聚類 (Spectral Clustering)
**算法**: Spectral Clustering
**自動估計**: 特徵值間隙方法
**結果**: 估計 2 個說話人
**技術來源**:
- 譜聚類Shi & Malik (2000), IEEE TPAMI
- 連結https://ieeexplore.ieee.org/document/868688
---
## 📈 與 pyannote.audio 比較
### 優勢
| 項目 | 自實作 ASRX | pyannote.audio |
|------|------------|----------------|
| **速度** | ✅ 96x 實時 | ~16x 實時 |
| **依賴** | ✅ 無外部 API | ⚠️ 需 HuggingFace |
| **Token** | ✅ 不需要 | ⚠️ 需要 |
| **模型大小** | ✅ 80MB | ~100MB |
| **自定義** | ✅ 完全可控 | ⚠️ 黑盒子 |
---
### 劣勢
| 項目 | 自實作 ASRX | pyannote.audio |
|------|------------|----------------|
| **準確度** | ⚠️ 85-90% (預估) | ✅ 90-95% |
| **重疊說話** | ❌ 不支援 | ✅ 支援 |
| **成熟度** | ⚠️ 新實作 | ✅ 成熟穩定 |
| **文檔** | ⚠️ 自行編寫 | ✅ 完善 |
---
## 💡 使用建議
### 推薦使用自實作 ASRX 如果
- ✅ 需要快速處理96x 實時)
- ✅ 不想配置 HuggingFace token
- ✅ 需要完全控制算法
- ✅ 本地部署需求
- ✅ 接受 85-90% 準確度
---
### 推薦使用 pyannote.audio 如果
- ✅ 需要最高準確度90-95%
- ✅ 需要處理重疊說話
- ✅ 不介意配置 HuggingFace
- ✅ 需要成熟穩定方案
---
## 🎯 最終評估
### 自實作 ASRX 評分
| 項目 | 評分 | 說明 |
|------|------|------|
| **速度** | ⭐⭐⭐⭐⭐ | 96x 實時,極快 |
| **準確度** | ⭐⭐⭐⭐ | 85-90%,良好 |
| **易用性** | ⭐⭐⭐⭐ | 簡單,無需 token |
| **靈活性** | ⭐⭐⭐⭐⭐ | 完全可控 |
| **穩定性** | ⭐⭐⭐⭐ | 測試通過 |
**總評**: ⭐⭐⭐⭐ (4/5)
---
### 結論
**自實作 ASRX 成功實現**
- ✅ 基於聲紋嵌入 + 譜聚類
- ✅ 96x 實時處理速度
- ✅ 檢測到 2 個說話人
- ✅ 無需外部 API 或 token
- ✅ 完全本地運行
**與 pyannote.audio 比較**
- ✅ 速度**快 6 倍**
- ✅ 無需 HuggingFace token
- ⚠️ 準確度可能略低(待進一步測試)
- ❌ 不支援重疊說話檢測
**建議**
- **一般應用**: 使用自實作 ASRX快速、簡單
- **高準確度需求**: 使用 pyannote.audio
- **重疊說話**: 使用 pyannote.audio
---
## 📁 創建的文件
```
scripts/asrx_self/
├── __init__.py # 模組初始化
├── vad.py # VAD 語音檢測
├── speaker_encoder.py # 聲紋特徵提取
├── speaker_cluster.py # 譜聚類
└── main.py # 主流程
docs_v1.0/ARCHITECTURE/
├── ASRX_SELF_IMPLEMENTATION_FEASIBILITY.md # 可行性分析
└── ASRX_SELF_VS_PYANNOTE_COMPARISON.md # 本比較報告
```
---
**報告完成**: 2026-04-02
**狀態**: ✅ 自實作 ASRX 成功實現並測試通過

View File

@@ -1,920 +0,0 @@
# ASR/ASRX 模型與聲紋比對分析
| 項目 | 內容 |
|------|------|
| 建立者 | OpenCode |
| 建立時間 | 2026-04-06 |
| 文件版本 | V1.0 |
---
## 版本歷史
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-04-06 | 創建文件 | OpenCode | MiniMax M2.5 |
---
## 概述
本文檔詳細分析 Momentry 系統中的語音識別ASR、說話人分離ASRX和聲紋比對技術包括模型架構、性能指標和整合方案。
---
## 系統架構總覽
```
┌──────────────────────────────────────────────────────────────┐
│ Momentry 語音處理系統架構 │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ ASR │ │ ASRX │ │ Speaker │ │
│ │ Whisper │ │ WhisperX │ │ Encoder │ │
│ │ (轉錄) │ │ (分離) │ │ (聲紋) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ 輸入: 音頻/視頻 │
│ 輸出: 文字 + 時間戳 + 說話人ID + 聲紋嵌入 │
│ │
└──────────────────────────────────────────────────────────────┘
```
---
## 1. ASR (自動語音識別)
### 1.1 模型概覽
| 項目 | 規格 |
|------|------|
| **模型名稱** | Whisper (faster-whisper) |
| **開發者** | OpenAI |
| **模型類型** | Transformer Encoder-Decoder |
| **實現框架** | faster-whisper (CTranslate2) |
| **訓練數據** | 680K 小時多語言音頻 |
| **支持語言** | 99 種語言 |
| **模型大小** | 39M - 1.5B 參數 |
### 1.2 模型系列
| 模型 | 參數量 | 模型大小 | 速度 | 準確率 | 推薦場景 |
|------|--------|----------|------|--------|----------|
| **tiny** | 39M | ~40 MB | ~1x RT | ⭐⭐ | 快速預覽 |
| **base** | 74M | ~75 MB | ~1.5x RT | ⭐⭐⭐ | 一般用途 |
| **small** | 244M | ~250 MB | ~2x RT | ⭐⭐⭐⭐ | 高品質 |
| **medium** | 769M | ~800 MB | ~3x RT | ⭐⭐⭐⭐⭐ | 專業級 |
| **large-v2** | 1.5B | ~1.5 GB | ~5x RT | ⭐⭐⭐⭐⭐ | 最高精度 |
| **large-v3** | 1.5B | ~1.5 GB | ~5x RT | ⭐⭐⭐⭐⭐ | 最新版本 |
**Momentry 默認**: `tiny` (快速) 或 `base` (平衡)
### 1.3 模型架構
```
Whisper Architecture:
┌────────────────────────────────────────────┐
│ Input: Mel-spectrogram (80 dims) │
│ (30-second audio chunks) │
└──────────────┬─────────────────────────────┘
┌────────────────────────────────────────────┐
│ Encoder (Transformer Blocks) │
│ - 4-32 layers (model dependent) │
│ - Self-attention mechanism │
│ - Positional encoding (sinusoidal) │
│ - Learned positional embeddings │
└──────────────┬─────────────────────────────┘
┌────────────────────────────────────────────┐
│ Decoder (Transformer Blocks) │
│ - 4-32 layers (model dependent) │
│ - Cross-attention (encoder-decoder) │
│ - Autoregressive generation │
│ - Beam search decoding │
└──────────────┬─────────────────────────────┘
┌────────────────────────────────────────────┐
│ Output: Token sequence │
│ - Text tokens (BPE encoding) │
│ - Timestamp tokens │
│ - Special tokens (<|start|>, <|end|>) │
└────────────────────────────────────────────┘
```
### 1.4 性能指標
#### **英語識別準確率 (WER)**
| 模型 | LibriSpeech | TED-LIUM3 | Common Voice | 平均 |
|------|-------------|-----------|--------------|------|
| tiny | 7.1% | 9.2% | 12.3% | 9.5% |
| base | 5.4% | 6.8% | 9.7% | 7.3% |
| small | 3.9% | 5.2% | 7.4% | 5.5% |
| medium | 2.9% | 4.1% | 5.8% | 4.3% |
| large-v3 | **2.2%** | **3.4%** | **4.9%** | **3.5%** |
#### **中文識別準確率 (CER)**
| 模型 | AISHELL-1 | AISHELL-2 | Common Voice | 平均 |
|------|-----------|-----------|--------------|------|
| tiny | 12.5% | 14.2% | 18.3% | 15.0% |
| base | 9.2% | 10.8% | 13.6% | 11.2% |
| small | 6.8% | 8.1% | 10.2% | 8.4% |
| medium | 5.1% | 6.3% | 7.9% | 6.4% |
| large-v3 | **3.9%** | **4.8%** | **6.1%** | **4.9%** |
### 1.5 faster-whisper 優化
| 優化技術 | 效果 | 說明 |
|----------|------|------|
| **CTranslate2** | 4x 加速 | 優化推理引擎 |
| **INT8 量化** | 2x 加速 | 降低精度,維持準確率 |
| **批處理** | 3x 加速 | 並行處理多個片段 |
| **GPU 加速** | 2-5x 加速 | CUDA/MPS 支持 |
**Momentry 配置:**
```python
model = WhisperModel("tiny", device="cpu", compute_type="int8")
segments, info = model.transcribe(video_path, beam_size=5)
```
### 1.6 輸出格式
```json
{
"language": "en",
"language_probability": 0.98,
"segments": [
{
"start": 0.0,
"end": 2.5,
"text": "Hello, how are you today?"
},
{
"start": 2.5,
"end": 4.8,
"text": "I'm doing great, thank you."
}
]
}
```
---
## 2. ASRX (說話人分離)
### 2.1 模型概覽
| 項目 | 規格 |
|------|------|
| **模型名稱** | WhisperX |
| **開發者** | m-bain (Open Source) |
| **模型類型** | 多模組管線 |
| **組件數量** | 3 個模型ASR + 對齊 + 分離) |
| **支持功能** | 轉錄 + 時間戳對齊 + 說話人識別 |
| **依賴庫** | whisperx, pyannote.audio |
### 2.2 WhisperX 管線架構
```
WhisperX Pipeline:
┌────────────────────────────────────────────┐
│ Input: Audio/Video File │
└──────────────┬─────────────────────────────┘
┌────────────────────────────────────────────┐
│ Stage 1: Speech Recognition (Whisper) │
│ - Transcribe audio to text │
│ - Language detection │
│ - Segment boundaries │
│ Output: text + coarse timestamps │
└──────────────┬─────────────────────────────┘
┌────────────────────────────────────────────┐
│ Stage 2: Forced Alignment (Wav2Vec2.0) │
│ - Fine-grained word timestamps │
│ - Phonetic alignment │
│ - Language-specific models │
│ Output: word-level timestamps │
└──────────────┬─────────────────────────────┘
┌────────────────────────────────────────────┐
│ Stage 3: Speaker Diarization (pyannote) │
│ - Voice Activity Detection (VAD) │
│ - Speaker Change Detection (SCD) │
│ - Speaker Embedding (x-vector) │
│ - Spectral Clustering │
│ Output: speaker labels │
└──────────────┬─────────────────────────────┘
┌────────────────────────────────────────────┐
│ Output: Segments with Speakers │
│ - Text │
│ - Word-level timestamps │
│ - Speaker ID (SPEAKER_00, SPEAKER_01...) │
└────────────────────────────────────────────┘
```
### 2.3 說話人分離模型詳解
#### **2.3.1 Voice Activity Detection (VAD)**
| 項目 | 規格 |
|------|------|
| **模型** | pyannote/voice-activity-detection |
| **架構** | S4ND (Self-Supervised Speaker ND) |
| **訓練數據** | VoxCeleb, DIHARD, AVA |
| **準確率** | F1 = 0.96 |
| **功能** | 區分語音/非語音 |
#### **2.3.2 Speaker Change Detection (SCD)**
| 項目 | 規格 |
|------|------|
| **模型** | pyannote/speaker-change-detection |
| **架構** | PyanNet (pyannote audio neural network) |
| **功能** | 檢測說話人切換點 |
| **延遲** | < 100ms |
#### **2.3.3 Speaker Embedding (x-vector)**
| 項目 | 規格 |
|------|------|
| **模型** | pyannote/embedding |
| **架構** | x-vector (Time-Delay Neural Network) |
| **嵌入維度** | 512-D |
| **功能** | 提取說話人特徵向量 |
#### **2.3.4 Spectral Clustering**
```
說話人聚類流程:
┌────────────────────────────────────┐
│ Input: Speaker Embeddings │
│ [N segments, 512 dims] │
└──────────────┬─────────────────────┘
┌────────────────────────────────────┐
│ Compute Similarity Matrix │
│ Cosine Similarity: │
│ S[i][j] = cos(e_i, e_j) │
└──────────────┬─────────────────────┘
┌────────────────────────────────────┐
│ Estimate Number of Speakers │
│ - Eigengap method │
│ - Silhouette score │
│ - Max eigenvalue gap → n_spkrs │
└──────────────┬─────────────────────┘
┌────────────────────────────────────┐
│ Spectral Clustering │
│ 1. Compute Laplacian matrix │
│ 2. Eigenvalue decomposition │
│ 3. k-means on eigenvectors │
│ Output: speaker_labels │
└────────────────────────────────────┘
```
### 2.4 性能指標
#### **說話人分離準確率 (DER)**
| 指標 | 說明 | 數值 |
|------|------|------|
| **DER (Diarization Error Rate)** | 分離錯誤率 | 8.5% |
| **FA (False Alarm)** | 誤報率 | 2.1% |
| **MISS** | 漏檢率 | 3.2% |
| **CONF** | 混淆率 | 3.2% |
**DER 計算:**
```
DER = FA + MISS + CONF
= (誤檢語音時間 + 漏檢語音時間 + 混淆時間) / 總語音時間
```
### 2.5 ASRX 輸出格式
```json
{
"language": "en",
"segments": [
{
"start": 0.0,
"end": 2.5,
"text": "Hello, how are you today?",
"speaker": "SPEAKER_00"
},
{
"start": 2.5,
"end": 4.8,
"text": "I'm doing great, thank you.",
"speaker": "SPEAKER_01"
},
{
"start": 4.8,
"end": 7.2,
"text": "What about you?",
"speaker": "SPEAKER_00"
}
]
}
```
---
## 3. 聲紋比對 (Speaker Verification)
### 3.1 模型概覽
| 項目 | 規格 |
|------|------|
| **模型名稱** | ECAPA-TDNN |
| **開發者** | Desplanques et al. (2020) |
| **實現框架** | SpeechBrain |
| **模型類型** | 說話人識別編碼器 |
| **預訓練模型** | spkrec-ecapa-voxceleb |
| **嵌入維度** | 192-D |
| **參數量** | ~6.2M |
### 3.2 模型架構
```
ECAPA-TDNN Architecture:
┌────────────────────────────────────────────┐
│ Input: MFCC Features (80 dims) │
│ Frame rate: 100 frames/sec │
└──────────────┬─────────────────────────────┘
┌────────────────────────────────────────────┐
│ Layer 1: 1D Convolution │
│ - Kernel size: 5 │
│ - Channels: 512 │
│ - Temporal convolution │
└──────────────┬─────────────────────────────┘
┌────────────────────────────────────────────┐
│ Layer 2-4: SE-Res2Blocks x 3 │
│ - Res2Net: Multi-scale features │
│ - Squeeze-Excitation: Channel attention │
│ - Skip connections │
│ │
│ Each block: │
│ ┌──────────────────────────────┐ │
│ │ Conv 1x1 → Conv 3x3 x 4 │ │
│ │ ↓ ↓ ↓ ↓ │ │
│ │ Scale 1 2 3 4 │ │
│ │ └───────┴───┴───┘ │ │
│ │ ↓ │ │
│ │ SE Module │ │
│ │ (Squeeze-Excitation) │ │
│ └──────────────────────────────┘ │
└──────────────┬─────────────────────────────┘
┌────────────────────────────────────────────┐
│ Aggregation: Attentive Statistics Pool │
│ - Self-attention weighting │
│ - Mean + Std pooling │
│ - Learnable attention mechanism │
│ Output: [batch, 1536] │
└──────────────┬─────────────────────────────┘
┌────────────────────────────────────────────┐
│ Final Layer: Fully Connected │
│ - Input: 1536 │
│ - Output: 192 (embedding) │
│ - L2 normalization │
└──────────────┬─────────────────────────────┘
┌────────────────────────────────────────────┐
│ Output: Speaker Embedding (192-D) │
│ L2-normalized vector │
└────────────────────────────────────────────┘
```
### 3.3 關鍵創新
#### **1. ECAPA (Emphasized Channel Attention)**
```python
# SE Module (Squeeze-Excitation)
def SE_block(x, reduction=8):
# Squeeze: Global Average Pooling
squeezed = torch.mean(x, dim=2, keepdim=True)
# Excitation: FC layers
excited = FC(squeezed)
excited = ReLU(excited)
excited = FC(excited)
excited = Sigmoid(excited)
# Reweight channels
output = x * excited
return output
```
**效果**: 自動學習通道重要性,強調關鍵特徵
#### **2. TDNN (Time-Delay Neural Network)**
```python
# 1D Convolution with dilation
# Capture long-range temporal dependencies
conv = Conv1d(in_channels, out_channels,
kernel_size=3, dilation=2)
```
**效果**: 擴大感受野,捕捉長時依賴
#### **3. Res2Net (Multi-Scale Features)**
```python
# Split feature maps into 4 scales
x1, x2, x3, x4 = torch.chunk(x, 4, dim=1)
# Process each scale
y1 = conv1(x1)
y2 = conv2(x2 + y1)
y3 = conv3(x3 + y2)
y4 = conv4(x4 + y3)
# Concatenate
output = torch.cat([y1, y2, y3, y4], dim=1)
```
**效果**: 多尺度特徵融合,提升表徵能力
#### **4. Attentive Statistics Pooling (ASP)**
```python
def ASP(x):
# Self-attention
attention = Softmax(FC(x), dim=2)
# Weighted mean
mean = torch.sum(x * attention, dim=2)
# Weighted std
std = torch.sqrt(torch.sum((x - mean.unsqueeze(2))**2 * attention, dim=2))
# Concatenate
output = torch.cat([mean, std], dim=1)
return output
```
**效果**: 自適應聚合,保留統計信息
### 3.4 訓練數據與策略
#### **訓練數據: VoxCeleb2**
| 項目 | 數值 |
|------|------|
| **說話人數** | 6,000+ |
| **語音片段** | 1,000,000+ |
| **總時長** | 2,400+ 小時 |
| **來源** | YouTube 訪談視頻 |
| **語言** | 英語為主 |
#### **數據增強策略**
```
Augmentation Pipeline:
┌──────────────────────────────────┐
│ Original Audio │
└────────┬─────────────────────────┘
├─→ Noise Addition (MUSAN)
│ - SNR: 0-20 dB
│ - Background noise
├─→ Reverberation (RIR)
│ - Room Impulse Response
│ - Simulate room acoustics
├─→ Music Addition
│ - Background music
│ - SNR: 5-15 dB
└─→ Codec Compression
- MP3/AAC encoding
- Simulate transmission
```
### 3.5 性能指標
#### **VoxCeleb1 測試集**
| 指標 | 說明 | 數值 |
|------|------|------|
| **EER (Equal Error Rate)** | 等錯誤率 | **0.80%** |
| **minDCF** | 最小檢測代價函數 | **0.055** |
#### **EER 解釋**
```
EER (Equal Error Rate):
- 閾值調整使 FAR = FRR 的錯誤率
- FAR (False Acceptance Rate): 誤識別率
- FRR (False Rejection Rate): 拒識率
EER = 0.80% 意味著:
- 每 1000 次比對,僅 8 次錯誤
- 達到工業級應用標準
對比:
- 人類辨識: EER ~ 3-5%
- ECAPA-TDNN: EER 0.80% ✅ 超越人類
- x-vector: EER 2.5%
- d-vector: EER 5.0%
```
### 3.6 聲紋比對流程
```
Speaker Verification Pipeline:
┌────────────────────────────────────────┐
│ Step 1: Audio Preprocessing │
│ - Resample to 16kHz │
│ - Remove silence (VAD) │
│ - Normalize volume │
└────────┬───────────────────────────────┘
┌────────────────────────────────────────┐
│ Step 2: Feature Extraction │
│ - MFCC (80 dims) │
│ - Frame rate: 100fps │
│ - Window: 25ms, Stride: 10ms │
└────────┬───────────────────────────────┘
┌────────────────────────────────────────┐
│ Step 3: Speaker Encoding │
│ - ECAPA-TDNN forward pass │
│ - Output: 192-D embedding │
│ - L2 normalization │
└────────┬───────────────────────────────┘
┌────────────────────────────────────────┐
│ Step 4: Similarity Computation │
│ - Cosine Similarity: │
│ score = cos(e1, e2) │
│ = dot(e1, e2) / (||e1|| * ||e2||) │
└────────┬───────────────────────────────┘
┌────────────────────────────────────────┐
│ Step 5: Decision │
│ - Threshold: 0.25-0.35 │
│ - score > threshold → Same speaker │
│ - score < threshold → Different │
└────────────────────────────────────────┘
```
### 3.7 閾值選擇
| 應用場景 | 建議閾值 | FAR | FRR | 說明 |
|----------|----------|-----|-----|------|
| **高安全** | 0.35 | 0.1% | 5% | 銀行、門禁 |
| **平衡** | 0.30 | 0.5% | 1% | 一般應用 |
| **高可用** | 0.25 | 2% | 0.3% | 用戶體驗優先 |
**Momentry 默認**: 0.30 (平衡模式)
---
## 4. 模型對比總表
### 4.1 功能矩陣
| 功能 | Whisper | WhisperX | ECAPA-TDNN |
|------|---------|----------|------------|
| **語音轉文字** | ✅ | ✅ | ❌ |
| **時間戳對齊** | ⚠️ (句子級) | ✅ (詞級) | ❌ |
| **說話人分離** | ❌ | ✅ | ❌ |
| **聲紋提取** | ❌ | ⚠️ (x-vector) | ✅ (ECAPA) |
| **說話人識別** | ❌ | ⚠️ (聚類) | ✅ (比對) |
| **多語言支持** | ✅ (99種) | ✅ (99種) | ❌ (語言無關) |
| **GPU 加速** | ✅ | ✅ | ✅ |
| **實時處理** | ✅ | ⚠️ | ✅ |
### 4.2 性能對比
| 指標 | Whisper (base) | WhisperX | ECAPA-TDNN |
|------|----------------|----------|------------|
| **WER (英語)** | 5.4% | 5.4% | N/A |
| **WER (中文)** | 9.2% | 9.2% | N/A |
| **DER (分離)** | N/A | 8.5% | N/A |
| **EER (聲紋)** | N/A | N/A | **0.80%** |
| **速度 (CPU)** | ~1.5x RT | ~2x RT | ~50x RT |
| **速度 (GPU)** | ~4x RT | ~5x RT | ~200x RT |
| **模型大小** | 75 MB | 200 MB | 25 MB |
| **內存需求** | ~500 MB | ~2 GB | ~100 MB |
### 4.3 系統集成狀態
| 系統 | ASR 模型 | ASRX 模型 | 聲紋模型 | 狀態 |
|------|----------|-----------|----------|------|
| **Momentry Desktop** | Whisper tiny | ❌ | ❌ | ✅ 已集成 |
| **Momentry Core** | Whisper base | WhisperX | ECAPA-TDNN | ✅ 已集成 |
---
## 5. 整合方案
### 5.1 ASR + ASRX 整合
```
整合流程:
┌─────────────────────────────────────┐
│ Input: Video File │
└────────┬────────────────────────────┘
├─→ ASR (Whisper)
│ ├─ Transcribe
│ └─ Detect language
└─→ ASRX (WhisperX)
├─ Transcribe
├─ Align timestamps
├─ Speaker diarization
└─ Assign speaker IDs
┌─────────────────────────────────────┐
│ Output: │
│ { │
│ "segments": [ │
│ { │
│ "start": 0.0, │
│ "end": 2.5, │
│ "text": "...", │
│ "speaker": "SPEAKER_00" │
│ } │
│ ] │
│ } │
└─────────────────────────────────────┘
```
### 5.2 Face + ASRX 整合
```python
# 人臉與說話人匹配
def match_face_with_speaker(face_data, asrx_data, time_threshold=3.0):
"""
匹配邏輯:
1. 遍歷 ASRX 語音片段
2. 找到時間範圍內的人臉 (start-3s ~ end+3s)
3. 選擇最接近片段中間時間的人臉
4. 記錄匹配結果
"""
for segment in asrx_segments:
mid_time = (start + end) / 2
# 找時間範圍內的人臉
faces_in_range = find_faces_in_range(
start - time_threshold,
end + time_threshold
)
# 選擇最接近的人臉
best_face = min(faces_in_range,
key=lambda f: abs(f.timestamp - mid_time))
# 記錄匹配
result.append({
'speaker': segment.speaker,
'text': segment.text,
'has_face': best_face is not None,
'face_location': best_face.location
})
```
### 5.3 完整管線
```
完整處理管線:
┌─────────────────────────────────────┐
│ Input: Video File │
└────────┬────────────────────────────┘
├─→ Face Detection (MediaPipe)
│ └─ Frames with face bounding boxes
├─→ ASRX (WhisperX)
│ ├─ Speech transcription
│ ├─ Word timestamps
│ └─ Speaker IDs
└─→ Speaker Encoder (ECAPA-TDNN)
└─ Speaker embeddings (192-D)
┌─────────────────────────────────────┐
│ Integration Layer: │
│ - Match face ↔ speaker │
│ - Cluster speakers │
│ - Build timeline │
└────────┬────────────────────────────┘
┌─────────────────────────────────────┐
│ Output: │
│ { │
│ "timeline": [ │
│ { │
│ "start": 0.0, │
│ "end": 2.5, │
│ "speaker": "SPEAKER_00", │
│ "text": "...", │
│ "face_detected": true, │
│ "face_location": {...}, │
│ "embedding": [192 floats] │
│ } │
│ ] │
│ } │
└─────────────────────────────────────┘
```
---
## 6. 應用場景
### 6.1 場景推薦
| 場景 | 推薦方案 | 模型組合 |
|------|----------|----------|
| **快速轉錄** | ASR only | Whisper tiny |
| **字幕生成** | ASR + ASRX | WhisperX base |
| **會議記錄** | ASRX + Face | WhisperX + MediaPipe |
| **聲紋識別** | ASRX + Speaker | WhisperX + ECAPA-TDNN |
| **說話人追蹤** | Full Pipeline | WhisperX + MediaPipe + ECAPA-TDNN |
### 6.2 性能優化建議
#### **CPU 優化**
```python
# 使用 INT8 量化
model = WhisperModel("tiny", device="cpu", compute_type="int8")
# 降低採樣率
sample_interval = 30 # 每 30 幀處理一次
```
#### **GPU 優化**
```python
# 使用 GPU 加速
model = WhisperModel("base", device="cuda", compute_type="float16")
# 批處理
batch_size = 8
```
#### **內存優化**
```python
# 流式處理
chunk_duration = 30 # 秒
# 釋放不需要的模型
del model
torch.cuda.empty_cache()
```
---
## 7. 未來擴展方向
### 7.1 短期計劃1-2 個月)
| 功能 | 模型 | 優先級 |
|------|------|--------|
| **實時轉錄** | Whisper streaming | High |
| **多語言識別** | WhisperX + lang detect | Medium |
| **情感識別** | SpeechBrain emotion | Low |
### 7.2 中期計劃3-6 個月)
| 功能 | 模型 | 優先級 |
|------|------|--------|
| **聲紋註冊系統** | ECAPA-TDNN + Qdrant | High |
| **說話人數據庫** | PostgreSQL + pgvector | High |
| **跨視頻追蹤** | Speaker ID linking | Medium |
### 7.3 長期計劃6-12 個月)
| 功能 | 模型 | 優先級 |
|------|------|--------|
| **實時說話人識別** | Streaming pipeline | High |
| **聲紋去重** | Vector deduplication | Medium |
| **說話人屬性分析** | Age/Gender/Emotion | Low |
---
## 8. 參考資源
### 8.1 官方文檔
- [OpenAI Whisper](https://github.com/openai/whisper)
- [faster-whisper](https://github.com/guillaumekln/faster-whisper)
- [WhisperX](https://github.com/m-bain/whisperX)
- [SpeechBrain](https://speechbrain.github.io/)
- [pyannote.audio](https://github.com/pyannote/pyannote-audio)
### 8.2 學術論文
1. **Whisper**: "Robust Speech Recognition via Large-Scale Weak Supervision" (OpenAI, 2022)
2. **ECAPA-TDNN**: "ECAPA-TDNN: Emphasized Channel Attention, Propagation and Aggregation in TDNN Based Speaker Verification" (Interspeech 2020)
3. **x-vector**: "X-vectors: Robust DNN Embeddings for Speaker Recognition" (ICASSP 2018)
4. **Spectral Clustering**: "Normalized Cuts and Image Segmentation" (IEEE TPAMI 2000)
### 8.3 數據集
- **VoxCeleb1/2**: Large-scale speaker recognition dataset
- **LibriSpeech**: English speech recognition benchmark
- **AISHELL-1/2**: Chinese speech recognition dataset
- **Common Voice**: Multilingual speech dataset
---
## 9. 附錄:模型下載與安裝
### 9.1 Whisper (faster-whisper)
```bash
# 安裝 faster-whisper
pip install faster-whisper
# 模型自動下載(首次運行時)
# 存儲位置: ~/.cache/huggingface/hub/
```
### 9.2 WhisperX
```bash
# 安裝 WhisperX
pip install whisperx
# 安裝 PyTorch
pip install torch torchvision torchaudio
# 安裝 pyannote.audio (用於說話人分離)
pip install pyannote.audio
# 需要接受 HuggingFace 用戶協議
# 訪問: https://huggingface.co/pyannote/speaker-diarization
# 訪問: https://huggingface.co/pyannote/segmentation
```
### 9.3 SpeechBrain (ECAPA-TDNN)
```bash
# 安裝 SpeechBrain
pip install speechbrain
# 模型自動下載(首次運行時)
# 存儲位置: ~/.cache/huggingface/hub/
```
### 9.4 完整環境配置
```bash
# 創建虛擬環境
python3.11 -m venv venv
source venv/bin/activate
# 安裝核心依賴
pip install torch torchvision torchaudio
pip install faster-whisper
pip install whisperx
pip install speechbrain
pip install pyannote.audio
# 驗證安裝
python -c "from faster_whisper import WhisperModel; print('faster-whisper OK')"
python -c "import whisperx; print('whisperx OK')"
python -c "from speechbrain.inference.speaker import EncoderClassifier; print('SpeechBrain OK')"
```
---
**文檔結束**
---
**更新日誌:**
- 2026-04-06: V1.0 初始版本,完整分析 ASR/ASRX 和聲紋模型

View File

@@ -1,225 +0,0 @@
---
document_type: "reference_doc"
service: "MOMENTRY_CORE"
title: "ASR Configuration Unification"
date: "2026-04-25"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "configuration"
- "unification"
ai_query_hints:
- "查詢 ASR Configuration Unification 的內容"
- "ASR Configuration Unification 的主要目的是什麼?"
- "如何操作或實施 ASR Configuration Unification"
---
# ASR Configuration Unification
## Overview
This document defines the unified configuration approach for the ASR (Automatic Speech Recognition) system in Momentry Core. The goal is to eliminate configuration fragmentation and establish a single source of truth for ASR settings.
## Current Configuration Fragmentation
| System | Configuration | Default Value | Purpose |
|--------|--------------|---------------|---------|
| Rust Core | `MOMENTRY_ASR_TIMEOUT` | 3600 seconds (1 hour) | Overall ASR process timeout |
| Python Script | `MOMENTRY_ASR_DIRECT_TIMEOUT` | 600 seconds (10 min) | Direct transcription timeout |
| Python Script | `MOMENTRY_ASR_CHUNK_TIMEOUT` | 300 seconds (5 min) | Per-chunk transcription timeout |
| Monitoring | `monitor_config.yaml` | Various | Health check timeouts |
## Unified Configuration Strategy
### 1. Centralized Configuration in Rust
All ASR configuration should be centralized in the Rust configuration system (`src/core/config.rs`).
### 2. Environment Variable Hierarchy
```
MOMENTRY_ASR_TIMEOUT (primary) → MOMENTRY_ASR_DIRECT_TIMEOUT → MOMENTRY_ASR_CHUNK_TIMEOUT
```
### 3. Configuration Propagation
Rust configuration should be passed to Python scripts via:
- Environment variables
- Command-line arguments
- Configuration files
## Unified Configuration Specification
### Core Timeout Settings
| Environment Variable | Default | Description | Contract Compliance |
|---------------------|---------|-------------|---------------------|
| `MOMENTRY_ASR_TIMEOUT` | 3600 | Overall ASR process timeout | Required |
| `MOMENTRY_ASR_PROCESS_TIMEOUT` | 1800 | ASR processing timeout (subset of overall) | Recommended |
| `MOMENTRY_ASR_CHUNK_TIMEOUT` | 300 | Per-chunk transcription timeout | Optional |
### Performance Settings
| Environment Variable | Default | Description |
|---------------------|---------|-------------|
| `MOMENTRY_ASR_MODEL_SIZE` | "medium" | Whisper model size (tiny, base, small, medium, large) |
| `MOMENTRY_ASR_DEVICE` | "cpu" | Processing device (cpu, cuda, mps) |
| `MOMENTRY_ASR_COMPUTE_TYPE` | "int8" | Compute type for quantization |
| `MOMENTRY_ASR_BATCH_SIZE` | 16 | Batch size for processing |
### Quality Settings
| Environment Variable | Default | Description |
|---------------------|---------|-------------|
| `MOMENTRY_ASR_LANGUAGE` | "auto" | Language code or "auto" for detection |
| `MOMENTRY_ASR_TASK` | "transcribe" | Task type (transcribe, translate) |
| `MOMENTRY_ASR_BEAM_SIZE` | 5 | Beam size for decoding |
| `MOMENTRY_ASR_BEST_OF` | 5 | Number of candidates for beam search |
## Implementation Plan
### Phase 1: Configuration Unification
1. **Update Rust Configuration** (`src/core/config.rs`)
- Add comprehensive ASR configuration constants
- Maintain backward compatibility with existing environment variables
2. **Update Python Scripts**
- Modify `asr_processor_contract_v1.py` to use unified configuration
- Add timeout handling compliant with AI-Driven Processor Contract
- Remove hardcoded timeout values
3. **Update Monitoring Configuration**
- Align `monitor_config.yaml` with unified timeout values
### Phase 2: Contract Compliance
1. **Add Timeout Handling to Contract-Compliant Version**
- Implement signal-based timeout handling
- Add progress reporting during long operations
- Ensure graceful degradation on timeout
2. **Update AI-Driven Processor Contract**
- Add timeout specification requirements
- Define timeout handling best practices
### Phase 3: Validation and Testing
1. **Create Configuration Tests**
- Test environment variable propagation
- Verify timeout behavior
- Validate backward compatibility
2. **Update Documentation**
- Update AGENTS.md with new configuration variables
- Create configuration reference guide
## Code Changes Required
### 1. Rust Configuration Update
```rust
// src/core/config.rs
pub mod asr {
pub static TIMEOUT_SECS: Lazy<u64> = Lazy::new(|| {
env::var("MOMENTRY_ASR_TIMEOUT")
.unwrap_or_else(|_| "3600".to_string())
.parse()
.unwrap_or(3600)
});
pub static PROCESS_TIMEOUT_SECS: Lazy<u64> = Lazy::new(|| {
env::var("MOMENTRY_ASR_PROCESS_TIMEOUT")
.unwrap_or_else(|_| "1800".to_string())
.parse()
.unwrap_or(1800)
});
pub static CHUNK_TIMEOUT_SECS: Lazy<u64> = Lazy::new(|| {
env::var("MOMENTRY_ASR_CHUNK_TIMEOUT")
.unwrap_or_else(|_| "300".to_string())
.parse()
.unwrap_or(300)
});
// Additional configuration...
}
```
### 2. Python Configuration Handling
```python
# scripts/asr_processor_contract_v1.py
class ASRProcessor:
def __init__(self):
# Get unified configuration
self.overall_timeout = int(os.environ.get("MOMENTRY_ASR_TIMEOUT", "3600"))
self.process_timeout = int(os.environ.get("MOMENTRY_ASR_PROCESS_TIMEOUT", "1800"))
self.chunk_timeout = int(os.environ.get("MOMENTRY_ASR_CHUNK_TIMEOUT", "300"))
def process_with_timeout(self):
# Implement timeout handling compliant with contract
pass
```
## Migration Strategy
### Step 1: Backward Compatibility
- Keep existing environment variables functional
- Log deprecation warnings for old variables
- Provide migration guide
### Step 2: Gradual Migration
1. Update contract-compliant version first
2. Test with new configuration
3. Update other processors following same pattern
### Step 3: Full Migration
1. Remove old configuration variables
2. Update all documentation
3. Verify system-wide consistency
## Testing Requirements
### Unit Tests
- Configuration loading from environment variables
- Timeout behavior validation
- Backward compatibility verification
### Integration Tests
- End-to-end ASR processing with timeouts
- Configuration propagation from Rust to Python
- Signal handling and graceful degradation
### Performance Tests
- Timeout impact on processing performance
- Resource usage with different configurations
- Memory consumption with model caching
## Success Criteria
1. **Single Source of Truth**: All ASR configuration centralized in Rust
2. **Contract Compliance**: All processors follow AI-Driven Processor Contract
3. **Backward Compatibility**: Existing deployments continue to work
4. **Improved Maintainability**: Reduced configuration complexity
5. **Better Observability**: Consistent logging and monitoring
## Timeline
- **Week 1**: Design and specification
- **Week 2**: Implementation and testing
- **Week 3**: Deployment and validation
- **Week 4**: Documentation and training
## Responsible Parties
- **Technical Lead**: Warren (design and implementation)
- **Quality Assurance**: Warren (testing and validation)
- **Documentation**: Warren (guides and references)
## Approval
| Role | Name | Date | Status |
|------|------|------|--------|
| Technical Reviewer | Warren | 2026-03-27 | Pending |
| Ops Responsible | Warren | 2026-03-27 | Pending |
| Final Approver | Warren | 2026-03-27 | Pending |
---
*Document Version: 1.0*
*Last Updated: 2026-03-27*
*Next Review: 2026-04-27*

View File

@@ -1,185 +0,0 @@
---
document_type: "architecture_design"
service: "MOMENTRY_CORE"
title: "ASR Improvement Plan"
date: "2026-04-25"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "improvement"
- "plan"
ai_query_hints:
- "查詢 ASR Improvement Plan 的內容"
- "ASR Improvement Plan 的主要目的是什麼?"
- "如何操作或實施 ASR Improvement Plan"
---
# ASR Improvement Plan
## Overview
This document outlines the plan to optimize the Automatic Speech Recognition (ASR) system in Momentry Core. The current implementation has several areas for improvement including performance bottlenecks, architectural complexity, and configuration fragmentation.
## Current State Analysis
### Architecture
1. **Rust → Python Subprocess**: Rust calls Python script via subprocess with 3600s timeout
2. **Complex Python Script**: `asr_processor.py` (953 lines) with monitoring, Redis publishing, chunking logic
3. **Configuration Fragmentation**:
- Rust: `ASR_TIMEOUT_SECS = 3600` (1 hour)
- Python: Environment variables, hardcoded settings
- Monitoring: Separate configuration
### Performance Issues
1. **Subprocess Overhead**: Rust → Python → Whisper pipeline adds latency
2. **Chunking Overhead**: Large files (>20 minutes) require complex chunking logic
3. **Memory Usage**: No model caching, reloads Whisper for each file
4. **No Concurrency**: Processes files sequentially
### Testing Coverage
- Multiple test scripts but no systematic performance monitoring
- No regression testing for optimization changes
## Improvement Goals
### Phase 1: Immediate Optimizations (Week 1)
1. **Simplify Python Script**: Remove unnecessary monitoring and Redis logic
2. **Unify Configuration**: Centralize ASR settings in Rust config
3. **Add Basic Caching**: Implement simple Whisper model caching
### Phase 2: Performance Enhancements (Week 2)
1. **PyO3 Integration**: Replace subprocess with direct Rust-Python calls
2. **Parallel Processing**: Enable concurrent ASR processing
3. **Smart Chunking**: Optimize chunk sizes based on file characteristics
### Phase 3: Advanced Features (Week 3)
1. **Performance Metrics**: Add detailed timing and resource usage tracking
2. **Adaptive Timeouts**: Dynamic timeout based on file size/duration
3. **Language Detection**: Improve language identification accuracy
## Detailed Implementation Plan
### Task 1: Simplify Python Script
**Current**: 953 lines with monitoring, Redis publishing, complex chunking
**Target**: ~300 lines focused on core ASR functionality
**Changes**:
1. Remove `ResourceMonitor` class and background monitoring
2. Remove Redis publishing dependencies
3. Simplify chunking logic with sensible defaults
4. Keep essential error handling and logging
### Task 2: Unify Configuration
**Current**: Settings spread across Rust config, Python env vars, monitoring config
**Target**: Single source of truth in Rust config
**Changes**:
1. Move all ASR settings to `src/core/config.rs`
2. Add environment variable overrides for key parameters:
- `MOMENTRY_ASR_CHUNK_SIZE`: Chunk duration in seconds
- `MOMENTRY_ASR_MODEL`: Whisper model name
- `MOMENTRY_ASR_CACHE_ENABLED`: Enable model caching
3. Pass configuration from Rust to Python via command line arguments
### Task 3: Implement Model Caching
**Current**: Loads Whisper model for each file
**Target**: Cache model in memory across invocations
**Implementation**:
```python
# Simple singleton cache
_whisper_model_cache = {}
def get_whisper_model(model_name="base"):
if model_name not in _whisper_model_cache:
import whisper
_whisper_model_cache[model_name] = whisper.load_model(model_name)
return _whisper_model_cache[model_name]
```
### Task 4: Add Performance Metrics
**Current**: No systematic performance tracking
**Target**: Collect and log key metrics
**Metrics to Track**:
- Processing time per file
- Time per audio minute
- Memory usage
- CPU utilization
- Chunk count and sizes
### Task 5: Test Optimizations
**Test Strategy**:
1. **Unit Tests**: Verify simplified script functionality
2. **Performance Tests**: Compare before/after metrics
3. **Integration Tests**: Ensure Rust-Python integration works
4. **Regression Tests**: Verify existing functionality preserved
## Success Criteria
### Quantitative Metrics
1. **Processing Time**: Reduce by 20% for typical files
2. **Memory Usage**: Reduce peak memory by 30%
3. **Code Complexity**: Reduce Python script lines by 60%
4. **Configuration Points**: Reduce from 5+ to 2-3
### Qualitative Improvements
1. **Simpler Maintenance**: Easier to understand and modify
2. **Better Error Handling**: Clearer error messages and recovery
3. **Improved Monitoring**: Better visibility into ASR performance
4. **Enhanced Reliability**: More robust handling of edge cases
## Risks and Mitigations
### Risk 1: Breaking Existing Functionality
**Mitigation**: Comprehensive test suite, gradual rollout, backup of original scripts
### Risk 2: Performance Regression
**Mitigation**: Benchmark before/after, performance monitoring during rollout
### Risk 3: Increased Complexity
**Mitigation**: Keep changes focused, document thoroughly, peer review
## Timeline
### Week 1: Foundation
- Day 1-2: Simplify Python script
- Day 3-4: Unify configuration
- Day 5: Implement basic caching
### Week 2: Performance
- Day 1-2: Add performance metrics
- Day 3-4: Optimize chunking logic
- Day 5: Test and benchmark
### Week 3: Advanced Features
- Day 1-2: PyO3 integration research
- Day 3-4: Parallel processing implementation
- Day 5: Documentation and final testing
## Dependencies
1. **Whisper Model Availability**: Ensure required models are accessible
2. **FFmpeg/FFprobe**: Required for audio extraction
3. **Python Dependencies**: `openai-whisper`, `psutil` (optional)
## Team Responsibilities
- **Primary Developer**: Implement code changes
- **QA Engineer**: Test optimization results
- **DevOps**: Monitor production performance
- **Technical Lead**: Review architecture changes
## Next Steps
1. **Immediate**: Create simplified version of `asr_processor.py`
2. **Short-term**: Update Rust configuration to pass settings to Python
3. **Medium-term**: Implement performance metrics collection
4. **Long-term**: Evaluate PyO3 for direct Rust-Python integration
---
*Last Updated: 2026-03-27*
*Status: Planning Phase*
*Owner: Warren (Technical Lead)*

View File

@@ -1,348 +0,0 @@
---
document_type: "test_doc"
service: "MOMENTRY_CORE"
title: "ASR vs ASRX 效能差異分析"
date: "2026-04-01"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "asrx"
- "效能差異分析"
ai_query_hints:
- "查詢 ASR vs ASRX 效能差異分析 的內容"
- "ASR vs ASRX 效能差異分析 的主要目的是什麼?"
- "如何操作或實施 ASR vs ASRX 效能差異分析?"
---
# ASR vs ASRX 效能差異分析
| 項目 | 內容 |
|------|------|
| 分析日期 | 2026-04-01 |
| 分析者 | OpenCode |
| 測試影片 | ExaSAN (159.6秒) |
---
## 效能測試結果
| 處理器 | 處理時間 | 輸出大小 | 狀態 |
|--------|---------|---------|------|
| **ASR** | 12.68s | 9.0 KB | ✅ 成功 |
| **ASRX** | 4.79s | 40 B | ⚠️ 失敗(空結果) |
---
## 差異原因分析
### ASR 處理器
**成功運行**
```python
# ASR 配置
model = WhisperModel("tiny", device="cpu", compute_type="int8")
segments, info = model.transcribe(video_path, beam_size=5)
```
**輸出結果**
```json
{
"language": "zh",
"language_probability": 0.9916,
"segments": [
{"start": 0.0, "end": 2.0, "text": "正常來講就是簡吉斯用完之後..."},
...
]
}
```
**特點**
- ✅ 使用 `faster_whisper`
- ✅ 模型tiny最小最快
- ✅ beam_size=5更精確
- ✅ 成功識別中文 (zh, 99.16%)
---
### ASRX 處理器
**失敗運行**
```python
# ASRX 配置
model = whisperx.load_model("base", device="cpu", compute_type="int8")
result = model.transcribe(video_path, language="en")
# ... 後續還有對齊和說話人分離步驟
```
**輸出結果**
```json
{
"language": null,
"segments": []
}
```
**失敗原因**
1. **模塊依賴複雜**
- 需要 `whisperx`
- 需要 `pyannote.audio`(說話人分離)
- 需要 `speechbrain`(語音處理)
- 需要大量額外模型下載
2. **處理流程更長**
```
ASRX 處理步驟:
1. 語音活動檢測 (VAD) - Pyannote
2. 轉錄 (Transcription) - Whisper
3. 時間戳對齊 (Alignment) - wav2vec
4. 說話人分離 (Diarization) - pyannote
```
3. **首次運行需要下載模型**
```
- Pyannote VAD 模型 (~100MB)
- Wav2vec 對齊模型 (~350MB)
- 說話人分離模型 (~500MB)
```
---
## 實際效能對比(正確測試)
### ASR成功案例
| 指標 | 結果 |
|------|------|
| 處理時間 | 12.68s |
| 加速比 | 12.6x |
| 語言識別 | zh (99.16%) |
| 片段數 | 79 |
| 模型 | tiny |
| 輸出大小 | 9.0 KB |
### ASRX預期正確運行
| 指標 | 預期結果 |
|------|---------|
| 處理時間 | 30-60s |
| 加速比 | 2.7-5.3x |
| 語言識別 | zh |
| 片段數 | 79+ (含說話人ID) |
| 模型 | base + 說話人分離 |
| 輸出大小 | ~15-20 KB |
---
## ASRX 處理流程詳解
```
輸入影片
[1] 語音活動檢測 (VAD)
- 使用 Pyannote
- 檢測有人說話的片段
- 預估時間5-10s
[2] 轉錄 (Transcription)
- 使用 Whisper base 模型
- 轉錄語音為文字
- 預估時間10-15s
[3] 時間戳對齊 (Alignment)
- 使用 Wav2vec 模型
- 精確對齊詞級時間戳
- 預估時間5-10s
[4] 說話人分離 (Diarization)
- 使用 Pyannote 說話人模型
- 識別不同說話人
- 預估時間10-25s
輸出結果含說話人ID
```
**總預估時間30-60s**
---
## 功能對比
| 功能 | ASR | ASRX |
|------|-----|------|
| 語音轉文字 | ✅ | ✅ |
| 語言識別 | ✅ | ✅ |
| 詞級時間戳 | ❌ | ✅ |
| 說話人分離 | ❌ | ✅ |
| 說話人ID | ❌ | ✅ |
| 處理速度 | 快 | 慢 |
| 模型大小 | ~75MB | ~1GB+ |
---
## 為什麼測試中 ASRX 更快?
### 實際原因:**ASRX 失敗了**
```
測試日誌顯示:
[SCENE] Loading PyTorch model on mps
2026-04-01 10:14:22 - whisperx.asr - INFO - No language specified...
2026-04-01 10:14:22 - whisperx.vads.pyannote - INFO - Performing VAD...
[等待超時或失敗]
返回空結果:{"language": null, "segments": []}
```
**失敗原因**
1. 首次運行需要下載大型模型(~1GB
2. 網絡連接問題
3. 處理器超時(但異常被捕獲)
4. 返回空結果而非報錯
---
## 正確的效能對比
### 如果 ASRX 正確運行
| 處理器 | 模型 | 功能 | 預估時間 | 實際測試 |
|--------|------|------|---------|---------|
| **ASR** | tiny | 轉錄 | 12.68s | ✅ 12.68s |
| **ASRX** | base + diarization | 轉錄+說話人 | 30-60s | ❌ 4.79s (失敗) |
**結論**ASRX 實際上比 ASR 慢 2.4-4.7 倍
---
## 建議
### 1. 使用場景
**ASR**(快速轉錄):
- ✅ 只需要文字轉錄
- ✅ 不需要說話人信息
- ✅ 處理速度優先
**ASRX**(完整分析):
- ✅ 需要說話人分離
- ✅ 需要詞級時間戳
- ✅ 準確度優先
### 2. 優化建議
**對於 ASR**
- 使用 `tiny` 模型(最快)
- 如果需要更高準確度,使用 `base` 或 `small`
- MPS 加速(如果可用)
**對於 ASRX**
- 首次運行需要預下載模型
- 使用 GPU 加速(如有)
- 考慮分段處理長影片
### 3. 測試改進
修改 `test_processor_performance.py`,檢查輸出有效性:
```python
# 檢查 ASRX 輸出是否有效
if output_data.get("language") is None:
print(f"[ASRX] ✗ Failed - empty output")
return {
"processor": "asrx",
"status": "error",
"error": "Empty output (processing failed)"
}
```
---
## 技術細節
### ASRfaster-whisper
```python
from faster_whisper import WhisperModel
model = WhisperModel("tiny", device="cpu", compute_type="int8")
segments, info = model.transcribe(video_path, beam_size=5)
# 輸出
{
"language": "zh",
"language_probability": 0.9916,
"segments": [
{"start": 0.0, "end": 2.0, "text": "..."}
]
}
```
### ASRXwhisperx
```python
import whisperx
# 1. 轉錄
model = whisperx.load_model("base", device="cpu", compute_type="int8")
result = model.transcribe(video_path, language="en")
# 2. 對齊
model_a, metadata = whisperx.load_align_model(language_code=result["language"])
result = whisperx.align(result["segments"], model_a, metadata, video_path)
# 3. 說話人分離
diarize_model = whisperx.DiarizationPipeline(use_auth_token=None)
diarize_segments = diarize_model(video_path)
result = whisperx.assign_word_speakers(diarize_segments, result)
# 輸出
{
"language": "zh",
"segments": [
{
"start": 0.0,
"end": 2.0,
"text": "...",
"speaker_id": "SPEAKER_01"
}
]
}
```
---
## 結論
### 測試結果解釋
**ASRX 測試結果異常**
- ❌ 測試顯示 4.79s(比 ASR 快)
- ❌ 實際原因:處理失敗,返回空結果
- ✅ 正確預期30-60s比 ASR 慢 2.4-4.7x
### 正確的效能排序
```
快 ←────────────────────────────────→ 慢
ASR (tiny) < ASR (base) < ASRX < ASRX (large)
12.68s ~20-25s 30-60s ~60-120s
```
### 使用建議
1. **快速轉錄** → 使用 ASR (tiny)
2. **準確轉錄** → 使用 ASR (base/small)
3. **說話人分離** → 使用 ASRX確保模型已下載
---
## 參考資料
- [faster-whisper](https://github.com/SYSTRAN/faster-whisper)
- [whisperx](https://github.com/m-bain/whisperX)
- [pyannote.audio](https://github.com/pyannote/pyannote-audio)

View File

@@ -1,786 +0,0 @@
---
document_type: "architecture_design"
service: "MOMENTRY_CORE"
title: "ASRX Large 取代 ASR - 邊緣 AI 場景分析"
date: "2026-04-01"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "asrx"
- "large"
- "場景分析"
ai_query_hints:
- "查詢 ASRX Large 取代 ASR - 邊緣 AI 場景分析 的內容"
- "ASRX Large 取代 ASR - 邊緣 AI 場景分析 的主要目的是什麼?"
- "如何操作或實施 ASRX Large 取代 ASR - 邊緣 AI 場景分析?"
---
# ASRX Large 取代 ASR - 邊緣 AI 場景分析
| 項目 | 內容 |
|------|------|
| 分析日期 | 2026-04-01 |
| 部署模式 | **邊緣 AI**(本地運行,無雲端) |
| 硬體環境 | M4 Mac Mini 16GB |
| 目標 | 評估邊緣 AI 場景下 ASRX 取代 ASR 的可行性 |
---
## 執行摘要
### ✅ 可以考慮取代(有條件)
**邊緣 AI 場景優勢**
- ✅ 無雲端成本考量
- ✅ 離線運行能力
- ✅ 數據隱私保護
- ✅ 硬體資源固定
**建議方案**
- 使用 **ASRX 可配置模式**
- 根據影片類型自動選擇模型
- 優化記憶體使用
---
## 邊緣 AI 特性分析
### 與雲端 AI 的差異
| 因素 | 雲端 AI | 邊緣 AI |
|------|---------|---------|
| **成本模式** | 按使用計費 | 硬體固定成本 |
| **處理時間** | 彈性(可並行) | 用戶等待時間 |
| **資源限制** | 可擴展 | 固定16GB RAM |
| **網路依賴** | 需要連線 | 完全離線 |
| **數據隱私** | 需上傳 | 本地處理 ✅ |
| **部署複雜度** | 低 | 高(需預裝模型) |
### 邊緣 AI 關鍵考量
1. **處理時間** → 用戶體驗
2. **記憶體使用** → 系統穩定性
3. **離線能力** → 完整功能
4. **部署便利性** → 維護成本
---
## 硬體資源評估
### M4 Mac Mini 16GB 資源分配
```
系統保留: 2-3 GB
├─ macOS: 1.5 GB
├─ 後台服務: 0.5-1 GB
└─ 其他應用: 0-0.5 GB
可用於處理器: 13-14 GB
├─ PostgreSQL: 0.5 GB
├─ MongoDB: 1 GB
├─ Redis: 0.5 GB
├─ API Server: 0.5 GB
└─ 處理器: 10-11 GB
```
### 處理器記憶體需求
| 處理器 | 模型 | 記憶體峰值 | 可行性 |
|--------|------|-----------|--------|
| **ASR** | tiny | 2 GB | ✅ 輕鬆 |
| **ASR** | base | 2.5 GB | ✅ 輕鬆 |
| **ASR** | small | 3 GB | ✅ 輕鬆 |
| **ASR** | medium | 4 GB | ✅ 安全 |
| **ASRX** | base | 4-5 GB | ✅ 安全 |
| **ASRX** | large-v3 | **6-8 GB** | ⚠️ 接近上限 |
**結論**
- ASRX large 在 M4 16GB 上可行
- 但需注意記憶體峰值
- 建議並行處理時限制其他處理器
---
## 處理時間評估(邊緣場景)
### 短影片(< 5分鐘
```
影片時長: 159.6秒
ASR tiny: 12.68s → 用戶可接受 ✅
ASR base: ~25s → 用戶可接受 ✅
ASRX base: 30-60s → 用戶可接受 ✅
ASRX large: 120-200s → 稍久,但可接受 ⚠️
```
**結論**:短影片使用 ASRX large 可接受
### 中等影片5-30分鐘
```
影片時長: 10分鐘
ASR tiny: ~50s → 快速 ✅
ASRX base: ~3-5分鐘 → 可接受 ✅
ASRX large: ~8-15分鐘 → 用戶等待 ⚠️
```
**建議**
- 會議記錄ASRX large用戶願意等待
- 快速預覽ASR tiny
### 長影片(> 30分鐘
```
影片時長: 114分鐘
ASR tiny: ~9分鐘 → 可接受 ✅
ASRX base: ~30-60分鐘 → 用戶等待 ⚠️
ASRX large: ~90-150分鐘 → 很久 ❌
```
**建議**
- 電影/長片:分段處理或使用 ASR
- 會議記錄ASRX base平衡
---
## 功能需求分析
### 邊緣 AI 典型使用場景
| 場景 | 頻率 | ASR 需求 | ASRX 需求 |
|------|------|---------|----------|
| **會議記錄** | 高 | 轉錄 | ✅ 說話人分離 |
| **訪談/播客** | 中 | 轉錄 | ✅ 說話人分離 |
| **教學影片** | 中 | 轉錄 | ❌ 單人,不需要 |
| **新聞/演講** | 低 | 轉錄 | ❌ 單人,不需要 |
| **客戶服務** | 低 | 轉錄 | ✅ 說話人分離 |
**統計**
- 需要說話人分離:**60-70%**
- 只需轉錄:**30-40%**
---
## 取代方案設計
### 方案 AASRX 完全取代(激進)
```python
# 統一使用 ASRX large
class AudioProcessor:
def process(self, video_path):
return self.run_asrx_large(video_path)
```
**優點**
- ✅ 單一處理器,維護簡單
- ✅ 功能完整(說話人分離)
- ✅ 最高準確度
- ✅ 統一輸出格式
**缺點**
- ❌ 短影片處理時間增加 10 倍
- ❌ 記憶體使用接近上限
- ❌ 用戶體驗下降(等待時間)
**適用場景**
- 用戶願意等待
- 說話人分離是必需功能
- 硬體資源充足
---
### 方案 BASRX 智能選擇(推薦)⭐
```python
class AudioProcessor:
def process(self, video_path, mode="auto"):
"""
mode:
- "auto": 自動判斷(預設)
- "fast": 快速模式ASR tiny
- "diarized": 說話人分離ASRX base
"""
if mode == "auto":
# 自動判斷
duration = get_video_duration(video_path)
if duration < 300: # < 5分鐘
return self.run_asrx_base(video_path)
else:
return self.run_asr_medium(video_path)
elif mode == "fast":
return self.run_asr_tiny(video_path)
elif mode == "diarized":
return self.run_asrx_base(video_path)
```
**優點**
- ✅ 自動優化處理時間
- ✅ 記憶體使用安全
- ✅ 靈活配置
- ✅ 良好用戶體驗
**缺點**
- ⚠️ 邏輯較複雜
- ⚠️ 需維護多個模型
**適用場景**
- 各種影片類型
- 平衡效能與功能
- 邊緣 AI 最佳實踐
---
### 方案 CASRX 可配置(靈活)
```python
class AudioProcessor:
def process(self, video_path, config=None):
"""
config:
- model: "tiny" | "base" | "small" | "large-v3"
- diarization: true | false
- alignment: true | false
"""
config = config or {"model": "base", "diarization": True}
# 使用 ASRX 統一介面
return self.run_whisperx(
video_path,
model=config["model"],
diarization=config["diarization"]
)
```
**配置範例**
```json
// 快速模式(等同 ASR
{
"model": "tiny",
"diarization": false,
"alignment": false
}
// 標準模式ASR + 時間戳對齊)
{
"model": "base",
"diarization": false,
"alignment": true
}
// 完整模式(說話人分離)
{
"model": "base",
"diarization": true,
"alignment": true
}
// 專業模式(最高準確度)
{
"model": "large-v3",
"diarization": true,
"alignment": true
}
```
**優點**
- ✅ 單一處理器
- ✅ 最大靈活性
- ✅ 統一介面
- ✅ 向下兼容
**缺點**
- ⚠️ 配置複雜
- ⚠️ 用戶需了解參數
---
## 邊緣 AI 優化建議
### 1. 模型預載入
```python
class ModelManager:
"""邊緣 AI 模型管理器"""
_instance = None
_models = {}
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
# 啟動時預載入常用模型
cls._preload_models()
return cls._instance
@classmethod
def _preload_models(cls):
"""預載入模型到記憶體"""
# 載入 ASRX base最常用
cls._models["asrx_base"] = whisperx.load_model(
"base",
device="mps",
compute_type="float16"
)
print("[ModelManager] Preloaded ASRX base model")
def get_model(self, name):
return self._models.get(name)
```
**優點**
- ✅ 減少首次處理時間
- M4 MPS 加速
- ✅ 記憶體復用
### 2. 記憶體管理
```python
import gc
import torch
class MemoryManager:
"""邊緣 AI 記憶體管理"""
@staticmethod
def cleanup():
"""清理記憶體"""
gc.collect()
if torch.backends.mps.is_available():
torch.mps.empty_cache()
@staticmethod
def get_memory_usage():
"""取得記憶體使用情況"""
import psutil
process = psutil.Process()
return {
"rss": process.memory_info().rss / 1024 / 1024, # MB
"available": psutil.virtual_memory().available / 1024 / 1024
}
```
### 3. 批次處理優化
```python
class BatchProcessor:
"""邊緣 AI 批次處理"""
def process_videos(self, video_paths, config):
"""批次處理多個影片"""
results = []
for i, video_path in enumerate(video_paths):
# 檢查記憶體
mem = MemoryManager.get_memory_usage()
if mem["rss"] > 12000: # > 12GB
print(f"[Batch] Memory high ({mem['rss']:.0f}MB), cleaning...")
MemoryManager.cleanup()
# 處理影片
result = self.process_single(video_path, config)
results.append(result)
print(f"[Batch] Progress: {i+1}/{len(video_paths)}")
return results
```
### 4. M4 硬體加速
```python
class AcceleratorManager:
"""M4 加速器管理"""
@staticmethod
def get_device():
"""取得最佳裝置"""
if torch.backends.mps.is_available():
return torch.device("mps") # M4 GPU
elif torch.cuda.is_available():
return torch.device("cuda")
else:
return torch.device("cpu")
@staticmethod
def get_compute_type():
"""取得計算精度"""
device = AcceleratorManager.get_device()
if device.type == "mps":
return "float16" # M4 支援 FP16
else:
return "int8" # CPU 使用 INT8
```
---
## 實施建議
### Phase 1統一為 ASRX立即
**目標**:將 ASR 和 ASRX 合併為單一處理器
```python
# 新的統一處理器
scripts/audio_processor_unified.py
```
**實現**
```python
def process_audio(video_path, output_path, config=None):
"""
統一音頻處理器
config 預設值(平衡模式):
{
"model": "base",
"diarization": True,
"alignment": True,
"device": "mps",
"compute_type": "float16"
}
"""
config = config or {
"model": "base",
"diarization": True,
"alignment": True
}
# 使用 whisperx 統一處理
model = whisperx.load_model(
config["model"],
device=config.get("device", "mps"),
compute_type=config.get("compute_type", "float16")
)
result = model.transcribe(video_path)
if config.get("alignment"):
# 時間戳對齊
model_a, metadata = whisperx.load_align_model(
language_code=result["language"]
)
result = whisperx.align(...)
if config.get("diarization"):
# 說話人分離
diarize_model = whisperx.DiarizationPipeline()
diarize_segments = diarize_model(video_path)
result = whisperx.assign_word_speakers(diarize_segments, result)
# 統一輸出格式
output = {
"language": result["language"],
"segments": result["segments"],
"speakers": result.get("speakers", [])
}
with open(output_path, "w") as f:
json.dump(output, f, indent=2)
return output
```
### Phase 2配置管理第二週
```python
# 配置文件
config/audio_profiles.json
{
"profiles": {
"fast": {
"model": "tiny",
"diarization": false,
"alignment": false
},
"standard": {
"model": "base",
"diarization": false,
"alignment": true
},
"diarized": {
"model": "base",
"diarization": true,
"alignment": true
},
"professional": {
"model": "large-v3",
"diarization": true,
"alignment": true
}
},
"default": "diarized"
}
```
### Phase 3API 整合(第三週)
```bash
# API 端點
POST /api/v1/process
{
"file_uuid": "...",
"processors": ["audio"],
"audio_config": {
"profile": "diarized" # 或自定義配置
}
}
# 向下兼容
POST /api/v1/process
{
"file_uuid": "...",
"processors": ["asr"] # 自動使用 "standard" profile
}
```
---
## 性能基準測試
### M4 Mac Mini 16GB 測試結果
| 配置 | 短影片 (159.6s) | 中影片 (10分鐘) | 記憶體峰值 |
|------|----------------|----------------|-----------|
| **fast** (tiny, 無分離) | 12s | 50s | 2GB |
| **standard** (base, 對齊) | 25s | 100s | 2.5GB |
| **diarized** (base, 分離) | 45s | 180s | 4GB |
| **professional** (large-v3) | 150s | 600s | 7GB |
**建議配置**
- 預設:**diarized**(最佳平衡)
- 快速預覽fast
- 專業用途professional
---
## 部署建議
### 模型預下載
```bash
# 預下載所有模型(首次部署)
python3 scripts/download_audio_models.py
# 下載列表
models/
├── whisperx_base.pt # 150MB
├── whisperx_large_v3.pt # 3GB
├── alignment_model_zh.pt # 350MB
├── alignment_model_en.pt # 350MB
└── diarization_model.pt # 500MB
總計:~4.5GB
```
### 記憶體優化配置
```python
# config/memory_config.json
{
"max_memory_mb": 12000,
"cleanup_threshold_mb": 10000,
"preload_models": ["base"],
"lazy_load_models": ["large-v3"]
}
```
---
## 最終建議
### ✅ 可以取代(推薦方案 B
**理由**
1. ✅ 邊緣 AI 無雲端成本
2. ✅ 統一處理器降低維護
3. ✅ 功能更完整
4. ✅ 靈活配置適應不同場景
5. ⚠️ 需優化記憶體管理
### 📋 實施步驟
1. **立即**:創建統一 `audio_processor_unified.py`
2. **第二週**:實現配置管理系統
3. **第三週**API 整合與測試
4. **第四週**:部署與優化
### 🎯 預期效果
| 指標 | 現狀(雙處理器) | 新方案(統一處理器) |
|------|----------------|---------------------|
| 維護成本 | 高 | 低 ✅ |
| 功能完整性 | 中 | 高 ✅ |
| 用戶體驗 | 好 | 更好 ✅ |
| 記憶體使用 | 安全 | 需優化 ⚠️ |
| 處理時間 | 快 | 可配置 ✅ |
---
## 附錄:統一處理器完整實現
```python
#!/usr/bin/env python3
"""
統一音頻處理器 (Edge AI)
支援多種配置模式,完全離線運行
"""
import json
import argparse
from pathlib import Path
from typing import Dict, Any, Optional
class UnifiedAudioProcessor:
"""統一音頻處理器 - 邊緣 AI 優化版"""
PROFILES = {
"fast": {
"model": "tiny",
"diarization": False,
"alignment": False,
"description": "快速轉錄(無說話人分離)"
},
"standard": {
"model": "base",
"diarization": False,
"alignment": True,
"description": "標準轉錄(含時間戳對齊)"
},
"diarized": {
"model": "base",
"diarization": True,
"alignment": True,
"description": "說話人分離(推薦)"
},
"professional": {
"model": "large-v3",
"diarization": True,
"alignment": True,
"description": "專業級(最高準確度)"
}
}
def __init__(self, profile: str = "diarized"):
self.profile = self.PROFILES.get(profile, self.PROFILES["diarized"])
self.device = self._get_device()
self.compute_type = self._get_compute_type()
def _get_device(self):
"""取得最佳裝置"""
import torch
if torch.backends.mps.is_available():
return "mps" # M4 GPU
return "cpu"
def _get_compute_type(self):
"""取得計算精度"""
return "float16" if self.device == "mps" else "int8"
def process(self, video_path: str, output_path: str) -> Dict[str, Any]:
"""處理音頻"""
import whisperx
# 載入模型
model = whisperx.load_model(
self.profile["model"],
device=self.device,
compute_type=self.compute_type
)
# 轉錄
result = model.transcribe(video_path)
# 時間戳對齊
if self.profile["alignment"]:
model_a, metadata = whisperx.load_align_model(
language_code=result["language"],
device=self.device
)
result = whisperx.align(
result["segments"],
model_a,
metadata,
video_path,
device=self.device
)
# 說話人分離
if self.profile["diarization"]:
diarize_model = whisperx.DiarizationPipeline(
use_auth_token=None,
device=self.device
)
diarize_segments = diarize_model(video_path)
result = whisperx.assign_word_speakers(diarize_segments, result)
# 建立輸出
output = {
"language": result.get("language"),
"segments": result.get("segments", []),
"speakers": self._extract_speakers(result),
"profile": self.profile["model"],
"diarization": self.profile["diarization"]
}
# 寫出
with open(output_path, "w", encoding="utf-8") as f:
json.dump(output, f, ensure_ascii=False, indent=2)
return output
def _extract_speakers(self, result):
"""提取說話人統計"""
if not self.profile["diarization"]:
return []
speakers = {}
for seg in result.get("segments", []):
speaker = seg.get("speaker")
if speaker:
if speaker not in speakers:
speakers[speaker] = {
"id": speaker,
"segment_count": 0,
"total_duration": 0.0
}
speakers[speaker]["segment_count"] += 1
speakers[speaker]["total_duration"] += (
seg["end"] - seg["start"]
)
return list(speakers.values())
def main():
parser = argparse.ArgumentParser(description="統一音頻處理器")
parser.add_argument("video_path", help="影片路徑")
parser.add_argument("output_path", help="輸出路徑")
parser.add_argument(
"--profile",
choices=["fast", "standard", "diarized", "professional"],
default="diarized",
help="處理模式預設diarized"
)
parser.add_argument("--uuid", help="影片 UUID")
args = parser.parse_args()
processor = UnifiedAudioProcessor(profile=args.profile)
result = processor.process(args.video_path, args.output_path)
print(f"[Audio] Processed {len(result['segments'])} segments")
if result.get("speakers"):
print(f"[Audio] Detected {len(result['speakers'])} speakers")
if __name__ == "__main__":
main()
```

View File

@@ -1,504 +0,0 @@
---
document_type: "architecture_design"
service: "MOMENTRY_CORE"
title: "ASRX Large 取代 ASR 可行性分析"
date: "2026-04-01"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "asrx"
- "large"
- "可行性分析"
ai_query_hints:
- "查詢 ASRX Large 取代 ASR 可行性分析 的內容"
- "ASRX Large 取代 ASR 可行性分析 的主要目的是什麼?"
- "如何操作或實施 ASRX Large 取代 ASR 可行性分析?"
---
# ASRX Large 取代 ASR 可行性分析
| 項目 | 內容 |
|------|------|
| 分析日期 | 2026-04-01 |
| 分析者 | OpenCode |
| 目標 | 評估是否可以用 ASRX large 完全取代 ASR |
---
## 執行摘要
### ❌ 不建議完全取代
**建議保留兩個處理器**,原因:
1. **效能差異巨大**3-10倍
2. **使用場景不同**
3. **資源消耗不同**
4. **向下兼容性**
---
## 功能對比
### ASR (faster-whisper)
```json
{
"language": "zh",
"language_probability": 0.9916,
"segments": [
{
"start": 0.0,
"end": 2.0,
"text": "正常來講就是簡吉斯用完之後"
}
]
}
```
**功能**
- ✅ 語音轉文字
- ✅ 語言識別
- ✅ 句級時間戳
### ASRX Large (whisperx + large-v3)
```json
{
"language": "zh",
"segments": [
{
"start": 0.0,
"end": 2.0,
"text": "正常來講就是簡吉斯用完之後",
"speaker_id": "SPEAKER_01",
"words": [
{"start": 0.0, "end": 0.5, "word": "正常", "speaker": "SPEAKER_01"},
{"start": 0.5, "end": 1.0, "word": "來講", "speaker": "SPEAKER_01"},
...
]
}
]
}
```
**功能**
- ✅ 語音轉文字(更高準確度)
- ✅ 語言識別
- ✅ 句級時間戳
-**詞級時間戳**
-**說話人分離**
-**說話人ID**
---
## 效能對比
### 短影片 (159.6秒)
| 處理器 | 模型 | 時間 | 加速比 | 記憶體 |
|--------|------|------|--------|--------|
| **ASR** | tiny | 12.68s | 12.6x | ~2GB |
| **ASR** | base | ~25s | 6.4x | ~2.5GB |
| **ASR** | small | ~50s | 3.2x | ~3GB |
| **ASRX** | base + diarization | 30-60s | 2.7-5.3x | ~4GB |
| **ASRX** | large-v3 + diarization | **120-200s** | **0.8-1.3x** | **~6-8GB** |
### 長影片 (114分鐘)
| 處理器 | 預估時間 | 記憶體 |
|--------|---------|--------|
| **ASR** | ~9分鐘 | ~2GB |
| **ASRX large** | **~90-150分鐘** | **~6-8GB** |
**關鍵發現**
- ASRX large 比 ASR 慢 **10-16 倍**
- 長影片處理時間從 9 分鐘增加到 **90-150 分鐘**
- 記憶體使用增加 **3-4 倍**
---
## 準確度對比
### Whisper 模型準確度WER - Word Error Rate
| 模型 | WER (英文) | WER (中文) | 相對準確度 |
|------|-----------|-----------|-----------|
| tiny | 7.5% | 12-15% | 基準 |
| base | 5.5% | 9-12% | +20% |
| small | 4.5% | 7-10% | +30% |
| medium | 3.5% | 6-8% | +40% |
| **large-v3** | **2.5%** | **5-7%** | **+50%** |
**結論**
- large-v3 比 tiny 準確度提升 **50-60%**
- 但代價是處理時間增加 **10-16 倍**
---
## 使用場景分析
### 場景 1快速預覽ASR 勝)
```
需求:快速查看影片內容
時間限制:< 30秒
準確度要求:中等
說話人分離:不需要
推薦ASR (tiny)
理由:
- 12.68s vs 120-200s
- 快速索引,後續可精確處理
```
### 場景 2會議記錄ASRX 勝)
```
需求:完整會議記錄
時間限制:無
準確度要求:高
說話人分離:必需
推薦ASRX (large-v3)
理由:
- 需要識別不同發言人
- 準確度優先
- 可接受較長處理時間
```
### 場景 3字幕生成ASR 中等模型勝)
```
需求:生成字幕
時間限制:< 5分鐘
準確度要求:高
說話人分離:不需要
推薦ASR (small/medium)
理由:
- 字幕不需要說話人信息
- 準確度足夠
- 處理時間合理
```
### 場景 4播客/訪談ASRX 勝)
```
需求:播客節目轉錄
時間限制:無
準確度要求:高
說話人分離:必需
推薦ASRX (base/large)
理由:
- 多人對話需要區分
- 準確度重要
```
### 場景 5新聞/演講ASR 勝)
```
需求:單一演講者轉錄
時間限制:< 1分鐘
準確度要求:中等
說話人分離:不需要(單人)
推薦ASR (base)
理由:
- 單一說話人,無需分離
- 快速處理
```
---
## 架構建議
### 方案 A保留雙處理器推薦
```
Momentry 處理管道:
[影片輸入]
[快速分析] → ASR (tiny/base) → 快速索引
[深度分析] → ASRX (large) → 完整記錄(可選)
```
**優點**
- ✅ 靈活選擇
- ✅ 效能優化
- ✅ 成本控制
- ✅ 向下兼容
**缺點**
- ⚠️ 需維護兩個處理器
- ⚠️ 配置較複雜
### 方案 BASRX 取代 ASR不推薦
```
Momentry 處理管道:
[影片輸入]
[ASRX large] → 完整分析
```
**優點**
- ✅ 單一處理器
- ✅ 功能完整
- ✅ 最高準確度
**缺點**
- ❌ 效能下降 10-16 倍
- ❌ 記憶體增加 3-4 倍
- ❌ 成本大幅增加
- ❌ 不適合快速預覽
### 方案 CASRX 可配置模式(折衷)
```python
class ASRXProcessor:
def __init__(self, mode="auto"):
"""
mode:
- "fast": 使用 tiny 模型,無說話人分離(等同 ASR
- "balanced": 使用 base 模型,輕量說話人分離
- "accurate": 使用 large 模型,完整說話人分離
"""
if mode == "fast":
self.model = "tiny"
self.diarization = False
elif mode == "balanced":
self.model = "base"
self.diarization = True
elif mode == "accurate":
self.model = "large-v3"
self.diarization = True
```
**優點**
- ✅ 單一處理器
- ✅ 靈活配置
- ✅ 向下兼容
**缺點**
- ⚠️ 配置複雜度增加
- ⚠️ 需要維護多種模式
---
## 成本分析
### 硬體資源
| 處理器 | CPU | GPU | 記憶體 | 儲存 |
|--------|-----|-----|--------|------|
| **ASR (tiny)** | 低 | 可選 | 2GB | 75MB |
| **ASR (base)** | 中 | 可選 | 2.5GB | 150MB |
| **ASRX (large)** | 高 | 建議 | 6-8GB | 3GB+ |
### 處理時間成本
以 100 部影片(平均 30 分鐘)為例:
| 方案 | 總處理時間 | 記憶體峰值 |
|------|-----------|-----------|
| **ASR (tiny)** | 15 小時 | 2GB |
| **ASRX (large)** | **150-250 小時** | 6-8GB |
### 雲端成本AWS p3.2xlarge
| 方案 | 每小時成本 | 總成本 |
|------|-----------|--------|
| **ASR** | $0.90 | $13.50 |
| **ASRX** | $0.90 | **$135-225** |
**結論**ASRX large 成本為 ASR 的 **10-17 倍**
---
## 技術實現
### ASRX Large 輸出格式
```json
{
"language": "zh",
"segments": [
{
"start": 0.0,
"end": 2.0,
"text": "正常來講就是簡吉斯用完之後",
"speaker_id": "SPEAKER_01",
"confidence": 0.95,
"words": [
{
"start": 0.0,
"end": 0.5,
"word": "正常",
"speaker": "SPEAKER_01",
"confidence": 0.98
}
]
}
],
"speakers": [
{
"id": "SPEAKER_01",
"total_time": 120.5,
"segment_count": 45
}
]
}
```
### 向下兼容方案
如果決定用 ASRX 取代 ASR需要
```python
def get_asr_compatible_output(asrx_result):
"""將 ASRX 輸出轉換為 ASR 格式(向下兼容)"""
return {
"language": asrx_result["language"],
"language_probability": 0.99,
"segments": [
{
"start": seg["start"],
"end": seg["end"],
"text": seg["text"]
}
for seg in asrx_result["segments"]
]
}
```
---
## 決策矩陣
| 因素 | ASR | ASRX large | 權重 | 得分 |
|------|-----|-----------|------|------|
| **處理速度** | 10 | 2 | 30% | ASR勝 |
| **準確度** | 6 | 10 | 25% | ASRX勝 |
| **功能完整** | 4 | 10 | 20% | ASRX勝 |
| **資源消耗** | 10 | 3 | 15% | ASR勝 |
| **維護成本** | 8 | 6 | 10% | ASR勝 |
| **總分** | **7.6** | **5.9** | 100% | **ASR勝** |
---
## 最終建議
### ✅ 保留兩個處理器(強烈推薦)
**實施方案**
```rust
pub enum ASRMode {
Fast, // ASR (tiny/base) - 快速轉錄
Accurate, // ASR (small/medium) - 準確轉錄
Diarized, // ASRX (base/large) - 說話人分離
}
impl VideoProcessor {
pub fn process_audio(&self, mode: ASRMode) -> Result<ASRResult> {
match mode {
ASRMode::Fast => self.run_asr("tiny"),
ASRMode::Accurate => self.run_asr("medium"),
ASRMode::Diarized => self.run_asrx("base"),
}
}
}
```
**API 設計**
```bash
# 快速轉錄(預設)
POST /api/v1/process
{
"file_uuid": "...",
"processors": ["asr"] # 使用 ASR tiny
}
# 準確轉錄
POST /api/v1/process
{
"file_uuid": "...",
"processors": ["asr:medium"]
}
# 說話人分離
POST /api/v1/process
{
"file_uuid": "...",
"processors": ["asrx"] # 使用 ASRX base
}
# 完整分析
POST /api/v1/process
{
"file_uuid": "...",
"processors": ["asrx:large"]
}
```
---
## 實施建議
### Phase 1保留現狀已完成
- ✅ ASR 處理器tiny/base/small/medium
- ✅ ASRX 處理器base/large
### Phase 2統一介面建議
- 創建 `AudioProcessor` 統一介面
- 支援模式選擇
- 向下兼容現有 API
### Phase 3優化 ASRX可選
- 預下載模型
- GPU 加速
- 批次處理
---
## 結論
### ❌ 不建議完全取代
**原因**
1. 效能差異太大10-16倍
2. 使用場景不同
3. 成本差異顯著
4. 靈活性降低
### ✅ 建議保留雙處理器
**理由**
1. 滿足不同場景需求
2. 效能與準確度平衡
3. 成本可控
4. 向下兼容
### 📋 未來方向
考慮將 ASR 和 ASRX 合併為統一的 `AudioProcessor`,支援多種模式:
```
AudioProcessor
├── mode: fast (ASR tiny)
├── mode: balanced (ASR medium)
└── mode: diarized (ASRX base)
```
這樣可以:
- 統一 API
- 靈活配置
- 向下兼容
- 降低維護複雜度

View File

@@ -1,658 +0,0 @@
# Face 處理模型分析
| 項目 | 內容 |
|------|------|
| 建立者 | OpenCode |
| 建立時間 | 2026-04-06 |
| 文件版本 | V1.0 |
---
## 版本歷史
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-04-06 | 創建文件 | OpenCode | MiniMax M2.5 |
---
## 概述
本文檔詳細分析 Momentry 系統中使用的三種人臉處理模型,包括其架構、性能、優缺點和適用場景。
---
## 模型總覽
```
┌─────────────────────────────────────────────────────────────┐
│ Momentry Face Processing Models │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ MediaPipe │ │ InsightFace │ │ OpenCV │ │
│ │ BlazeFace │ │ Buffalo_l │ │ HaarCascade │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ Primary: MediaPipe (Desktop + Core) │
│ Fallback: OpenCV Haar Cascade │
│ Advanced: InsightFace (Core only - Face Recognition) │
│ │
└─────────────────────────────────────────────────────────────┘
```
---
## 1. MediaPipe BlazeFace
### 1.1 模型架構
| 項目 | 規格 |
|------|------|
| **模型名稱** | BlazeFace |
| **開發者** | Google |
| **模型類型** | 輕量級單階段檢測器 |
| **骨幹網絡** | Custom CNN (MobileNet-like) |
| **模型格式** | TensorFlow Lite (.tflite) |
| **輸入尺寸** | 192x192 (Short-range), 256x256 (Full-range) |
| **輸出** | Bounding boxes + 6 keypoints |
### 1.2 模型特點
```
BlazeFace 架構:
┌─────────────────────────────────────┐
│ Input Image (256x256) │
└──────────────┬──────────────────────┘
┌─────────────────────────────────────┐
│ BlazeBlock (Lightweight CNN) │
│ - Depthwise Separable Conv │
│ - 5x5 & 3x3 Kernels │
│ - BatchNorm + ReLU6 │
└──────────────┬──────────────────────┘
┌─────────────────────────────────────┐
│ Multi-Scale Feature Maps │
│ (8x8, 16x16, 32x32) │
└──────────────┬──────────────────────┘
┌─────────────────────────────────────┐
│ SSD Head (Detection Head) │
│ - Classification │
│ - Bounding Box Regression │
│ - Keypoint Prediction (6 pts) │
└─────────────────────────────────────┘
```
### 1.3 GPU 加速支持
| 平台 | 加速方式 | 性能提升 |
|------|----------|---------|
| **Apple Silicon** | Metal Performance Shaders (MPS) | 3-5x |
| **NVIDIA GPU** | CUDA | 4-6x |
| **Intel GPU** | OpenCL | 2-3x |
| **CPU** | 多線程優化 | 基準 |
### 1.4 性能指標
| 指標 | Short-range | Full-range |
|------|-------------|------------|
| **準確率 (mAP)** | 93.5% | 95.2% |
| **速度 (FPS)** | 200+ | 100-150 |
| **檢測距離** | 0.5-2m | 0.5-5m |
| **最小人臉尺寸** | 20x20 px | 15x15 px |
| **模型大小** | ~1 MB | ~2 MB |
| **延遲** | <5ms | <10ms |
### 1.5 優缺點分析
#### ✅ 優點
1. **極致輕量**: 模型僅 1-2 MB適合移動端
2. **高速推理**: 實時檢測 (>100 FPS)
3. **GPU 加速**: 完整支持 Apple Metal (MPS)
4. **準確率高**: mAP > 95%
5. **關鍵點檢測**: 6 個面部關鍵點(眼、鼻、嘴)
6. **跨平台**: iOS, Android, Desktop, Web
7. **無需網絡**: 本地推理,隱私保護
#### ❌ 缺點
1. **僅檢測無識別**: 無法辨識人臉身份
2. **固定輸入尺寸**: 需要調整圖像大小
3. **小臉檢測受限**: 距離 >5m 準確率下降
4. **側臉效果差**: 側臉角度 >60° 檢測率降低
5. **遮擋敏感**: 口罩、眼鏡遮擋影響檢測
### 1.6 適用場景
| 場景 | 推薦度 | 說明 |
|------|--------|------|
| ✅ 實時視頻分析 | ⭐⭐⭐⭐⭐ | 最佳選擇 |
| ✅ 移動端應用 | ⭐⭐⭐⭐⭐ | 輕量、低功耗 |
| ✅ 本地處理 | ⭐⭐⭐⭐⭐ | 隱私友好 |
| ⚠️ 遠距離監控 | ⭐⭐⭐ | 需要高分辨率攝像頭 |
| ❌ 人臉識別 | ⭐ | 需搭配其他模型 |
| ❌ 側臉檢測 | ⭐⭐ | 效果不佳 |
---
## 2. InsightFace Buffalo_l
### 2.1 模型架構
| 項目 | 規格 |
|------|------|
| **模型名稱** | Buffalo_l (Large) |
| **開發者** | InsightFace Team |
| **模型類型** | 端到端人臉分析套件 |
| **模型格式** | ONNX |
| **組件數量** | 3 個模型(檢測、識別、關鍵點) |
| **嵌入維度** | 512-D |
| **訓練數據** | MS1MV3 (6M+ 人臉) |
### 2.2 組件詳解
```
InsightFace Buffalo_l Pipeline:
┌──────────────────────────────────────────────┐
│ Input Image (任意尺寸) │
└─────────────────┬────────────────────────────┘
┌──────────────────────────────────────────────┐
│ 1. Face Detection: SCRFD-10G │
│ - Multi-scale detection │
│ - Score: 0.5-1.0 │
│ - Output: Bounding boxes │
└─────────────────┬────────────────────────────┘
┌──────────────────────────────────────────────┐
│ 2. Face Alignment: 2D106det │
│ - 106 keypoints detection │
│ - 3D pose estimation │
│ - Output: Aligned face crop │
└─────────────────┬────────────────────────────┘
┌──────────────────────────────────────────────┐
│ 3. Face Recognition: w600k_r50 │
│ - ArcFace architecture │
│ - 512-D embedding vector │
│ - Cosine similarity matching │
└──────────────────────────────────────────────┘
```
### 2.3 模型組件詳情
#### **2.3.1 SCRFD-10G (Detection)**
| 項目 | 規格 |
|------|------|
| **骨幹網絡** | ResNet-50 + FPN |
| **檢測頭** | Multi-scale (8x, 16x, 32x) |
| **參數量** | 10.2M |
| **FLOPs** | 2.8G |
| **模型大小** | ~40 MB |
| **輸入尺寸** | 640x640 |
| **輸出** | NMS-filtered bounding boxes |
**特點:**
- Sample and Computation Redistribution (SCR)
- 優化計算分配,減少冗餘
- 支持多尺度檢測(小人臉、大臉)
#### **2.3.2 2D106det (Landmark)**
| 項目 | 規格 |
|------|------|
| **關鍵點數量** | 106 點 |
| **骨幹網絡** | MobileNet-like |
| **參數量** | 2.5M |
| **模型大小** | ~10 MB |
| **精度** | NME < 3.5% |
**關鍵點分布:**
```
眼睛 (12點) 眉毛 (18點)
┌─────┐ ┌─────┐ ┌─────────────┐
│ o o │ │ o o │ │ ^ ^ ^ ^ │
└─────┘ └─────┘ └─────────────┘
鼻子 (14點)
┌───┐
│ • │
└───┘
┌───────────────────┐
│ 嘴巴 (20點) │ 臉部輪廓 (42點)
│ ────┼──── │ 外圈完整輪廓
└───────────────────┘
```
#### **2.3.3 w600k_r50 (Recognition)**
| 項目 | 規格 |
|------|------|
| **骨幹網絡** | ResNet-50 (Modified) |
| **訓練損失** | ArcFace Loss |
| **嵌入維度** | 512-D |
| **參數量** | 25.6M |
| **模型大小** | ~100 MB |
| **訓練數據** | WebFace600K (600K 身份) |
**ArcFace Loss:**
```python
# ArcFace angular margin penalty
cos(theta + m) = cos(theta) * cos(m) - sin(theta) * sin(m)
# 其中:
# theta = 角度距離
# m = angular margin (通常 0.5 rad)
# 使同類樣本在角度空間更緊密
```
### 2.4 性能指標
| 指標 | Buffalo_l | Buffalo_s |
|------|-----------|-----------|
| **檢測準確率 (mAP)** | 97.3% | 94.8% |
| **識別準確率 (LFW)** | 99.77% | 99.42% |
| **識別準確率 (CFP-FP)** | 98.47% | 97.21% |
| **識別準確率 (AgeDB-30)** | 97.82% | 96.15% |
| **推理速度 (CPU)** | 15-20 FPS | 30-40 FPS |
| **推理速度 (GPU)** | 80-120 FPS | 150-200 FPS |
| **總模型大小** | ~150 MB | ~50 MB |
### 2.5 GPU 加速支持
| 平台 | Execution Provider | 性能 |
|------|-------------------|------|
| **Apple Silicon** | CoreML | 50-80 FPS |
| **NVIDIA GPU** | CUDA | 80-120 FPS |
| **Intel CPU** | OpenVINO | 20-30 FPS |
| **通用 CPU** | ONNX Runtime | 15-20 FPS |
### 2.6 優缺點分析
#### ✅ 優點
1. **端到端方案**: 檢測 + 識別 + 關鍵點一體化
2. **高準確率**: LFW 99.77%,業界領先
3. **身份識別**: 支持人臉身份辨識
4. **豐富關鍵點**: 106 點,支持精細對齊
5. **開源免費**: MIT License
6. **預訓練模型**: 600K 身份,可直接使用
7. **活躍社區**: 持續更新和優化
#### ❌ 缺點
1. **模型較大**: 150 MB (Buffalo_l)
2. **計算密集**: 需要較強硬件
3. **部署複雜**: 需要配置 ONNX Runtime
4. **延遲較高**: 單次推理 20-50ms
5. **內存佔用**: 需要 2-4 GB 內存
6. **小臉檢測**: 小於 30x30 px 效果下降
### 2.7 適用場景
| 場景 | 推薦度 | 說明 |
|------|--------|------|
| ✅ 人臉識別系統 | ⭐⭐⭐⭐⭐ | 最佳選擇 |
| ✅ 考勤打卡 | ⭐⭐⭐⭐⭐ | 高準確率 |
| ✅ 安防監控 | ⭐⭐⭐⭐ | 需要服務器 GPU |
| ✅ 人臉聚類 | ⭐⭐⭐⭐⭐ | 嵌入向量支持 |
| ⚠️ 移動端應用 | ⭐⭐⭐ | 使用 Buffalo_s |
| ❌ 實時低延遲 | ⭐⭐ | 延遲較高 |
---
## 3. OpenCV Haar Cascade
### 3.1 模型架構
| 項目 | 規格 |
|------|------|
| **模型名稱** | Haar Cascade Classifier |
| **開發者** | Viola-Jones (2001) |
| **模型類型** | 傳統機器學習(非深度學習) |
| **模型格式** | XML |
| **特徵類型** | Haar-like features |
| **分類器** | AdaBoost + Cascade |
| **模型大小** | ~900 KB |
### 3.2 算法原理
```
Haar Cascade 工作流程:
┌────────────────────────────────────────┐
│ Input Image (灰度) │
└────────────┬───────────────────────────┘
┌────────────────────────────────────────┐
│ Integral Image 計算 │
│ (快速特徵計算) │
└────────────┬───────────────────────────┘
┌────────────────────────────────────────┐
│ Haar-like Features 提取 │
│ ┌──┬──┐ ┌──┬──┐ ┌──┬──┐ │
│ │▓▓│ │ │ │▓▓│ │▓▓│▓▓│ │
│ └──┴──┘ └──┴──┘ ├──┼──┤ │
│ Edge Edge Line │
│ │
│ ┌─────────┐ │
│ │▓▓▓▓▓▓▓▓▓│ │
│ ├─────────┤ │
│ │ │ │
│ └─────────┘ │
│ Four-rectangle │
└────────────┬───────────────────────────┘
┌────────────────────────────────────────┐
│ Cascade of Classifiers │
│ Stage 1 (弱分類器 x 2) │
│ ↓ 通過 │
│ Stage 2 (弱分類器 x 10) │
│ ↓ 通過 │
│ Stage 3 (弱分類器 x 25) │
│ ↓ 通過 │
│ ... │
│ Stage 38 (強分類器) │
└────────────┬───────────────────────────┘
┌────────────────────────────────────────┐
│ Output: 人臉區域 │
└────────────────────────────────────────┘
```
### 3.3 性能指標
| 指標 | 數值 |
|------|------|
| **準確率** | 70-85% |
| **速度 (CPU)** | 15-30 FPS |
| **速度 (GPU)** | 不支持 |
| **檢測時間** | 50-100 ms/image |
| **誤檢率** | 5-10% |
| **最小人臉尺寸** | 20x20 px |
| **訓練數據** | ~5000 正樣本 + 3000 負樣本 |
### 3.4 優缺點分析
#### ✅ 優點
1. **無需 GPU**: 純 CPU 運算
2. **極度輕量**: 僅 900 KB
3. **無依賴**: 內建於 OpenCV
4. **部署簡單**: 加載 XML 即可
5. **快速啟動**: 無需模型下載
6. **穩定可靠**: 經典算法,久經考驗
7. **跨平台**: 所有平台支持
#### ❌ 缺點
1. **準確率低**: 僅 70-85%
2. **誤檢率高**: 5-10% false positive
3. **側臉差**: 正臉檢測,側臉效果差
4. **遮擋敏感**: 眼鏡、口罩影響大
5. **光線敏感**: 光照變化影響檢測
6. **無 GPU 加速**: 僅支持 CPU
7. **無關鍵點**: 僅返回 bounding box
8. **無識別功能**: 僅檢測,無法識別身份
### 3.5 適用場景
| 場景 | 推薦度 | 說明 |
|------|--------|------|
| ✅ 快速原型 | ⭐⭐⭐⭐⭐ | 無需配置 |
| ✅ 資源受限環境 | ⭐⭐⭐⭐ | 低功耗設備 |
| ✅ 備用方案 | ⭐⭐⭐⭐ | 主要模型失敗時 |
| ⚠️ 簡單應用 | ⭐⭐⭐ | 準確率要求不高 |
| ❌ 生產環境 | ⭐⭐ | 準確率不足 |
| ❌ 高精度需求 | ⭐ | 不推薦 |
---
## 4. 模型對比總表
### 4.1 核心指標對比
| 指標 | MediaPipe BlazeFace | InsightFace Buffalo_l | OpenCV Haar Cascade |
|------|---------------------|------------------------|----------------------|
| **檢測準確率** | 95.2% | 97.3% | 75% |
| **識別準確率** | ❌ | 99.77% | ❌ |
| **速度 (GPU)** | 100-200 FPS | 80-120 FPS | N/A |
| **速度 (CPU)** | 50-80 FPS | 15-20 FPS | 15-30 FPS |
| **模型大小** | 1-2 MB | 150 MB | 900 KB |
| **關鍵點** | 6 點 | 106 點 | ❌ |
| **身份識別** | ❌ | ✅ | ❌ |
| **GPU 加速** | ✅ (MPS/CUDA) | ✅ (CoreML/CUDA) | ❌ |
| **部署難度** | 簡單 | 中等 | 極簡 |
| **內存需求** | ~100 MB | ~2 GB | ~50 MB |
### 4.2 功能矩陣
| 功能 | MediaPipe | InsightFace | OpenCV |
|------|-----------|-------------|--------|
| **人臉檢測** | ✅ | ✅ | ✅ |
| **人臉識別** | ❌ | ✅ | ❌ |
| **關鍵點檢測** | ✅ (6 點) | ✅ (106 點) | ❌ |
| **人臉對齊** | ❌ | ✅ | ❌ |
| **人臉聚類** | ❌ | ✅ | ❌ |
| **表情識別** | ❌ | ⚠️ (需擴展) | ❌ |
| **年齡性別** | ❌ | ⚠️ (需擴展) | ❌ |
| **活體檢測** | ❌ | ⚠️ (需擴展) | ❌ |
### 4.3 系統集成狀態
| 系統 | 模型 | 用途 | 狀態 |
|------|------|------|------|
| **Momentry Desktop** | MediaPipe | 人臉檢測 | ✅ 已集成 |
| **Momentry Desktop** | OpenCV Haar | 備用檢測 | ✅ 已集成 |
| **Momentry Core** | MediaPipe | 人臉檢測 | ✅ 已集成 |
| **Momentry Core** | InsightFace | 人臉識別 | ✅ 已集成 |
| **Momentry Core** | OpenCV Haar | 備用檢測 | ✅ 已集成 |
---
## 5. 使用建議
### 5.1 場景推薦
```
┌─────────────────────────────────────────────────────────┐
│ 模型選擇決策樹 │
├─────────────────────────────────────────────────────────┤
│ │
│ 開始 → 是否需要人臉識別? │
│ │ │
│ ├─ 是 → InsightFace Buffalo_l │
│ │ │
│ └─ 否 → 是否需要 GPU 加速? │
│ │ │
│ ├─ 是 → MediaPipe BlazeFace │
│ │ │
│ └─ 否 → OpenCV Haar Cascade │
│ │
└─────────────────────────────────────────────────────────┘
```
### 5.2 具體建議
#### **生產環境(高精度)**
```
推薦組合:
1. Primary: MediaPipe BlazeFace (檢測)
2. Secondary: InsightFace Buffalo_l (識別)
3. Fallback: OpenCV Haar Cascade (備用)
```
#### **開發測試環境**
```
推薦組合:
1. Primary: MediaPipe BlazeFace
2. Fallback: OpenCV Haar Cascade
```
#### **資源受限環境(嵌入式設備)**
```
推薦:
OpenCV Haar Cascade (純 CPU, 低內存)
```
#### **雲端服務器(高性能)**
```
推薦組合:
1. Primary: InsightFace Buffalo_l (檢測 + 識別)
2. Fallback: MediaPipe BlazeFace
```
---
## 6. 性能優化策略
### 6.1 幀採樣策略
| 視頻 FPS | 建議採樣間隔 | 處理速度提升 | 時間分辨率損失 |
|----------|-------------|-------------|---------------|
| 30 FPS | 每 10 幀 | 10x | 3 幀/秒 |
| 60 FPS | 每 15 幀 | 15x | 4 幀/秒 |
| 30 FPS | 每 30 幀 | 30x | 1 幀/秒 |
| 60 FPS | 每 60 幀 | 60x | 1 幀/秒 |
**Momentry 默認**: 每 30 幀採樣一次30 FPS 視頻 = 1 幀/秒)
### 6.2 GPU 加速配置
#### **Apple Silicon (M1/M2/M3)**
```python
# MediaPipe with MPS
detector = MediaPipeFaceDetector(device="mps")
# InsightFace with CoreML
providers = ["CoreMLExecutionProvider", "CPUExecutionProvider"]
face_model = FaceAnalysis(name="buffalo_l", providers=providers)
```
#### **NVIDIA GPU**
```python
# MediaPipe with CUDA
detector = MediaPipeFaceDetector(device="cuda")
# InsightFace with CUDA
providers = ["CUDAExecutionProvider", "CPUExecutionProvider"]
face_model = FaceAnalysis(name="buffalo_l", providers=providers)
```
### 6.3 內存優化
| 策略 | 效果 | 實現方式 |
|------|------|----------|
| **批量處理** | 內存 -30% | 每次處理 N 幀 |
| **圖像縮放** | 內存 -50% | 輸入縮小到 640x480 |
| **結果緩存** | 速度 +20% | Resume 機制 |
| **模型量化** | 內存 -60% | INT8 量化 |
---
## 7. 未來擴展方向
### 7.1 短期計劃1-2 個月)
| 功能 | 模型 | 優先級 |
|------|------|--------|
| **人臉追蹤** | DeepSORT | High |
| **表情識別** | FER2013 | Medium |
| **年齡性別預測** | AgeGenderNet | Medium |
### 7.2 中期計劃3-6 個月)
| 功能 | 模型 | 優先級 |
|------|------|--------|
| **活體檢測** | Silent Face Anti-Spoofing | High |
| **人臉 3D 重建** | DECA | Low |
| **人臉替換** | SimSwap | Low |
### 7.3 長期計劃6-12 個月)
| 功能 | 模型 | 優先級 |
|------|------|--------|
| **實時人臉識別** | InsightFace + TensorRT | High |
| **多人臉追蹤** | ByteTrack | Medium |
| **跨攝像頭重識別** | ReID models | Medium |
---
## 8. 參考資源
### 8.1 官方文檔
- [MediaPipe Face Detection](https://developers.google.com/mediapipe/solutions/vision/face_detector)
- [InsightFace GitHub](https://github.com/deepinsight/insightface)
- [OpenCV Cascade Classifier](https://docs.opencv.org/4.x/db/d28/tutorial_cascade_classifier.html)
### 8.2 學術論文
1. **BlazeFace**: "BlazeFace: Sub-millisecond Neural Face Detection on Mobile GPUs" (Google, 2019)
2. **SCRFD**: "SCRFD: Sample and Computation Redistribution for Efficient Face Detection" (InsightFace, 2021)
3. **ArcFace**: "ArcFace: Additive Angular Margin Loss for Deep Face Recognition" (CVPR 2019)
4. **Viola-Jones**: "Rapid Object Detection using a Boosted Cascade of Simple Features" (CVPR 2001)
### 8.3 數據集
- **LFW**: Labeled Faces in the Wild (13K images)
- **WebFace600K**: 600K identities, 10M images
- **MS1MV3**: Microsoft Celebrities (1M identities)
- **AgeDB-30**: Age invariant face recognition
- **CFP-FP**: Cross-pose face recognition
---
## 9. 附錄:模型下載與安裝
### 9.1 MediaPipe
```bash
# 安裝 MediaPipe
pip install mediapipe
# 模型自動下載(首次運行時)
# 存儲位置: ~/.mediapipe/models/
```
### 9.2 InsightFace
```bash
# 安裝 InsightFace
pip install insightface
# 安裝 ONNX Runtime (GPU)
pip install onnxruntime-gpu
# 或 CPU 版本
pip install onnxruntime
# 模型下載(首次運行時)
# 存儲位置: ~/.insightface/models/buffalo_l/
```
### 9.3 OpenCV
```bash
# 安裝 OpenCV
pip install opencv-python
# Haar Cascade 模型內建於 OpenCV
# 路徑: cv2.data.haarcascades
```
---
**文檔結束**
---
**更新日誌:**
- 2026-04-06: V1.0 初始版本,完整分析三種模型

View File

@@ -1,218 +0,0 @@
# 人臉識別系統實現總結
## 概述
已成功為 Momentry Core 系統實施完整的人臉識別功能,包括人臉檢測、識別、追蹤、聚類和 MPS 加速支援。
## 完成的功能
### ✅ 1. 數據庫架構
- **表結構**:
- `face_identities`: 儲存註冊的人臉身份(帶向量嵌入)
- `face_detections`: 儲存視頻中的人臉檢測記錄
- `face_clusters`: 儲存人臉聚類結果
- `face_recognition_results`: 儲存處理結果
- **向量搜索**: 使用 pgvector 擴展支援向量相似度搜索
- **索引優化**: 為所有查詢模式創建了適當的索引
### ✅ 2. InsightFace 模型集成
- **模型選擇**: 使用 `buffalo_l` 模型(準確度高)
- **功能支援**:
- 人臉檢測和邊界框定位
- 人臉特徵提取512維嵌入向量
- 屬性分析(年齡、性別、姿態)
- 人臉對齊和特徵點檢測
### ✅ 3. MPS (Metal Performance Shaders) 加速
- **Apple Silicon 優化**: 自動檢測並使用 CoreMLExecutionProvider
- **回退機制**: MPS 不可用時自動回退到 CPU
- **性能提升**: 在 Apple Silicon 上提供 GPU 加速
### ✅ 4. 處理器功能
- **人臉檢測**: 使用 InsightFace 進行高精度檢測
- **人臉追蹤**: 基於 IoU 的跨幀追蹤算法
- **人臉聚類**: 使用 DBSCAN 算法進行人臉分組
- **屬性提取**: 年齡、性別、姿態等屬性分析
### ✅ 5. REST API 端點
- `POST /api/v1/face/register`: 註冊新人臉
- `POST /api/v1/face/recognize`: 識別人臉
- `POST /api/v1/face/search`: 搜索相似人臉
- `GET /api/v1/face/list`: 列出所有人臉身份
- `GET /api/v1/face/{face_id}`: 獲取人臉詳情
- `DELETE /api/v1/face/{face_id}`: 刪除人臉身份
- `GET /api/v1/face/results/{file_uuid}`: 獲取處理結果
### ✅ 6. 數據庫函數
- `find_similar_faces()`: 向量相似度搜索
- `find_or_create_face_identity()`: 查找或創建人臉身份
- `update_cluster_centroid()`: 更新聚類中心
## 技術架構
### 數據流
```
視頻輸入 → 幀提取 → 人臉檢測 → 特徵提取 → 追蹤/聚類 → 數據庫存儲
```
### 組件關係
```
Rust API 層 (axum)
Python 處理器層 (InsightFace)
數據庫層 (PostgreSQL + pgvector)
客戶端應用
```
## 測試結果
### 單元測試
- ✅ 數據庫連接和操作
- ✅ InsightFace 模型加載
- ✅ 人臉處理器功能
- ✅ API 端點配置
### 集成測試
- ✅ 人臉註冊流程
- ✅ 人臉識別流程
- ✅ 數據庫操作
- ✅ MPS 加速測試
### 端到端測試
- ✅ 完整的人臉識別流程
- ✅ 向量相似度搜索
- ✅ 跨幀人臉追蹤
- ✅ 人臉聚類分組
## 性能特點
### 準確性
- 使用 state-of-the-art 的 InsightFace 模型
- 支援多人臉檢測和識別
- 高精度的特徵提取
### 效率
- MPS 加速Apple Silicon
- 批處理和緩存機制
- 異步處理支援
### 可擴展性
- 模塊化設計
- 可配置的處理管道
- 支援分佈式處理
## 配置選項
### 處理器配置
```toml
[face_recognition]
enable_recognition = true
enable_tracking = true
enable_clustering = true
use_mps = true # 自動使用 MPS 加速
model_name = "buffalo_l"
```
### 數據庫配置
```sql
-- 自動創建的表結構
-- 自動創建的向量索引
-- 預定義的搜索函數
```
## 使用示例
### 1. 註冊人臉
```bash
curl -X POST http://localhost:3002/api/v1/face/register \
-F "image=@person.jpg" \
-F "name=John Doe" \
-F "metadata={\"department\": \"engineering\"}"
```
### 2. 識別人臉
```bash
curl -X POST http://localhost:3002/api/v1/face/recognize \
-H "Content-Type: application/json" \
-d '{
"file_uuid": "video-123",
"enable_recognition": true,
"enable_tracking": true
}'
```
### 3. 搜索相似人臉
```bash
curl -X POST http://localhost:3002/api/v1/face/search \
-H "Content-Type: application/json" \
-d '{
"embedding": [0.1, 0.2, ...], # 512維向量
"similarity_threshold": 0.6
}'
```
## 部署指南
### 1. 環境要求
- PostgreSQL 13+ with pgvector 擴展
- Python 3.9+ with InsightFace
- Rust 1.70+ for API 服務器
- Apple Silicon (可選 MPS 加速)
### 2. 安裝步驟
```bash
# 1. 安裝 Python 依賴
pip install insightface onnxruntime psycopg2-binary
# 2. 運行數據庫遷移
psql -U accusys -d momentry -f migrations/006_face_recognition_tables.sql
# 3. 構建 Rust 項目
cargo build --release
# 4. 啟動服務器
cargo run -- server
```
### 3. 驗證安裝
```bash
./scripts/final_validation.sh
```
## 故障排除
### 常見問題
1. **MPS 加速不可用**: 檢查 ONNX Runtime 版本和 CoreML 支援
2. **模型下載失敗**: 手動下載 InsightFace 模型到 `~/.insightface/models/`
3. **數據庫連接失敗**: 檢查 PostgreSQL 服務和 pgvector 擴展
4. **內存不足**: 調整批處理大小或使用較小的模型 (`buffalo_s`)
### 日誌級別
```bash
export RUST_LOG=info
export MOMENTRY_LOG_LEVEL=debug
```
## 未來擴展
### 計劃功能
1. **實時人臉識別**: 支援實時視頻流處理
2. **分佈式處理**: 支援多節點並行處理
3. **模型微調**: 支援自定義模型訓練
4. **隱私保護**: 添加人臉數據加密和匿名化
### 性能優化
1. **模型量化**: 使用量化模型減少內存使用
2. **緩存機制**: 添加嵌入向量緩存
3. **異步隊列**: 使用消息隊列處理大量請求
## 結論
人臉識別系統已成功集成到 Momentry Core 中,提供了完整的從人臉檢測到識別、追蹤和聚類的功能。系統支援 Apple Silicon MPS 加速,具有高準確性和良好的性能表現。所有組件都經過充分測試,可以投入生產使用。
**系統狀態**: ✅ 生產就緒
**測試覆蓋率**: ✅ 全面測試
**文檔完整性**: ✅ 完整文檔
**性能表現**: ✅ 優化完成

View File

@@ -1,334 +0,0 @@
---
document_type: "architecture_design"
service: "MOMENTRY_CORE"
title: "圖片處理架構設計"
date: "2026-04-25"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "圖片處理架構設計"
ai_query_hints:
- "查詢 圖片處理架構設計 的內容"
- "圖片處理架構設計 的主要目的是什麼?"
- "如何操作或實施 圖片處理架構設計?"
---
# 圖片處理架構設計
## 1. 概述
### 1.1 設計理念
將圖片視為**單幀影片**,利用現有的影片處理管道進行統一的元數據提取和內容分析。
### 1.2 核心優勢
1. **技術復用**重用現有影片處理器ASR/ASRX、YOLO、OCR、Face、Scene
2. **統一接口**:圖片和影片使用相同的 API 接口
3. **成本效益**:無需開發專用的圖片處理系統
4. **數據一致性**:圖片和影片使用相同的數據模型
---
## 2. 技術實現
### 2.1 處理流程
```
圖片輸入
[圖片預處理]
圖片 → 單幀影片轉換 (1秒, 1fps)
[現有影片處理管道]
├──> ASR/ASRX 處理器 (跳過,無音頻)
├──> OCR 處理器 (文字識別)
├──> YOLO 處理器 (物件檢測)
├──> Face 處理器 (人臉識別)
├──> Scene 處理器 (場景分類)
分片生成
向量嵌入
檢索服務
```
### 2.2 圖片轉影片策略
| 參數 | 值 | 說明 |
|------|-----|------|
| **幀率** | 1 fps | 單幀影片1秒長度 |
| **分辨率** | 保持原圖 | 不進行縮放 |
| **編碼格式** | MP4/H.264 | 標準影片格式 |
| **臨時存儲** | 處理後刪除 | 減少存儲占用 |
### 2.3 EXIF 元數據提取
| EXIF 字段 | 用途 | 存儲位置 |
|-----------|------|----------|
| **拍攝時間** | 時間戳 | `chunks.start_time` |
| **GPS 坐標** | 地理位置 | `chunks.metadata.gps` |
| **相機型號** | 設備信息 | `chunks.metadata.camera` |
| **曝光參數** | 技術數據 | `chunks.metadata.exposure` |
---
## 3. 數據模型擴展
### 3.1 媒體類型枚舉
```rust
// src/core/media/types.rs
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum MediaType {
Video(VideoType),
Image(ImageType),
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum VideoType {
Mp4,
Mov,
Avi,
Mkv,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ImageType {
Jpeg,
Png,
Gif,
Bmp,
Webp,
}
// 擴展 VideoRecord 結構
pub struct VideoRecord {
pub id: i64,
pub uuid: String,
pub media_type: MediaType, // 新增字段
pub duration: f64, // 圖片: duration = 1.0
pub width: u32,
pub height: u32,
// ... 其他現有字段
}
```
### 3.2 圖片特定元數據
```rust
pub struct ImageMetadata {
pub exif_data: Option<serde_json::Value>,
pub color_profile: Option<String>,
pub dpi: Option<(u32, u32)>,
pub format: ImageType,
}
pub struct VideoRecord {
// ... 現有字段
pub image_metadata: Option<ImageMetadata>, // 圖片特有元數據
}
```
---
## 4. 分片策略
### 4.1 圖片特有分片類型
| 分片類型 | 對應影片分片 | 圖片應用 |
|----------|--------------|----------|
| **TimeBased** | `ChunkType::TimeBased` | 單一時間點 (0.0-1.0秒) |
| **Visual** | `ChunkType::Visual` | YOLO 檢測到的視覺物件 |
| **Text** | `ChunkType::Sentence` | OCR 識別的文本內容 |
| **Face** | 新類型 `ChunkType::Face` | 人臉識別結果 |
### 4.2 分片內容結構
```rust
// 圖片視覺分片
pub struct ImageVisualChunk {
pub objects: Vec<DetectedObject>, // YOLO 檢測結果
pub scene_tags: Vec<String>, // 場景分類標籤
pub dominant_colors: Vec<Color>, // 主導顏色
}
// 圖片文本分片
pub struct ImageTextChunk {
pub ocr_text: String, // OCR 識別文本
pub text_regions: Vec<TextRegion>, // 文本區域位置
pub language: Option<String>, // 語言識別
}
```
---
## 5. 處理器適配
### 5.1 現有處理器修改
| 處理器 | 圖片處理策略 | 修改需求 |
|--------|--------------|----------|
| **ASR/ASRX** | 跳過處理 | 檢測媒體類型,圖片時跳過 |
| **OCR** | 增強處理 | 支持圖片 OCR可選用更高精度模型 |
| **YOLO** | 正常處理 | 無需修改 |
| **Face** | 正常處理 | 無需修改 |
| **Scene** | 正常處理 | 無需修改 |
| **CUT** | 跳過處理 | 單幀無需場景切換檢測 |
### 5.2 新增處理器
```rust
// EXIF 提取處理器
pub struct ExifExtractor;
impl Processor for ExifExtractor {
fn process(&self, context: &ProcessorContext) -> Result<ProcessorOutput> {
// 僅對圖片執行
if context.media_type == MediaType::Image {
// 提取 EXIF 數據
let exif_data = extract_exif(&context.input_path)?;
Ok(ProcessorOutput::Exif(exif_data))
} else {
Ok(ProcessorOutput::Skipped)
}
}
}
// 圖片質量評估處理器
pub struct ImageQualityAssessor;
impl Processor for ImageQualityAssessor {
fn process(&self, context: &ProcessorContext) -> Result<ProcessorOutput> {
// 評估圖片質量
let quality_score = assess_image_quality(&context.input_path)?;
Ok(ProcessorOutput::ImageQuality(quality_score))
}
}
```
---
## 6. API 擴展
### 6.1 新增端點
```rust
// 圖片上傳端點
POST /api/v1/images/upload
Content-Type: multipart/form-data
// 圖片搜索端點
GET /api/v1/images/search
Query: {
"text": "沙灘日落",
"objects": ["person", "umbrella"],
"colors": ["#FF6B35", "#004E89"],
"time_range": {"start": "2024-01-01", "end": "2024-12-31"}
}
// 圖片元數據端點
GET /api/v1/images/{uuid}/metadata
```
### 6.2 搜索功能擴展
1. **視覺搜索**
- 基於 YOLO 物件檢測
- 顏色直方圖匹配
- 紋理特徵相似度
2. **文本搜索**
- OCR 文本全文搜索
- EXIF 元數據過濾
3. **混合搜索**
- 視覺 + 文本組合搜索
- 地理 + 時間範圍搜索
---
## 7. 部署與性能
### 7.1 資源需求
| 資源 | 圖片處理需求 | 影片處理需求 |
|------|--------------|--------------|
| **CPU** | 較低 | 較高 |
| **GPU** | 可選(加速)| 必需 |
| **內存** | 較低 | 較高 |
| **存儲** | 較低 | 較高 |
### 7.2 性能優化
1. **批量處理**
```rust
// 支持批量圖片處理
pub async fn process_images_batch(
image_paths: Vec<PathBuf>,
concurrency: usize,
) -> Result<Vec<ProcessResult>> {
// 並行處理多張圖片
}
```
2. **緩存策略**
- 圖片轉影片結果緩存
- EXIF 元數據緩存
- 縮略圖預生成
3. **異步處理**
- 非阻塞上傳
- 後台處理隊列
- 處理狀態查詢
---
## 8. 實施路線圖
### 8.1 Phase 1: 基礎支持 (1個月)
- [ ] 圖片轉影片工具
- [ ] EXIF 元數據提取
- [ ] 現有處理器適配
### 8.2 Phase 2: 功能增強 (2個月)
- [ ] 圖片專用搜索功能
- [ ] 質量評估處理器
- [ ] 批量處理支持
### 8.3 Phase 3: 高級功能 (3個月)
- [ ] 視覺相似度搜索
- [ ] 圖片去重功能
- [ ] AI 圖片標註增強
---
## 9. 成功指標
### 9.1 功能指標
| 指標 | 目標值 |
|------|--------|
| 圖片處理成功率 | ≥99% |
| OCR 識別準確率 | ≥95% |
| 物件檢測準確率 | ≥90% |
| 處理延遲 | ≤5秒/圖片 |
### 9.2 業務指標
| 指標 | 目標值 |
|------|--------|
| 圖片檢索準確率 | ≥85% |
| 用戶滿意度 | ≥4.5/5.0 |
| 系統吞吐量 | ≥100圖片/分鐘 |
---
**最後更新**: 2026-04-22
**版本**: V1.0
**狀態**: 設計階段
**優先級**: 中

View File

@@ -1,202 +0,0 @@
---
document_type: "test_doc"
service: "MOMENTRY_CORE"
title: "長影片場景識別測試報告"
date: "2026-04-01"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "長影片場景識別測試報告"
ai_query_hints:
- "查詢 長影片場景識別測試報告 的內容"
- "長影片場景識別測試報告 的主要目的是什麼?"
- "如何操作或實施 長影片場景識別測試報告?"
---
# 長影片場景識別測試報告
| 項目 | 內容 |
|------|------|
| 測試日期 | 2026-04-01 |
| 測試影片 | Old_Time_Movie_Show_-_Charade_1963.HD.mov |
| 測試狀態 | ✅ 通過 |
---
## 測試影片資訊
### Old_Time_Movie_Show_-_Charade_1963
- **檔案大小**: 2.3 GB
- **時長**: 6,879.3 秒 (114 分 39 秒)
- **FPS**: 59.94
- **總幀數**: 412,343
- **解析度**: 1920x1080 (HD)
- **類型**: 電影(多場景)
---
## 測試參數
```bash
python3 scripts/scene_classifier.py \
"Old_Time_Movie_Show_-_Charade_1963.HD.mov" \
charade_scene_output.json \
--sample-interval 5.0 \
--min-scene-duration 10.0
```
### 參數選擇理由
- **取樣間隔 5 秒**: 電影場景變化較慢,減少取樣點提升速度
- **最小場景 10 秒**: 避免過於細碎的場景分段
---
## 測試結果
### 處理效能
| 指標 | 結果 | 備註 |
|------|------|------|
| 總處理時間 | 313.3 秒 | 約 5.2 分鐘 |
| 影片時長 | 6,879.3 秒 | 114 分 39 秒 |
| 加速比 | 22x | 實時 22 倍 |
| 取樣點數 | 1,379 個 | 每 5 秒取樣 |
| 處理 FPS | ~1,317 | 含模型載入 |
| 記憶體使用 | ~3-4 GB | M4 16GB 系統 |
### 識別結果
| 指標 | 結果 |
|------|------|
| 場景數量 | 1 |
| 場景類型 | scene_834 |
| 持續時間 | 6,873.9 秒 |
| 信心度 | 25.3% |
### Top 5 預測
1. scene_818 (4.0%)
2. scene_896 (2.2%)
3. scene_892 (1.7%)
4. scene_619 (1.6%)
5. scene_631 (1.5%)
---
## 效能分析
### 取樣策略評估
**5 秒間隔**:
- ✅ 處理速度快313 秒 vs 1,565 秒)
- ✅ 記憶體使用穩定
- ⚠️ 可能錯過短暫場景變化
**建議**:
- 對於電影5-10 秒間隔合適
- 對於短片/廣告2-3 秒間隔更佳
### 場景合併結果
**單一場景原因**:
1. 使用 ImageNet 模型(非 Places365
2. 電影包含多種場景,模型難以區分
3. 信心度分散Top 1 僅 4%
**預期改進**:
- 使用 Places365 模型後,應能識別多個場景
- 信心度應提升至 60-80%
---
## 與短片測試比較
| 指標 | 短片 (ExaSAN) | 長片 (Charade) |
|------|--------------|----------------|
| 影片時長 | 159.6 秒 | 6,879.3 秒 |
| 處理時間 | 1.2 秒 | 313.3 秒 |
| 取樣間隔 | 2 秒 | 5 秒 |
| 取樣點數 | 79 | 1,379 |
| 場景數量 | 1 | 1 |
| 信心度 | 37% | 25% |
| 加速比 | 133x | 22x |
### 觀察
- 長片處理時間線性增長
- 信心度較低(場景多樣性高)
- 加速比較低(模型載入時間佔比小)
---
## 技術限制
### 目前限制
1. **模型準確率**
- ImageNet 模型非場景分類專用
- 信心度偏低25-37%
- 場景名稱爲 scene_XXX 格式
2. **場景邊界偵測**
- 未整合 CUT 模組
- 無法精確識別場景切換點
- 建議後續整合
3. **處理速度**
- 長片需 5+ 分鐘
- 可優化批次處理、GPU 加速
### 改進建議
1. 下載 Places365 專門模型
2. 整合 CUT 場景切換偵測
3. 實現多線程/批次處理
4. 使用 Core ML 模型M4 優化)
---
## 測試結論
### ✅ 通過項目
- ✅ 長影片處理成功114 分鐘)
- ✅ 記憶體使用穩定(無溢位)
- ✅ 處理時間可接受5.2 分鐘)
- ✅ JSON 輸出格式正確
- ✅ 取樣策略有效
### ⚠️ 改進空間
- 場景識別準確率(需 Places365 模型)
- 場景邊界偵測(需整合 CUT
- 處理速度(可優化)
### 📋 下一步
1. 下載 Places365 專門模型
2. 整合 CUT 場景切換偵測
3. 測試更多電影類型
4. 優化長片處理策略
---
## 附錄:測試命令
```bash
# 長影片測試5 秒間隔)
python3 scripts/scene_classifier.py \
"Old_Time_Movie_Show_-_Charade_1963.HD.mov" \
output.json \
--sample-interval 5.0 \
--min-scene-duration 10.0
# 更快速測試10 秒間隔)
python3 scripts/scene_classifier.py \
"Old_Time_Movie_Show_-_Charade_1963.HD.mov" \
output.json \
--sample-interval 10.0 \
--min-scene-duration 30.0
# 精細測試2 秒間隔)
python3 scripts/scene_classifier.py \
"Old_Time_Movie_Show_-_Charade_1963.HD.mov" \
output.json \
--sample-interval 2.0 \
--min-scene-duration 5.0
```

View File

@@ -1,97 +0,0 @@
---
document_type: "installation_guide"
service: "PLACES365"
title: "Places365 模型安裝指南"
date: "2026-03-25"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "scene-classification"
- "places365"
- "model"
- "installation"
ai_query_hints:
- "如何安裝 Places365 場景識別模型?"
- "Places365 模型檔案存放路徑在哪裡?"
- "如何測試 Places365 場景識別功能?"
---
# Places365 模型安裝指南
## 概述
Places365 是一個專門用於場景識別的深度學習模型,包含 365 種場景類別。
## 目前狀態
### 已安裝 ✅
- ResNet18 ImageNet 預訓練模型 (`models/resnet18_imagenet.pth`, 44.7MB)
- Places365 類別映射 (`scripts/places365_categories.json`, 380 類)
- ImageNet 到場景映射 (`models/imagenet_to_scene.json`)
### 功能正常 ✅
- 基礎場景識別功能
- 380 個 Places365 類別支援
- PyTorch MPS 加速M4 Mac Mini 優化)
### 效能指標
| 指標 | 目前 | 預期 (Places365) |
|------|------|-----------------|
| 準確率 | 37% | 85-90% |
| 場景名稱 | scene_XXX | 實際名稱 |
| 處理速度 | ~60 FPS | ~60 FPS |
## 使用現有模型
即使沒有專門的 Places365 模型,系統仍可運作:
```bash
# 基本使用
python3 scripts/scene_classifier.py video.mp4 output.json
# 測試功能
python3 scripts/test_places365_scene.py
# 測試影片
python3 scripts/test_places365_scene.py /path/to/video.mp4
```
## 手動安裝 Places365 模型(可選)
如需提升準確率,可手動下載專門的 Places365 模型:
### 步驟 1: 下載模型
```bash
cd /Users/accusys/momentry/models
# 從 GitHub 下載
curl -L -o resnet18_places365.pth.tar \
"https://github.com/CSAILVision/places365/raw/master/resnet18_places365.pth.tar"
```
### 步驟 2: 驗證
```bash
ls -lh resnet18_places365.pth.tar
# 應該約 45MB
```
### 步驟 3: 測試
```bash
python3 scripts/test_places365_scene.py /path/to/video.mp4
```
## 參考資料
- [Places365 官方網站](http://places2.csail.mit.edu/)
- [GitHub Repository](https://github.com/CSAILVision/Places365)
## 故障排除
查看測試報告:
- `docs_v1.0/TESTING/SCENE_CLASSIFICATION_TEST_REPORT_2026_04_01.md`
- `docs_v1.0/IMPLEMENTATION/SCENE_CLASSIFICATION_MODULE.md`

View File

@@ -1,168 +0,0 @@
---
document_type: "guide"
service: "PLACES365"
title: "Places365 模型完整指南"
date: "2026-03-25"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "scene-classification"
- "places365"
- "model"
- "usage-guide"
ai_query_hints:
- "Places365 模型有哪些場景類別?"
- "如何升級 Places365 模型準確率?"
- "Places365 模型 API 如何使用?"
---
# Places365 模型完整指南
## 概述
Places365 是專門用於場景識別的深度學習模型,包含 365 種場景類別。
## 目前狀態
### ✅ 已安裝(可使用)
- **ResNet18 ImageNet**: `models/resnet18_imagenet.pth` (44.7 MB)
- **Places365 類別**: `scripts/places365_categories.json` (380 類)
- **功能狀態**: 正常運作
- **準確率**: ~37%ImageNet 模型)
### ⏳ 可選升級
- **Places365 專門模型**: 需手動下載
- **預期準確率**: 85-90%
- **場景名稱**: 實際名稱(如 office, classroom
## 手動下載 Places365 模型
### 方法 1: GitHub推薦
```bash
cd /Users/accusys/momentry/models
# 下載 ResNet18 Places365 模型
curl -L -o resnet18_places365.pth.tar \
"https://github.com/CSAILVision/places365/raw/master/resnet18_places365.pth.tar"
# 驗證大小(應約 45MB
ls -lh resnet18_places365.pth.tar
```
### 方法 2: Google Drive
1. 訪問https://drive.google.com/drive/folders/1qLX7dJNzqX8Z9Y0Z1Z2Z3Z4Z5Z6Z7Z8
2. 下載 `resnet18_places365.pth.tar`
3. 移動到 `/Users/accusys/momentry/models/`
### 方法 3: 使用 Python 腳本下載
```bash
cd /Users/accusys/momentry/models
python3 << 'PYEOF'
import torch
from torchvision import models
# 載入 Places365 模型(如果可用)
try:
model = models.resnet18(num_classes=365)
print("模型架構已建立")
print("請手動下載預訓練權重")
except Exception as e:
print(f"錯誤:{e}")
PYEOF
```
## 驗證模型
```bash
cd /Users/accusys/momentry/models
# 檢查檔案
ls -lh *.pth *.pth.tar 2>/dev/null
# 應看到:
# resnet18_imagenet.pth (44.7 MB) - 已安裝
# resnet18_places365.pth.tar (~45 MB) - 可選
```
## 使用模型
### 自動偵測
場景識別腳本會自動偵測並使用 Places365 模型(如果存在):
```bash
# 使用 ImageNet 模型(目前)
python3 scripts/scene_classifier.py video.mp4 output.json
# 下載 Places365 後會自動使用
# 場景名稱將從 scene_XXX 變為實際名稱(如 office
```
### 預期改進
| 指標 | ImageNet | Places365 |
|------|----------|-----------|
| 場景名稱 | scene_664 | office |
| 信心度 | 25-37% | 85-90% |
| 準確率 | 中等 | 高 |
| 場景類別 | 1000 (ImageNet) | 365 (Places) |
## 故障排除
### 問題:模型載入失敗
**檢查**:
```bash
python3 -c "import torch; print(torch.__version__)"
# 應 >= 1.8.0
```
**解決方案**:
```bash
pip3 install --upgrade torch torchvision
```
### 問題:場景名稱仍為 scene_XXX
**原因**: Places365 模型未正確載入
**檢查**:
```bash
ls -lh /Users/accusys/momentry/models/places365*.pth*
```
**解決方案**:
1. 確認模型檔案存在且 > 40MB
2. 重新啟動 Python 進程
3. 檢查腳本中的模型路徑
## 目前建議
### 立即可用
**使用現有 ImageNet 模型**
- 功能完整正常
- 380 個 Places365 類別可用
- 準確率可接受37%
### 可選升級
**下載 Places365 專門模型**
- 提升準確率到 85-90%
- 顯示實際場景名稱
- 需要手動下載(約 45MB
## 參考資料
- [Places365 官方網站](http://places2.csail.mit.edu/)
- [GitHub Repository](https://github.com/CSAILVision/Places365)
- [Model Download](https://github.com/CSAILVision/places365#model-download)
## 相關文檔
- `SCENE_CLASSIFICATION_MODULE.md` - 模組使用手冊
- `SCENE_CLASSIFICATION_TEST_RESULTS_2026_04_01.md` - 測試結果
- `LONG_MOVIE_SCENE_TEST_2026_04_01.md` - 長片測試

View File

@@ -1,407 +0,0 @@
---
document_type: "implementation_guide"
service: "MOMENTRY_CORE"
title: "場景識別模組 (Scene Classification)"
date: "2026-04-01"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "場景識別模組"
ai_query_hints:
- "查詢 場景識別模組 (Scene Classification) 的內容"
- "場景識別模組 (Scene Classification) 的主要目的是什麼?"
- "如何操作或實施 場景識別模組 (Scene Classification)"
---
# 場景識別模組 (Scene Classification)
| 項目 | 內容 |
|------|------|
| 建立者 | OpenCode |
| 建立時間 | 2026-04-01 |
| 文件版本 | V1.0 |
| 狀態 | 測試階段 |
---
## 版本歷史
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-04-01 | 創建場景識別模組 | OpenCode | - |
---
## 概述
場景識別模組用於識別影片中的場景類型(如醫院、教室、球場等),使用 Core ML + Places365 模型(針對 Apple Silicon M4 優化)。
---
## 功能特性
### 支援的場景類型
#### 室內場景
- hospital_room (醫院病房)
- pharmacy (藥房)
- classroom (教室)
- office (辦公室)
- kitchen (廚房)
- living_room (客廳)
- bedroom (臥室)
- bathroom (浴室)
- restaurant (餐廳)
- gym (健身房)
- supermarket (超市)
- auditorium (禮堂)
- library (圖書館)
- laboratory (實驗室)
- art_studio (藝術工作室)
- music_store (音樂商店)
- computer_room (電腦室)
- conference_room (會議室)
#### 室外場景
- basketball_court (籃球場)
- football_field (足球場)
- tennis_court (網球場)
- swimming_pool (游泳池)
- park (公園)
- street (街道)
- beach (海灘)
- mountain (山地)
- forest (森林)
- airport (機場)
- train_station (火車站)
- subway_station (地鐵站)
- gas_station (加油站)
- parking_lot (停車場)
- playground (遊樂場)
- ski_slope (滑雪坡)
- ice_rink (溜冰場)
- boxing_ring (拳擊場)
- volleyball_court (排球場)
- baseball_field (棒球場)
### 技術特點
-**Core ML 優化** - Apple Silicon M4 原生支援
-**PyTorch MPS 備案** - 當 Core ML 不可用時自動切換
-**中英文雙語** - 場景類型同時提供英文和中文
-**信心度排序** - 提供前 5 個預測結果
-**場景合併** - 自動合併連續相同場景
-**可配置取樣** - 支援自訂取樣間隔和最小場景持續時間
---
## 安裝與配置
### 系統需求
- macOS 12.0+ (支援 Core ML)
- Python 3.9+
- Apple Silicon M1/M2/M3/M4 (推薦)
### Python 依賴
```bash
# 必要依賴
pip install pillow opencv-python
# Core ML (推薦Apple Silicon 原生)
pip install coremltools
# PyTorch + MPS (備案)
pip install torch torchvision
```
### 模型準備
#### 方案 1: 使用 Places365 Core ML 模型(推薦)
```bash
# 下載 Places365 模型
# 從以下來源獲取:
# - https://github.com/onnx/models
# - https://coreml.store
# 或使用轉換工具自行轉換
# 放置模型於指定位置
mv places365.mlmodel ~/momentry/models/
```
#### 方案 2: 使用 PyTorch 預訓練模型(備案)
無需額外下載,會自動使用 ResNet18 預訓練模型。
---
## 使用方式
### CLI 基本用法
```bash
# 基本用法
python scripts/scene_classifier.py video.mp4 output.json
# 指定 UUID
python scripts/scene_classifier.py video.mp4 output.json --uuid "abc123"
# 指定 Core ML 模型
python scripts/scene_classifier.py video.mp4 output.json \
--model ~/momentry/models/places365.mlmodel
# 自訂取樣間隔(每 5 秒取樣一次)
python scripts/scene_classifier.py video.mp4 output.json \
--sample-interval 5.0
# 自訂最小場景持續時間(最少 5 秒)
python scripts/scene_classifier.py video.mp4 output.json \
--min-scene-duration 5.0
# 健康檢查
python scripts/scene_classifier.py --check-health
```
### Rust API
```rust
use momentry_core::core::processor::scene_classification::process_scene_classification;
// 執行場景識別
let result = process_scene_classification(
"/path/to/video.mp4",
"/path/to/output.json",
Some("abc123"),
).await?;
// 處理結果
for scene in &result.scenes {
println!(
"場景:{} ({}) - {:.1}s ~ {:.1}s (信心度:{:.0}%)",
scene.scene_type_zh.as_deref().unwrap_or(&scene.scene_type),
scene.scene_type,
scene.start_time,
scene.end_time,
scene.confidence * 100.0
);
}
```
### 整合到處理管線
```bash
# 作為獨立模組執行
cargo run --bin momentry -- process <uuid> --modules scene
# 與其他模組一起執行
cargo run --bin momentry -- process <uuid> \
--modules asr,cut,yolo,scene \
--force
```
---
## 輸出格式
### JSON 結構
```json
{
"frame_count": 3600,
"fps": 30.0,
"scenes": [
{
"start_time": 0.0,
"end_time": 150.5,
"scene_type": "hospital_room",
"scene_type_zh": "醫院病房",
"confidence": 0.92,
"top_5": [
{"scene_type": "hospital_room", "confidence": 0.92},
{"scene_type": "pharmacy", "confidence": 0.05},
{"scene_type": "classroom", "confidence": 0.02},
{"scene_type": "office", "confidence": 0.01},
{"scene_type": "living_room", "confidence": 0.00}
]
},
{
"start_time": 150.5,
"end_time": 280.0,
"scene_type": "basketball_court",
"scene_type_zh": "籃球場",
"confidence": 0.87,
"top_5": [...]
}
],
"metadata": {
"video_path": "/path/to/video.mp4",
"duration": 120.0,
"sample_interval": 2.0,
"min_scene_duration": 3.0,
"processed_at": "2026-04-01T12:00:00",
"model_type": "coreml"
}
}
```
### 欄位說明
| 欄位 | 類型 | 說明 |
|------|------|------|
| `frame_count` | u64 | 總幀數 |
| `fps` | f64 | 影格率 |
| `scenes` | Array | 場景片段陣列 |
| `scenes[].start_time` | f64 | 開始時間(秒) |
| `scenes[].end_time` | f64 | 結束時間(秒) |
| `scenes[].scene_type` | String | 場景類型(英文) |
| `scenes[].scene_type_zh` | String? | 場景類型(中文) |
| `scenes[].confidence` | f32 | 信心度0-1 |
| `scenes[].top_5` | Array | 前 5 個預測 |
| `metadata` | Object | 中繼資料 |
---
## 配置選項
### 環境變量
```bash
# 場景識別超時(秒)
export MOMENTRY_SCENE_TIMEOUT=7200
# Core ML 模型路徑
export MOMENTRY_SCENE_MODEL=~/momentry/models/places365.mlmodel
# 預設取樣間隔(秒)
export MOMENTRY_SCENE_SAMPLE_INTERVAL=2.0
# 預設最小場景持續時間(秒)
export MOMENTRY_SCENE_MIN_DURATION=3.0
```
### CLI 參數
| 參數 | 預設值 | 說明 |
|------|--------|------|
| `--model` | None | Core ML 模型路徑 |
| `--sample-interval` | 2.0 | 取樣間隔(秒) |
| `--min-scene-duration` | 3.0 | 最小場景持續時間(秒) |
| `--uuid` | None | 影片 UUID |
| `--check-health` | - | 健康檢查 |
---
## 效能基準
### M4 Mac Mini 16GB
| 模式 | 模型 | FPS | 記憶體 | 準確率 |
|------|------|-----|--------|--------|
| **Core ML** | Places365 | 15-20 | 2-4GB | 85-90% |
| **PyTorch MPS** | ResNet18 | 8-12 | 4-6GB | 75-85% |
| **PyTorch CPU** | ResNet18 | 2-5 | 2-4GB | 75-85% |
### 優化建議
1. **使用 Core ML** - 最佳效能
2. **調整取樣間隔** - 較長間隔 = 較快處理
3. **批次處理** - 一次處理多個影片
4. **模型量化** - INT8 量化減少記憶體
---
## 故障排除
### 問題Core ML 模型載入失敗
```bash
# 檢查模型檔案是否存在
ls -lh ~/momentry/models/places365.mlmodel
# 檢查 Core ML 是否安裝
pip show coremltools
# 使用 PyTorch 備案
python scripts/scene_classifier.py video.mp4 output.json
```
### 問題PyTorch MPS 不可用
```bash
# 檢查 PyTorch 版本(需要 1.12+
python -c "import torch; print(torch.__version__)"
# 檢查 MPS 支援
python -c "import torch; print(torch.backends.mps.is_available())"
# 更新 PyTorch
pip install --upgrade torch torchvision
```
### 問題OpenCV 無法開啟影片
```bash
# 檢查影片格式支援
ffmpeg -i video.mp4
# 重新編碼影片
ffmpeg -i video.mp4 -c:v libx264 video_fixed.mp4
# 檢查 OpenCV 版本
python -c "import cv2; print(cv2.__version__)"
```
---
## 測試
### 單元測試
```bash
# Rust 測試
cargo test --lib scene_classification
# Python 健康檢查
python scripts/scene_classifier.py --check-health
```
### 整合測試
```bash
# 測試短片(< 1 分鐘)
python scripts/scene_classifier.py test_short.mp4 test_output.json
# 驗證輸出
cat test_output.json | jq '.scenes | length'
```
---
## 相關文件
- [PROCESSING_PIPELINE.md](./ARCHITECTURE/PROCESSING_PIPELINE.md) - 處理管線
- [JSON_OUTPUT_SPEC.md](./REFERENCE/JSON_OUTPUT_SPEC.md) - JSON 輸出規範
- [MODULE_STANDARDIZATION_IMPLEMENTATION_PLAN.md](./ARCHITECTURE/MODULE_STANDARDIZATION_IMPLEMENTATION_PLAN.md) - 模組標準化
---
## 待辦事項
- [ ] 整合 Places365 Core ML 模型
- [ ] 添加更多場景類別
- [ ] 優化場景邊界檢測
- [ ] 添加場景轉換效果偵測
- [ ] 整合到字幕產生系統
- [ ] 添加視覺化顯示
---
## 參考資料
- [Places365 Dataset](http://places2.csail.mit.edu/)
- [Core ML Tools](https://coremltools.readme.io/)
- [PyTorch MPS Backend](https://pytorch.org/docs/stable/notes/mps.html)

View File

@@ -1,337 +0,0 @@
---
document_type: "test_doc"
service: "MOMENTRY_CORE"
title: "場景識別模組測試計畫"
date: "2026-04-01"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "場景識別模組測試計畫"
ai_query_hints:
- "查詢 場景識別模組測試計畫 的內容"
- "場景識別模組測試計畫 的主要目的是什麼?"
- "如何操作或實施 場景識別模組測試計畫?"
---
# 場景識別模組測試計畫
| 項目 | 內容 |
|------|------|
| 建立者 | OpenCode |
| 建立時間 | 2026-04-01 |
| 測試狀態 | 準備階段 |
---
## 測試目標
評估場景識別模組在 M4 Mac Mini 16GB 上的:
1. 功能完整性
2. 識別準確率
3. 處理效能
4. 記憶體使用
---
## 測試環境
### 硬體
- **設備**: Mac Mini M4
- **記憶體**: 16GB 統一記憶體
- **儲存**: SSD
### 軟體
- **macOS**: 14.0+ (Sonoma)
- **Python**: 3.9+
- **Rust**: 1.75+
### 依賴狀態
```
✓ PyTorch: Available (MPS 加速)
✓ PIL: Available
✓ OpenCV: Available
✗ Core ML: Not available (需安裝)
Device: mps
```
---
## 測試步驟
### Phase 1: 基本功能測試
#### 測試 1.1: 健康檢查
```bash
cd /Users/accusys/momentry_core_0.1
python3 scripts/scene_classifier.py --check-health
```
**預期結果**:
- Core ML: ✓ 或 ✗ (可接受)
- PyTorch: ✓
- PIL: ✓
- OpenCV: ✓
#### 測試 1.2: Rust 單元測試
```bash
cargo test --lib scene_classification
```
**預期結果**: 5 個測試全部通過
#### 測試 1.3: 短片測試 (< 1 分鐘)
```bash
# 使用現有測試影片
python3 scripts/scene_classifier.py \
/path/to/short_video.mp4 \
output_test.json \
--sample-interval 1.0 \
--min-scene-duration 2.0
```
**預期結果**:
- JSON 檔案成功產生
- 至少偵測到 1 個場景
- 處理時間 < 30 秒
---
### Phase 2: 準確率測試
#### 測試 2.1: 已知場景影片
使用已知場景的測試影片:
| 影片 | 預期場景 | 持續時間 |
|------|----------|----------|
| office_meeting.mp4 | office (辦公室) | 2:00 |
| basketball_game.mp4 | basketball_court (籃球場) | 5:00 |
| hospital_scene.mp4 | hospital_room (醫院病房) | 1:30 |
| classroom_lecture.mp4 | classroom (教室) | 10:00 |
```bash
python3 scripts/scene_classifier.py \
videos/office_meeting.mp4 \
results/office.json
```
**評估指標**:
- 主要場景類型是否正確
- 信心度是否 > 0.7
- 場景邊界是否準確
#### 測試 2.2: 多場景影片
使用包含多個場景的影片:
```bash
python3 scripts/scene_classifier.py \
videos/multi_scene.mp4 \
results/multi.json \
--sample-interval 2.0
```
**評估指標**:
- 偵測到的場景數量
- 場景轉換點是否準確
- 每個場景的持續時間
---
### Phase 3: 效能測試
#### 測試 3.1: 不同取樣間隔
```bash
# 1 秒間隔
time python3 scripts/scene_classifier.py \
video.mp4 out_1s.json --sample-interval 1.0
# 2 秒間隔
time python3 scripts/scene_classifier.py \
video.mp4 out_2s.json --sample-interval 2.0
# 5 秒間隔
time python3 scripts/scene_classifier.py \
video.mp4 out_5s.json --sample-interval 5.0
```
**預期結果**:
- 間隔越大,處理越快
- 間隔越小,場景偵測越精細
#### 測試 3.2: 記憶體使用
```bash
# 使用 Activity Monitor 或 Instruments 監控
# 或使用 /usr/bin/time -l
/usr/bin/time -l python3 scripts/scene_classifier.py \
video.mp4 output.json
```
**預期結果**:
- 記憶體使用 < 6GB (PyTorch MPS)
- 記憶體使用 < 4GB (Core ML)
#### 測試 3.3: 長影片測試
```bash
# 測試 30 分鐘影片
time python3 scripts/scene_classifier.py \
long_video.mp4 long_output.json
```
**預期結果**:
- 處理時間 < 10 分鐘
- 無記憶體溢位
- 成功完成
---
### Phase 4: 整合測試
#### 測試 4.1: Rust API 整合
```rust
use momentry_core::core::processor::scene_classification::process_scene_classification;
#[tokio::test]
async fn test_scene_classification_integration() {
let result = process_scene_classification(
"/path/to/video.mp4",
"/tmp/test_scene.json",
Some("test_uuid"),
).await.unwrap();
assert!(result.scenes.len() > 0);
assert!(result.fps > 0.0);
}
```
#### 測試 4.2: CLI 整合
```bash
# 作為 momentry 模組執行
cargo run --bin momentry -- process test_uuid --modules scene
```
---
## 評估標準
### 功能完整性
| 項目 | 權重 | 評分 (1-5) | 說明 |
|------|------|-----------|------|
| 基本識別 | 30% | - | 能識別基本場景 |
| 中英文支援 | 15% | - | 提供中英文場景名稱 |
| 信心度排序 | 15% | - | 提供 top 5 預測 |
| 場景合併 | 20% | - | 正確合併連續場景 |
| 錯誤處理 | 20% | - | 優雅處理異常 |
### 識別準確率
| 場景類型 | 測試影片數 | 正確數 | 準確率 |
|----------|-----------|--------|--------|
| 室內場景 | 5 | - | - |
| 室外場景 | 5 | - | - |
| 運動場景 | 3 | - | - |
| 交通場景 | 2 | - | - |
| **總計** | **15** | **-** | **-** |
**目標**: 整體準確率 > 80%
### 處理效能
| 指標 | 目標 | 實測 | 狀態 |
|------|------|------|------|
| FPS (Core ML) | > 15 | - | - |
| FPS (PyTorch MPS) | > 8 | - | - |
| 記憶體 (< 6GB) | ✓ | - | - |
| 30 分鐘影片處理 (< 10 分鐘) | ✓ | - | - |
---
## 測試影片清單
### 自備影片
- [ ] office_meeting.mp4 (辦公室)
- [ ] basketball_game.mp4 (籃球場)
- [ ] hospital_scene.mp4 (醫院)
- [ ] classroom_lecture.mp4 (教室)
- [ ] outdoor_park.mp4 (公園)
- [ ] street_view.mp4 (街道)
### 公開資料集
- [ ] Places365 validation set (子集)
- [ ] Kinetics-400 (場景相關子集)
---
## 已知問題
1. **Core ML 模型缺失** - 需要下載或轉換 Places365 模型
2. **PyTorch 使用 ImageNet** - 目前使用 ResNet18 預訓練模型,非 Places365
3. **場景類別有限** - 目前支援 38 種場景
---
## 下一步
1. [ ] 準備測試影片
2. [ ] 執行 Phase 1 測試
3. [ ] 執行 Phase 2 準確率測試
4. [ ] 執行 Phase 3 效能測試
5. [ ] 執行 Phase 4 整合測試
6. [ ] 撰寫測試報告
7. [ ] 根據結果優化
---
## 測試報告模板
```markdown
# 場景識別測試報告
## 測試日期
2026-04-XX
## 測試環境
- 硬體Mac Mini M4 16GB
- 軟體macOS 14.X, Python 3.9.X
## 測試結果
### 功能完整性
- 基本識別:✓
- 中英文支援:✓
- 信心度排序:✓
- 場景合併:✓
- 錯誤處理:✓
### 準確率
- 室內場景8/10 (80%)
- 室外場景7/10 (70%)
- 運動場景5/5 (100%)
- 總計20/25 (80%)
### 效能
- FPS: 12.5 (PyTorch MPS)
- 記憶體峰值4.2GB
- 30 分鐘影片處理8 分 30 秒
## 結論
場景識別模組基本功能正常,準確率可接受。
建議:
1. 整合 Places365 Core ML 模型提升準確率
2. 優化場景邊界檢測
3. 增加支援更多場景類別
```
---
## 參考文件
- [SCENE_CLASSIFICATION_MODULE.md](./SCENE_CLASSIFICATION_MODULE.md) - 模組文檔
- [PROCESSING_PIPELINE.md](./ARCHITECTURE/PROCESSING_PIPELINE.md) - 處理管線

View File

@@ -1,212 +0,0 @@
---
document_type: "test_doc"
service: "MOMENTRY_CORE"
title: "場景識別模組測試報告"
date: "2026-04-01"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "場景識別模組測試報告"
ai_query_hints:
- "查詢 場景識別模組測試報告 的內容"
- "場景識別模組測試報告 的主要目的是什麼?"
- "如何操作或實施 場景識別模組測試報告?"
---
# 場景識別模組測試報告
| 項目 | 內容 |
|------|------|
| 測試日期 | 2026-04-01 |
| 測試者 | OpenCode |
| 測試環境 | M4 Mac Mini 16GB |
| 測試狀態 | 初步測試完成 |
---
## 測試影片
### 影片 1: ExaSAN PCIe series
- **檔案**: `ExaSAN PCIe series - Director Ou Yu-Zhi Shares His Experience.mp4`
- **大小**: 6.8 MB
- **時長**: 159.6 秒 (2 分 40 秒)
- **FPS**: 22.0
- **總幀數**: 3512
- **場景**: 辦公室/會議室環境
### 影片 2: Old Time Movie Show
- **檔案**: `Old_Time_Movie_Show_-_Charade_1963.HD.mov`
- **大小**: 2.3 GB
- **時長**: 114 分鐘
- **場景**: 電影內容(多場景)
---
## 測試結果
### ExaSAN 影片測試
#### 執行命令
```bash
python3 scripts/scene_classifier.py \
"/Users/accusys/momentry/var/sftpgo/data/demo/ExaSAN PCIe series - Director Ou Yu-Zhi Shares His Experience.mp4" \
/tmp/exasan_test.json
```
#### 執行結果
```
[SCENE] Loading PyTorch model on mps
[SCENE] PyTorch model loaded successfully
[SCENE] Video: /Users/accusys/momentry/var/sftpgo/data/demo/...
[SCENE] FPS: 22.0, Frames: 3512, Duration: 159.6s
[SCENE] Collected 0 predictions
[SCENE] Result saved to: /tmp/exasan_test.json
[SCENE] Detected 0 scenes
[SCENE] Completed in 0.4s
```
#### 輸出 JSON
```json
{
"frame_count": 3512,
"fps": 22.0,
"scenes": [],
"metadata": {
"video_path": "...",
"duration": 159.6,
"sample_interval": 2.0,
"model_type": "pytorch"
}
}
```
---
## 問題分析
### 主要問題
**症狀**: 預測數量為 0
**原因**: `predict_frame` 方法中的類型檢查邏輯有問題
**證據**:
- 直接測試 PyTorch 模型預測成功
- 腳本執行時所有幀都返回空預測
- 幀讀取正常79 個取樣點)
### 已確認正常的功能
✅ Rust 模組編譯通過
✅ Rust 單元測試 5/5 通過
✅ Python 腳本健康檢查通過
✅ PyTorch 模型載入成功MPS 加速)
✅ OpenCV 幀讀取正常
✅ PIL 圖像轉換正常
✅ 單獨預測測試成功
### 待修復問題
❌ 腳本中的 `predict_frame` 方法在循環中返回空結果
❌ 需要添加更多調試信息找出問題
---
## 下一步建議
### 短期1-2 天)
1. **修復 predict_frame 方法**
- 添加更多調試輸出
- 檢查模型狀態在循環中是否保持
- 驗證 transform 在每次呼叫時正常工作
2. **重新測試 ExaSAN 影片**
- 確認預測正常運作
- 驗證場景合併邏輯
3. **測試長影片**
- 測試 Old_Time_Movie_Show (114 分鐘)
- 評估記憶體使用和處理時間
### 中期1 週)
1. **整合 Places365 模型**
- 下載或轉換 Core ML 模型
- 替換 ImageNet 模型
- 提升場景識別準確率
2. **整合到 Playground**
- 添加到 momentry_playground
- 使用 port 3003 測試
- 建立 Web UI 顯示結果
### 長期2-4 週)
1. **完整功能測試**
- 準確率評估
- 效能基準測試
- 使用者回饋收集
2. **優化與部署**
- 根據測試結果優化
- 文檔完善
- 生產環境部署
---
## 技術筆記
### 模型選擇
**目前使用**: ResNet18 (ImageNet)
- **優點**: 快速載入MPS 加速
- **缺點**: 不是場景分類專用模型
**建議升級**: Places365 (Core ML)
- **優點**: 365 種場景類別,準確率高
- **缺點**: 需要下載/轉換模型
### 效能預估M4 16GB
| 模型 | FPS | 記憶體 | 準確率 |
|------|-----|--------|--------|
| ResNet18 (ImageNet) | 15-20 | 2-4GB | 60-70% |
| Places365 (Core ML) | 20-30 | 1-2GB | 85-90% |
---
## 結論
場景識別模組基礎架構已完成Rust 和 Python 代碼都已實作。目前遇到預測邏輯問題,需要調試修復。
**建議優先順序**:
1. 修復 predict_frame 方法(立即)
2. 完成基本功能測試1-2 天)
3. 整合 Places365 模型1 週)
4. 整合到 Playground1-2 週)
---
## 附錄:測試命令
```bash
# 健康檢查
python3 scripts/scene_classifier.py --check-health
# 測試短片
python3 scripts/scene_classifier.py \
"/Users/accusys/momentry/var/sftpgo/data/demo/ExaSAN PCIe series - Director Ou Yu-Zhi Shares His Experience.mp4" \
/tmp/exasan_test.json
# 測試長片(待修復後)
python3 scripts/scene_classifier.py \
"/Users/accusys/momentry/var/sftpgo/data/demo/Old_Time_Movie_Show_-_Charade_1963.HD.mov" \
/tmp/charade_scene.json \
--sample-interval 5.0
# Rust 測試
cargo test --lib scene_classification
```

View File

@@ -1,151 +0,0 @@
---
document_type: "test_doc"
service: "MOMENTRY_CORE"
title: "場景識別測試結果"
date: "2026-04-01"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "場景識別測試結果"
ai_query_hints:
- "查詢 場景識別測試結果 的內容"
- "場景識別測試結果 的主要目的是什麼?"
- "如何操作或實施 場景識別測試結果?"
---
# 場景識別測試結果
| 項目 | 內容 |
|------|------|
| 測試日期 | 2026-04-01 |
| 測試者 | OpenCode |
| 測試狀態 | ✅ 通過 |
---
## 測試影片
### ExaSAN PCIe series
- **檔案**: `ExaSAN PCIe series - Director Ou Yu-Zhi Shares His Experience.mp4`
- **時長**: 159.6 秒
- **FPS**: 22.0
- **總幀數**: 3512
- **場景**: 辦公室/會議室環境
---
## 測試結果
### 基本功能測試
```bash
$ python3 scripts/test_places365_scene.py
✓ 載入 380 個場景類別
✓ 模型載入成功
✓ 所有測試完成!
```
### 影片場景識別
```bash
$ python3 scripts/scene_classifier.py ExaSAN.mp4 output.json
[SCENE] FPS: 22.0, Frames: 3512, Duration: 159.6s
[SCENE] Progress: 12.5% (10 samples)
[SCENE] Progress: 25.1% (20 samples)
...
[SCENE] Collected 79 predictions
[SCENE] Detected 1 scenes
[SCENE] Completed in 1.2s
```
### 識別結果
| 指標 | 結果 |
|------|------|
| 場景數量 | 1 |
| 場景類型 | scene_664 |
| 持續時間 | 156.0 秒 |
| 取樣點數 | 79 個 |
| 處理時間 | 1.2 秒 |
| 信心度 | 37.0% |
| FPS | ~60 (含模型載入) |
### Top 5 預測
1. scene_781 (92.6%)
2. scene_688 (1.9%)
3. scene_916 (1.4%)
4. scene_782 (0.7%)
5. scene_851 (0.6%)
---
## 效能分析
### 處理速度
- **總處理時間**: 1.2 秒
- **影片時長**: 159.6 秒
- **加速比**: 133x (實時 133 倍)
- **取樣間隔**: 2.0 秒
- **取樣點數**: 79 個
### 記憶體使用
- **模型大小**: 44.7 MB (ResNet18)
- **峰值記憶體**: ~2-3 GB (M4 16GB 系統)
- **MPS 加速**: 啟用
---
## 準確率評估
### 目前狀態ImageNet 模型)
- **場景名稱**: scene_XXX 格式
- **信心度**: 37%
- **準確率**: 中等(預期 60-70%
### 預期改進Places365 模型)
- **場景名稱**: 實際名稱(如 office, classroom
- **信心度**: 85-90%
- **準確率**: 高(預期 85-90%
---
## 測試結論
### ✅ 通過項目
- ✅ Rust 單元測試5/5
- ✅ Python 功能測試
- ✅ 影片場景識別
- ✅ JSON 輸出格式
- ✅ Places365 類別載入
- ✅ PyTorch MPS 加速
### ⚠️ 已知限制
- 使用 ImageNet 模型而非 Places365 專門模型
- 場景名稱為索引格式scene_XXX
- 準確率有提升空間37% → 預期 85-90%
### 📋 建議
1. 下載專門的 Places365 模型
2. 測試更多影片類型
3. 測試長影片Old_Time_Movie_Show
4. 整合到 Playground API
---
## 附錄:測試命令
```bash
# 基本功能測試
python3 scripts/test_places365_scene.py
# 影片場景識別
python3 scripts/scene_classifier.py video.mp4 output.json
# 自訂參數
python3 scripts/scene_classifier.py video.mp4 output.json \
--sample-interval 2.0 \
--min-scene-duration 3.0
# API 測試Playground 啟動後)
python3 scripts/test_scene_api.py <file_uuid>
```

View File

@@ -1,212 +0,0 @@
---
document_type: "architecture_design"
service: "MOMENTRY_CORE"
title: "視覺分片設計文檔 (Phase 2.1)"
date: "2026-04-25"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "視覺分片設計文檔"
ai_query_hints:
- "查詢 視覺分片設計文檔 (Phase 2.1) 的內容"
- "視覺分片設計文檔 (Phase 2.1) 的主要目的是什麼?"
- "如何操作或實施 視覺分片設計文檔 (Phase 2.1)"
---
# 視覺分片設計文檔 (Phase 2.1)
## 概述
視覺分片Visual Chunk是 Momentry Core 中基於 YOLO 物件檢測結果的視頻分片。它通過分析連續幀中的物件組成來創建有意義的視覺段落。
## 設計原則
1. **以實際實現為準**:當設計與代碼出現矛盾時,以實際的 Rust 代碼實現為最高權威
2. **漸進式開發**:先實現核心功能,後續逐步完善
3. **向後兼容**:不破壞現有系統的穩定性
## 數據結構
### 現有 Chunk 結構體
```rust
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Chunk {
pub file_id: i32,
pub uuid: String,
pub chunk_id: String,
pub chunk_index: u32,
pub chunk_type: ChunkType,
pub rule: ChunkRule,
pub fps: f64,
pub start_frame: i64,
pub end_frame: i64,
pub text_content: Option<String>,
pub content: serde_json::Value, // 存儲序列化的分片內容
pub metadata: Option<serde_json::Value>,
pub vector_id: Option<String>,
pub frame_count: i32,
pub pre_chunk_ids: Vec<i32>,
pub parent_chunk_id: Option<String>,
pub child_chunk_ids: Vec<String>,
pub visual_stats: Option<serde_json::Value>,
}
```
### 新增 ChunkType::Visual
```rust
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ChunkType {
TimeBased,
Sentence,
Cut,
Trace,
Story,
Visual, // 新增:視覺分片類型
}
```
### VisualChunkContent 結構體
```rust
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VisualChunkContent {
pub start_time: f64,
pub end_time: f64,
pub keyframe_objects: Vec<KeyframeObjects>,
pub dominant_objects: Vec<String>,
pub object_relationships: Vec<(String, String, String)>, // (object1, relationship, object2)
pub scene_description: Option<String>,
pub metadata: VisualMetadata,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VisualMetadata {
pub object_count: u32,
pub unique_classes: Vec<String>,
pub max_confidence: f32,
pub avg_confidence: f32,
pub spatial_density: f32, // objects per frame
}
```
## 功能設計
### 1. YOLO 結果轉換
-`YoloResult` 轉換為 `VisualChunkContent`
- 支持幀範圍過濾
- 自動計算元數據
### 2. 分片生成策略
- **固定間隔**:每 N 幀創建一個分片
- **物件相似性**:基於幀間物件相似度進行分組
- **場景變化**:檢測場景變化點(需集成 CUT 算法)
### 3. 關係檢測
- **空間關係**near, far, left, right, above, below
- **時間關係**appear, disappear, move
- **語義關係**:人與物互動關係
## 集成方案
### 階段 1概念驗證
1. 擴展 `ChunkType` 枚舉,添加 `Visual` 變體
2. 創建 `VisualChunkContent` 數據結構
3. 實現從 YOLO 結果到視覺分片的轉換邏輯
### 階段 2處理管道集成
1. 擴展現有 YOLO 處理器,支持視覺分片生成
2. 集成到處理作業流程
3. 存儲到數據庫
### 階段 3查詢優化
1. 構建視覺分片索引
2. 支持基於物件的視頻搜索
3. 集成到現有搜索 API
## 與現有系統的關係
### 現有分片類型
- **Sentence**基於語音轉文字的分片Rule 1
- **Cut**基於場景變化的分片Rule 3
- **Story**基於敘事分析的分片Rule 4
- **Visual**基於視覺物件的分片Rule 2 - 本次實現
### 數據流
```
YOLO Processor
YoloResult
VisualChunkContent (本次新增)
Chunk (chunk_type = Visual)
Database Storage
Search Index
```
## 測試策略
### 單元測試
1. `VisualChunkContent` 序列化/反序列化
2. 幀相似度計算
3. 從 YOLO 結果創建分片
### 集成測試
1. YOLO 處理器集成
2. 數據庫存儲
3. 搜索功能
## 已知問題與挑戰
### 問題 1設計與實現不一致
- **現狀**:設計文檔中的 chunk_type 值與實際 Rust 代碼存在不匹配
- **解決方案**:以實際代碼為準,更新設計文檔
### 問題 2YOLO 輸出格式複雜
- **現狀**Python 腳本輸出與 Rust 結構體需要適配
- **解決方案**:使用 `YoloPythonResult` 適配器模式
### 問題 3性能考慮
- **挑戰**:實時視覺分片生成可能消耗較多計算資源
- **優化**:批量處理、關鍵幀選擇、異步處理
## 下一步計劃
### 短期Phase 2.1 - 已完成)
- [x] 設計視覺分片數據結構
- [x] 實現基本轉換邏輯
- [x] 創建概念驗證測試
### 中期Phase 2.2
- [ ] 集成到現有 YOLO 處理器
- [ ] 實現分片存儲功能
- [ ] 添加更多輔助方法
### 長期Phase 2.3+
- [ ] 高級關係檢測
- [ ] 智能場景描述生成
- [ ] 與其他分片類型的關聯
## 參考文檔
1. **AGENTS.md** - 項目開發規範
2. **TERMINOLOGY_MAPPING.md** - 術語對照表
3. **DESIGN_IMPLEMENTATION_GAP.md** - 設計與實現差異分析
4. **ARCHITECTURE_DECISION_EXECUTION_PLAN.md** - 執行計畫
## 版本歷史
| 版本 | 日期 | 修改內容 |
|------|------|----------|
| 1.0 | 2026-04-22 | 初始版本Phase 2.1 設計完成 |
| 1.1 | 2026-04-22 | 添加測試策略和下一步計劃 |
---
**完成狀態**:✅ Phase 2.1 核心設計完成
**下一步**:修復現有 `types.rs` 文件的語法錯誤,然後進行 Phase 2.2 的處理器集成。

View File

@@ -1,202 +0,0 @@
# Processor Resume Strategy Design (Processor 續傳機制設計)
| 項目 | 內容 |
|------|------|
| 建立者 | OpenCode |
| 建立時間 | 2026-04-25 |
| 文件版本 | V1.0 |
---
## 1. 現狀分析 (Current State Analysis)
### 1.1 目前行為
目前系統的 Processor (如 YOLO, Face, OCR) **不支援高效續傳**
* **中斷處理**: 若處理過程因主動 (使用者取消) 或被動 (OOM, Crash) 中斷,重新執行時通常會**從頭開始 (Frame 0)**。
* **效能瓶頸**: 對於長影片,中斷後重新解碼和運算前 90% 的幀是巨大的資源浪費。
### 1.2 缺失環節
* **缺乏狀態記錄**: 處理器未記錄「已處理到第幾幀」。
* **缺乏增量寫入**: 輸出檔案通常為全量 JSON無法在尾部追加新數據而不破壞格式。
* **缺乏跳轉指令**: Worker 啟動腳本時未傳遞 `--start-frame` 參數。
---
## 2. 核心設計理念 (Core Concept)
設計目標:**Checkpoints (檢查點) + Append Mode (追加模式)**
* **Checkpoint**: 定期將當前進度 (`current_frame`) 寫入獨立檔案或 Redis。
* **Seek**: 啟動時若發現進度記錄,使用 OpenCV `set(CAP_PROP_POS_FRAMES)` 快速跳轉。
* **Append**: 結果輸出採用 **JSON Lines (.jsonl)** 格式,避免中斷導致 JSON 結構損壞,且支援尾部追加。
---
## 3. 資料流與協定 (Protocol)
### 3.1 檔案結構
對於一個 Video UUID (`vid_001`) 和 Processor (`yolo`),檔案佈局如下:
```text
output/vid_001/
├── vid_001.mp4
├── yolo_result.jsonl # 增量結果 (每一行是一個 Frame 的 JSON)
├── yolo_progress.json # 檢查點檔案 (記錄最後一幀的索引與時間戳)
└── yolo_final.json # (可選) 最終轉換後的完整 JSON
```
### 3.2 yolo_progress.json 結構
```json
{
"file_uuid": "vid_001",
"processor": "yolo",
"last_frame_index": 12500,
"last_timestamp": 416.66,
"total_frames": 50000,
"status": "running"
}
```
### 3.3 指令列參數協定 (CLI Arguments)
Rust Worker 在啟動 Python 腳本時,需檢測 `progress` 檔案並注入參數:
| 參數 | 類型 | 說明 |
|------|------|------|
| `--resume` | Flag | 啟用續傳模式。若無此 Flag腳本應清空舊結果並從頭開始。 |
| `--start-frame` | INT | 指定起始幀索引 (例如 `12501`)。 |
| `--output-file` | STR | 指定輸出的 JSONL 路徑。 |
| `--progress-file` | STR | 指定寫入進度的 JSON 路徑。 |
**範例指令 (Resume)**:
```bash
python3 scripts/yolo_processor.py \
--input video.mp4 \
--resume \
--start-frame 12501 \
--output-file yolo_result.jsonl \
--progress-file yolo_progress.json
```
---
## 4. 實作細節 (Implementation Details)
### 4.1 Python Script 端 (Processor)
#### A. 初始化與 Seek
```python
import cv2, json, os, sys
# 1. 解析參數
start_frame = 0
if args.resume and os.path.exists(args.progress_file):
with open(args.progress_file) as f:
progress = json.load(f)
start_frame = progress['last_frame_index'] + 1
# 2. 開啟影片並跳轉
cap = cv2.VideoCapture(args.input)
if start_frame > 0:
cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
current_frame = start_frame
else:
current_frame = 0
# 3. 開啟輸出 (Append Mode)
mode = 'a' if args.resume else 'w'
out_f = open(args.output_file, mode)
```
#### B. 循環與寫入
```python
while True:
ret, frame = cap.read()
if not ret:
break
# 處理邏輯...
result = process_frame(frame)
# 寫入 JSONL (一行一筆 JSON)
out_f.write(json.dumps({"frame": current_frame, "data": result}) + "\n")
# 更新進度 (每 N 幀寫入一次,避免 I/O 瓶頸)
if current_frame % 30 == 0:
save_progress(current_frame)
current_frame += 1
```
#### C. 信號處理 (Graceful Exit)
攔截 `SIGINT` / `SIGTERM`,確保最後一次進度被保存。
```python
import signal
def handler(signum, frame):
save_progress(current_frame)
sys.exit(0)
signal.signal(signal.SIGTERM, handler)
signal.signal(signal.SIGINT, handler)
```
### 4.2 Rust Worker 端 (Manager)
#### A. 啟動前檢查
`src/worker/processor.rs``run_processor` 函數中:
```rust
// 1. 檢查進度檔案
let progress_path = output_dir.join("yolo_progress.json");
let mut start_frame = 0;
let mut is_resume = false;
if progress_path.exists() {
if let Ok(json) = std::fs::read_to_string(&progress_path) {
if let Ok(p) = serde_json::from_str::<Value>(&json) {
if let Some(f) = p["last_frame_index"].as_i64() {
start_frame = (f + 1) as usize;
is_resume = true;
}
}
}
}
// 2. 建構指令
let mut args = vec!["--input", video_path];
if is_resume {
args.push("--resume");
args.push("--start-frame");
args.push(&start_frame.to_string());
}
// ... 其他 args
```
#### B. 後處理 (Post-Processing)
Processor 完成後,若輸出為 `.jsonl`,需轉換為系統預期的 `.json` (List of Objects) 以便存入 DB。
* *Optimization*: 可以在 Rust 端直接 `BufRead` 解析 JSONL 並批次 Insert DB無需轉換檔案。
---
## 5. 資料庫狀態更新
目前的 `monitor_jobs``processor_results` 表需支援**部分完成**的語意。
* **新增欄位**: `processed_frames` (BIGINT) 於 `processor_results``jobs` 表。
* **用途**: Worker 定期讀取 `progress.json` 並更新此欄位,以便前端顯示「處理進度 25%」。
---
## 6. 優勢分析
1. **容錯性**: 即使伺服器斷電,重啟後僅損失最近 30 幀 (約 1 秒) 的運算結果。
2. **I/O 效率**: 採用 Append 寫入,避免每次都重寫巨大的 JSON 檔案。
3. **資源節約**: OpenCV 的 `seek` 操作比重新解碼快數百倍。
4. **靈活性**: 支援主動暫停 (Pause),只需發送 `SIGINT` 讓腳本安全退出即可。
---
## 版本資訊
* 版本: V1.0
* 建立日期: 2026-04-25

View File

@@ -1,321 +0,0 @@
---
document_type: "reference_doc"
service: "MOMENTRY_CORE"
title: "Processor 升級分析報告"
date: "2026-04-27"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "processor"
- "agent"
- "upgrade"
- "identity-agent"
- "三層架構"
ai_query_hints:
- "查詢 Processor 升級分析報告的內容"
- "Processor 是否需要升級到 Agent"
- "Identity Agent 設計方案"
- "三層架構 Processor 分析"
- "Face Clustering 升級建議"
- "ASRX 升級建議"
related_documents:
- "AI_AGENTS/CORE/AGENT_SPEC.md"
- "AI_AGENTS/IDENTITY/FACE_SPEAKER_PERSON_WORKFLOW.md"
- "PROCESSORS/_CORE/PROCESSOR_RESUME_STRATEGY.md"
---
# Processor 升級分析報告
| 項目 | 內容 |
|------|------|
| 建立者 | OpenCode |
| 建立時間 | 2026-04-27 |
| 文件版本 | V1.0 |
---
## 版本歷史
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-04-27 | 分析 Processor 是否需要迭代或升級到 Agent | OpenCode | GLM-5 |
---
## 概述
本文檔分析 Momentry Core 系統中所有 Processor 的架構定位,判斷是否需要迭代或升級為 Agent。
---
## 當前狀態
| 項目 | 狀態 |
|------|------|
| Processor 總數 | 17 個 |
| 總代碼行數 | 4947 行 |
| 已添加 Resume 支持 | YOLO, OCR, Face |
| 待添加 Resume 支持 | Pose, CUT, ASRX |
---
## 1. Processor 三層架構分類
根據 `AGENT_SPEC.md` 定義的三層架構:
| 層次 | 名稱 | 特性 | 範例 |
|------|------|------|------|
| **L1** | **Processor (處理器)** | **確定性 (Deterministic)**<br>輸入 A 必得輸出 B | FFmpeg, Whisper, YOLO |
| **L2** | **Rule (規則)** | **邏輯性 (Logic)**<br>基於明確條件、正則表達式、時間軸聚合 | 語句切分,時間重疊計算 |
| **L3** | **Agent (智能體)** | **推論性 (Probabilistic)**<br>依賴 LLM 進行語義理解、決策或生成 | 5W1H 推論,身份解析 |
---
## 2. Processor 分類分析表
| Processor | 文件行數 | 當前層級 | 特性分析 | 是否需要升級 |
|-----------|----------|----------|----------|--------------|
| **asr_processor.py** | 126 | L1 (Processor) | 確定性Whisper 模型,輸入音頻→輸出文本 | ❌ 不需要升級 |
| **asrx_processor.py** | 124 | L1 (Processor) | 確定性WhisperX輸入音頻→輸出 speaker segments | ⚠️ 需與 Identity Agent 結合 |
| **yolo_processor.py** | 483 | L1 (Processor) | 確定性YOLOv8輸入帧→輸出檢測結果已支持 Resume | ❌ 不需要升級 |
| **ocr_processor.py** | 245 | L1 (Processor) | 確定性EasyOCR輸入帧→輸出文字已支持 Resume | ❌ 不需要升級 |
| **face_processor.py** | 297 | L1 (Processor) | 確定性InsightFace輸入帧→輸出人脸已支持 Resume | ❌ 不需要升級 |
| **pose_processor.py** | 178 | L1 (Processor) | 確定性YOLOv8 Pose輸入帧→輸出姿态 | ❌ 不需要升級 |
| **cut_processor.py** | 106 | L1 (Processor) | 確定性PySceneDetect輸入视频→輸出场景 | ❌ 不需要升級 |
| **face_clustering_processor.py** | 282 | **L2 (Rule)** | 邏輯性:聚类算法,將 Face ID→Person ID | ⚠️ 建議升級到 Identity Agent |
| **face_recognition_processor.py** | 648 | **L2 (Rule)** | 邏輯性:人脸匹配,將 Face→Database Person | ⚠️ 建議升級到 Identity Agent |
| **fast_face_clustering_processor.py** | 334 | L2 (Rule) | 邏輯性:快速聚类版本 | ⚠️ 建議升級到 Identity Agent |
| **story_processor.py** | 325 | **L3 (Agent)** | 推論性:需要 LLM 分析故事结构 | ✅ 已經是 Agent |
| **caption_processor.py** | 291 | L1 (Processor) | 確定性:字幕提取 | ❌ 不需要升級 |
| **lip_processor.py** | 351 | L1 (Processor) | 確定性:唇语识别 | ❌ 不需要升級 |
| **visual_chunk_processor.py** | 431 | L2 (Rule) | 邏輯性:视觉分塊邏輯 | ❌ 不需要升級 |
| **music_segmentation_processor.py** | 138 | L1 (Processor) | 確定性:音乐分割 | ❌ 不需要升級 |
| **audio_taxonomy_processor.py** | 137 | L1 (Processor) | 確定性:音频分类 | ❌ 不需要升級 |
| **unified_synonym_processor.py** | 451 | L2 (Rule) | 邏輯性:同义词扩展 | ❌ 不需要升級 |
---
## 3. 需要迭代的 Processor
### 3.1 Face Clustering Processor
| 項目 | 說明 |
|------|------|
| **當前問題** | 純聚类算法,無法處理跨場景身份識別 |
| **局限** | 1. 無法處理 Speaker 與 Face 的關聯<br>2. 無法處理時間重叠推理<br>3. 無法處理模糊、遮擋情況 |
| **迭代建議** | 升級到 **Identity Agent**Face+Speaker→Person |
| **優先級** | High |
---
### 3.2 Face Recognition Processor
| 队目 | 說明 |
|------|------|
| **當前問題** | 簡單匹配,無法處理模糊、遮擋、跨年齡識別 |
| **局限** | 1. 純 embedding 匹配,置信度低<br>2. 無法處理多證據推理<br>3. 無法處理跨場景身份關聯 |
| **迭代建議** | 升級到 **Identity Agent**(多證據推理) |
| **優先級** | High |
---
### 3.3 ASRX Processor
| 队目 | 說明 |
|------|------|
| **當前問題** | Speaker ID 與 Face ID 未關聯 |
| **局限** | 輸出 speaker segments但無法與 Person ID 绑定 |
| **迭代建議** | 需與 **Identity Agent** 結合 |
| **優先級** | Medium |
---
## 4. 建議升級到 Agent 的 Processor
### 4.1 Identity Agent核心建議
| 特性 | 說明 |
|------|------|
| **目的** | 綜合多證據Face + Speaker + 時間重叠)推論 Person Identity |
| **層級** | L3 (Agent) - 需要推理和决策 |
| **觸發條件** | Face Clustering + ASRX 完成 |
| **輸入** | pre_chunks(face), pre_chunks(asrx), face_clusters, person表 |
| **輸出** | identity 表person_id → identity_id 映射) |
| **核心邏輯** | 1. 時間重叠匹配Speaker segment vs Face frames<br>2. Embedding 相似度計算<br>3. 多證據置信度融合<br>4. LLM 推論(處理模糊情況) |
---
### 4.2 Identity Agent 設計方案
#### 4.2.1 Agent 目標
從多個 processor 的輸出中推論出「誰是誰」Who is Who
- **Face Processor**: 輸出每一帧的人脸位置和 embedding
- **ASRX Processor**:輸出每個 speaker 的時間段落
- **Face Clustering**: 輸出 Person ID聚合後的人脸群
- **Identity Agent**: 推論 Person ID → Identity Name全局身份
---
#### 4.2.2 輸入數據
```json
{
"file_uuid": "384b0ff44aaaa1f14cb2cd63b3fea966",
"person_id": "Person_17",
"face_frames": [100, 200, 300, ...],
"face_embeddings": [emb1, emb2, emb3, ...],
"speaker_segments": [
{"start": 10.5, "end": 15.2, "speaker": "SPEAKER_01"},
{"start": 20.3, "end": 25.1, "speaker": "SPEAKER_02"}
],
"face_clusters": {
"Person_17": {"frames": [100, 200, ...], "avg_embedding": emb_avg},
"Person_25": {"frames": [400, 500, ...], "avg_embedding": emb_avg}
}
}
```
---
#### 4.2.3 核心邏輯
**Step 1: 時間重叠匹配**
```python
def match_speaker_to_person(speaker_segments, person_frames, fps):
overlaps = []
for segment in speaker_segments:
start_frame = int(segment["start"] * fps)
end_frame = int(segment["end"] * fps)
overlap_frames = [f for f in person_frames if start_frame <= f <= end_frame]
overlap_ratio = len(overlap_frames) / len(person_frames)
if overlap_ratio > 0.5:
overlaps.append({
"speaker": segment["speaker"],
"person_id": person_id,
"overlap_ratio": overlap_ratio
})
return overlaps
```
**Step 2: Embedding 相似度計算**
```python
def calculate_similarity(face_emb, speaker_voice_emb):
cosine_sim = cosine_similarity(face_emb, speaker_voice_emb)
return cosine_sim
```
**Step 3: 多證據置信度融合**
```python
def fuse_evidence(face_conf, speaker_conf, time_overlap):
weighted_conf = 0.4 * face_conf + 0.3 * speaker_conf + 0.3 * time_overlap
return weighted_conf
```
**Step 4: LLM 推論(處理模糊情況)**
```python
def llm_identity_inference(evidence):
prompt = f"""
Given the following evidence:
- Face similarity: {evidence['face_sim']}
- Speaker overlap: {evidence['speaker_overlap']}
- Time overlap: {evidence['time_overlap']}
Should Person_17 and SPEAKER_01 be the same identity?
Provide confidence score and reasoning.
"""
response = llm.generate(prompt)
return response
```
---
#### 4.2.4 輸出格式
```json
{
"identity_id": "audrey_hepburn_001",
"identity_name": "Audrey Hepburn",
"person_ids": ["Person_17", "Person_25"],
"speaker_ids": ["SPEAKER_01"],
"confidence": 0.92,
"evidence": {
"face_similarity": 0.85,
"speaker_overlap": 0.78,
"time_overlap": 0.90,
"llm_reasoning": "High overlap in face and speaker segments..."
}
}
```
---
## 5. 實施計畫
### 5.1 Phase 1: Resume 功能補全(已完成部分)
| 任務 | 状态 | 預估工時 |
|------|------|----------|
| Pose Processor 添加 Resume | ⏳ 待處理 | 1h |
| CUT Processor 添加 Resume | ⏳ 待處理 | 1h |
---
### 5.2 Phase 2: Identity Agent 設計與實作
| 任務 | 預估工時 |
|------|----------|
| Identity Agent 設計文檔更新 | 2h |
| Identity Agent API 實作Rust | 6h |
| Identity Agent 核心邏輯實作Python | 4h |
| Identity Agent LLM 推論模塊 | 3h |
| Identity Agent 測試與驗證 | 2h |
**總計**: 17 小時
---
### 5.3 Phase 3: Processor 整合
| 任務 | 預估工時 |
|------|----------|
| Face Clustering → Identity Agent 輸出調整 | 2h |
| ASRX → Identity Agent 數據流調整 | 2h |
| Face Recognition → Identity Agent 整合 | 3h |
**總計**: 7 小時
---
## 6. 相關文件
| 文件 | 說明 |
|------|------|
| `AGENT_SPEC.md` | Agent 三層架構定義 |
| `FACE_SPEAKER_PERSON_WORKFLOW.md` | Identity Workflow 流程 |
| `PROCESSOR_RESUME_STRATEGY.md` | Resume 功能設計 |
| `JOB_WORKER_IMPLEMENTATION_PLAN.md` | Worker 數據流向修正計畫 |
---
## 7. 檔案位置
| 類型 | 路徑 |
|------|------|
| Processor 目錄 | `/scripts/*_processor.py` |
| Agent 設計文檔 | `/docs_v1.0/AI_AGENTS/` |
| Resume Framework | `/scripts/resume_framework.py` |
---
## 版本資訊
- 版本: V1.0
- 建立日期: 2026-04-27

View File

@@ -1,151 +0,0 @@
# Rule Specification & Data Flow (規則規範與數據流)
| 項目 | 內容 |
|------|------|
| 建立者 | OpenCode |
| 建立時間 | 2026-04-25 |
| 文件版本 | V1.0 |
---
## 版本歷史
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-04-25 | 定義 Rule 的 Input/Logic/Output 及依賴關係 (DAG) | OpenCode | OpenCode |
---
## 1. 核心概念
**Rule (規則)** 負責將 **Processor** 產出的原始數據 (`pre_chunks`) 聚合、過濾、推論為有意義的 **Chunks**
### 1.1 數據流向
```mermaid
graph LR
Video((Video File)) -->|Process| P1[Processor: YOLO/Face/OCR]
Video -->|Process| P2[Processor: ASR/CUT]
P1 -->|JSON/JSONL| DB[(pre_chunks)]
P2 -->|JSON/JSONL| DB
DB -->|Read| R1[Rule 1: Sentence]
DB -->|Read| R2[Rule 2: Visual]
DB -->|Read| R3[Rule 3: Scene]
R1 -->|Write| Chunks[(chunks)]
R2 -->|Write| Chunks
R3 -->|Write| Chunks
Chunks -->|Read| Agent[AI Agent: 5W1H/Summary]
Agent -->|Update| Chunks
```
---
## 2. 依賴管理 (DAG)
為了解決依賴關係糾結的問題,系統採用 **顯式依賴宣告 (Explicit Dependency Declaration)**
Job Worker 根據此配置決定何時觸發 Rule。
```json
{
"rules": [
{
"rule_id": "rule_1_sentence",
"description": "語句級聚合 (基於 ASR)",
"dependencies": ["processor_asr"],
"agent_involved": false
},
{
"rule_id": "rule_2_visual",
"description": "視覺片段聚合 (基於 YOLO/Face)",
"dependencies": ["processor_yolo", "processor_face"],
"agent_involved": false
},
{
"rule_id": "rule_3_scene",
"description": "場景級聚合 (基於 CUT + ASR 對齊)",
"dependencies": ["processor_cut", "processor_asr"],
"agent_involved": false
},
{
"rule_id": "rule_4_summary",
"description": "生成段落摘要 (依賴所有 Rule 1-3 完成)",
"dependencies": ["rule_1_sentence", "rule_3_scene"],
"agent_involved": true
}
]
}
```
**觸發邏輯**:
*`dependencies` 中列出的所有項目狀態變為 `completed` 時,觸發該 Rule。
---
## 3. Rule 詳細定義
### 3.1 Rule 1: Sentence (語句聚合)
* **用途**: 將 ASR 的逐字/逐句輸出聚合為可搜尋的文本 Chunk。
* **Input**: `pre_chunks` 表中 `processor_type = 'asr'` 的紀錄。
* **Logic**:
1. 按時間順序讀取 ASR segments。
2. (可選) 結合物件標籤 (YOLO) 豐富 metadata。
3. 生成 `ChunkType::Sentence`
* **Output**: 寫入 `chunks` 表。
### 3.2 Rule 2: Visual (視覺聚合)
* **用途**: 將零散的 Frame 聚合為有意義的視覺事件 (例如:「某人出現在畫面中 5 秒」)。
* **Input**:
* `pre_chunks` 表中 `processor_type = 'yolo'` 的紀錄。
* `pre_chunks` 表中 `processor_type = 'face'` 的紀錄。
* **Logic**:
1. **滑動視窗**: 若連續 N 幀都偵測到同一 Identity視為一個 Visual Chunk。
2. **事件過濾**: 忽略低於信心度閾值的偵測。
3. 生成 `ChunkType::Visual`
* **Output**: 寫入 `chunks` 表。
### 3.3 Rule 3: Scene (場景聚合)
* **用途**: 基於鏡頭切換 (CUT) 與語音內容,定義場景邊界。
* **Input**:
* `pre_chunks` 表中 `processor_type = 'cut'` 的紀錄。
* `chunks` 表中 Rule 1 產生的 Sentence Chunks (用於填充場景內容)。
* **Logic**:
1. 讀取 CUT 偵測到的 Scene 邊界。
2. 將該時間段內的所有 Rule 1 Chunks 關聯到此 Scene。
3. 生成 `ChunkType::Scene`
* **Output**: 寫入 `chunks` 表。
### 3.4 Rule 4: Summary / Agent (AI 摘要)
* **用途**: 利用 LLM 生成場景或影片的摘要、5W1H 標籤。
* **Input**: `chunks` 表中已完成的 Scene/Sentence Chunks。
* **Logic**:
1. 收集 Chunk 的文本、視覺標籤。
2. 調用 **Translation/Summary Agent**
3. 將生成的摘要與標籤更新回 `chunks` 表的 `metadata` 欄位。
* **Output**: 更新 `chunks` 表 (In-place Update)。
---
## 4. Agent 在 Rule 中的角色
AI Agent 不再是獨立的「黑盒子」,而是作為 Rule 的執行引擎之一。
* **Prompt Injection**: Rule 負責組裝 Context (Input Chunks),注入預定義的 Prompt Template。
* **Structured Output**: Agent 必須輸出符合 Schema 的 JSON以便 Rust 寫入資料庫。
**範例 (Rule 4 摘要)**:
> "You are a movie analyst. Based on the following dialogue and visual tags, summarize the scene in 50 words and extract the 5W1H entities."
---
## 版本資訊
* 版本: V1.0
* 建立日期: 2026-04-25