docs: update docs_v1.0/ documentation
- Fix markdown lint issues (MD030, MD047, MD051, MD028, MD005) - Update AI agents, architecture, implementation docs - Add new identity, face recognition, and API documentation - Remove deprecated face/person API guides
This commit is contained in:
@@ -287,4 +287,4 @@ MOMENTRY_POSE_MAX_PERSONS=10
|
||||
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
|
||||
4. [AGENTS.md](../../AGENTS.md) - Updated configuration documentation
|
||||
|
||||
@@ -385,7 +385,7 @@ refrigerator, book, clock, vase, scissors, teddy bear, hair drier, toothbrush
|
||||
```sql
|
||||
-- 存储到 MongoDB (非结构化数据)
|
||||
db.yolo_frames.insertOne({
|
||||
uuid: "384b0ff44aaaa1f1",
|
||||
uuid: "384b0ff44aaaa1f14cb2cd63b3fea966",
|
||||
frame_number: 0,
|
||||
objects: [...]
|
||||
})
|
||||
@@ -1162,4 +1162,4 @@ CREATE TABLE person_appearances (
|
||||
---
|
||||
|
||||
**维护者**: OpenCode
|
||||
**最后更新**: 2026-04-09
|
||||
**最后更新**: 2026-04-09
|
||||
|
||||
@@ -454,4 +454,4 @@ python3 -c "import torch; print(torch.__version__)"
|
||||
# MPS支持
|
||||
python3 -c "import torch; print(torch.backends.mps.is_available())"
|
||||
# True
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Momentry Core Processors 快速参考
|
||||
|
||||
**更新日期**: 2026-04-09
|
||||
**更新日期**: 2026-04-28
|
||||
|
||||
---
|
||||
|
||||
@@ -13,16 +13,18 @@
|
||||
| 3 | **CUT** | 场景检测 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | PySceneDetect |
|
||||
| 4 | **YOLO** | 物体检测 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | YOLOv8 |
|
||||
| 5 | **OCR** | 文字识别 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | PaddleOCR |
|
||||
| 6 | **Face** | 人脸检测 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | RetinaFace |
|
||||
| 6 | **Face** | 人脸检测 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | InsightFace ⭐ |
|
||||
| 7 | **Pose** | 姿态估计 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | MediaPipe |
|
||||
| 8 | **Scene** | 场景分类 | ✅ 100% | ✅ | ✅ | ✅ | ⚠️ | **MIT Places365** |
|
||||
| 8 | **Scene** | 场景分类 | ✅ 100% | ✅ | ✅ | ✅ | ✅ | **MIT Places365** ⭐ |
|
||||
| 9 | **Caption** | 字幕生成 | ✅ 100% | ✅ | ✅ | ✅ | ⚠️ | GPT-4V (付费) |
|
||||
| 10 | **Story** | 故事生成 | ✅ 100% | ✅ | ✅ | ✅ | ⚠️ | GPT-4 (付费) |
|
||||
|
||||
**统计**:
|
||||
- ✅ 完成: 9/10 (90%)
|
||||
- ✅ 完成: 8/10 (80%)
|
||||
- ⚠️ 修复中: 1/10 (10%)
|
||||
- ⚠️ 待数据库: 2/10 (20%)
|
||||
- 💰 付费 API: 2/10 (Caption, Story)
|
||||
- ⭐ Benchmark完成: 4/10 (Face, YOLO, CUT, Scene)
|
||||
|
||||
---
|
||||
|
||||
@@ -34,7 +36,7 @@
|
||||
python3 scripts/asr_processor.py video.mp4 output.json
|
||||
|
||||
# API
|
||||
curl http://localhost:3002/api/v1/asr/384b0ff44aaaa1f1
|
||||
curl http://localhost:3002/api/v1/asr/384b0ff44aaaa1f14cb2cd63b3fea966
|
||||
|
||||
# 示例
|
||||
ExaSAN: 78 segments, 15KB
|
||||
@@ -47,7 +49,7 @@ Charade: 1826 segments, 198KB
|
||||
python3 scripts/asrx_processor_custom.py video.mp4 output.json
|
||||
|
||||
# API
|
||||
curl http://localhost:3002/api/v1/asrx/384b0ff44aaaa1f1
|
||||
curl http://localhost:3002/api/v1/asrx/384b0ff44aaaa1f14cb2cd63b3fea966
|
||||
|
||||
# 测试结果
|
||||
Charade: 1118 segments, 8 speakers, 99.82% match rate
|
||||
@@ -63,7 +65,7 @@ Charade: 1118 segments, 8 speakers, 99.82% match rate
|
||||
python3 scripts/cut_processor.py video.mp4 output.json
|
||||
|
||||
# API
|
||||
curl http://localhost:3002/api/v1/cut/384b0ff44aaaa1f1
|
||||
curl http://localhost:3002/api/v1/cut/384b0ff44aaaa1f14cb2cd63b3fea966
|
||||
|
||||
# 示例
|
||||
Charade: 1331 scenes, 217KB
|
||||
@@ -76,7 +78,7 @@ ExaSAN: 18 scenes, 2KB
|
||||
python3 scripts/yolo_processor.py video.mp4 output.json
|
||||
|
||||
# API
|
||||
curl http://localhost:3002/api/v1/yolo/384b0ff44aaaa1f1
|
||||
curl http://localhost:3002/api/v1/yolo/384b0ff44aaaa1f14cb2cd63b3fea966
|
||||
|
||||
# 示例
|
||||
Charade: 127MB, 15234 objects, 80 classes
|
||||
@@ -232,11 +234,17 @@ cargo run -- process video.mp4 --modules asr --force
|
||||
## 待办事项
|
||||
|
||||
### 高优先级
|
||||
- [x] Scene: 添加数据库存储 ✅ (2026-04-28)
|
||||
- [ ] ASRX: 切换到自定义 SpeechBrain 实现
|
||||
- [ ] Scene: 添加数据库存储
|
||||
- [ ] 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 错误处理
|
||||
- [ ] 添加批量处理接口
|
||||
@@ -244,4 +252,4 @@ cargo run -- process video.mp4 --modules asr --force
|
||||
|
||||
---
|
||||
|
||||
**详细文档**: `docs/PROCESSOR_IMPLEMENTATION_STATUS.md`
|
||||
**详细文档**: `docs/PROCESSOR_IMPLEMENTATION_STATUS.md`
|
||||
|
||||
430
docs_v1.0/PROCESSORS/CORE/YOLO_PROCESSOR_TECHNICAL_REVIEW.md
Normal file
430
docs_v1.0/PROCESSORS/CORE/YOLO_PROCESSOR_TECHNICAL_REVIEW.md
Normal file
@@ -0,0 +1,430 @@
|
||||
# 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.py(MPS版本)
|
||||
|
||||
#### 技术栈
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **引擎** | ultralytics YOLOv8 |
|
||||
| **模型** | yolov8n.pt(默认nano) |
|
||||
| **设备** | MPS(Metal 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.py(Contract版本)
|
||||
|
||||
#### 技术栈
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **引擎** | 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 | **最快** ⭐⭐⭐ | 较低 | 实时检测 |
|
||||
| yolov8s(small) | 11.2M | 640 | 快 ⭐⭐ | 中等 | 平衡方案 |
|
||||
| yolov8m(medium) | 25.9M | 640 | 中等 | 高 ⭐⭐ | 精度优先 |
|
||||
| yolov8l(large) | 43.7M | 640 | 慢 | 很高 ⭐⭐⭐ | 最高精度 |
|
||||
| yolov8x(extra) | 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版本** | ✅ 已实现(标准化) |
|
||||
| **默认模型** | yolov8n(nano) |
|
||||
|
||||
---
|
||||
|
||||
### 推荐方案
|
||||
|
||||
| 场景 | 推荐 | 优先级 |
|
||||
|------|------|--------|
|
||||
| **生产环境** | 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版本
|
||||
@@ -198,4 +198,4 @@ The ASR processor (`scripts/asr_processor.py`) serves as the reference implement
|
||||
|
||||
### Version 1.0 (2025-03-27)
|
||||
- Initial contract definition
|
||||
- Based on ASR processor refactoring experience
|
||||
- Based on ASR processor refactoring experience
|
||||
|
||||
@@ -250,4 +250,4 @@ python3 verify_processor_compliance.py --output report.md
|
||||
- Initial compliance checklist created
|
||||
- 3/5 processors at 100% compliance
|
||||
- Automated verification tool created
|
||||
- Comprehensive documentation structure established
|
||||
- Comprehensive documentation structure established
|
||||
|
||||
@@ -39,17 +39,17 @@ ai_query_hints:
|
||||
|
||||
為確保所有處理器(ASR, OCR, Face, YOLO, Cut)產出的時間軸精確且一致,本規範定義以下核心原則:
|
||||
|
||||
1. **幀為本位 (Frame-Based)**:
|
||||
* 所有時間計算的**唯一權威來源**是幀編號 (`frame_number`)。
|
||||
* 開始時間、結束時間、長度皆以幀為單位 (`start_frame`, `end_frame`, `length_frames`)。
|
||||
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` 探針結果嚴格一致。
|
||||
2. **秒數為參考 (Timestamp is Derived)**:
|
||||
* 秒數 (`timestamp_sec`, `start_time_sec`) 僅供人類閱讀與外部 API 參考。
|
||||
* 計算公式:`time = frame / fps`。
|
||||
* FPS 資訊必須與 `ffprobe` 探針結果嚴格一致。
|
||||
|
||||
3. **結構統一**:
|
||||
* 產出分為兩大層級:**Frame (單幀檢測)** 與 **Pre-Chunk (時間區間聚合)**。
|
||||
3. **結構統一**:
|
||||
* 產出分為兩大層級:**Frame (單幀檢測)** 與 **Pre-Chunk (時間區間聚合)**。
|
||||
|
||||
---
|
||||
|
||||
@@ -121,8 +121,8 @@ ai_query_hints:
|
||||
### 2.1 ASR (語音識別) -> Pre-Chunk
|
||||
ASR 產出主要是文字片段,因此歸類為 `Pre-Chunk`。
|
||||
|
||||
* **輸出檔名**: `{uuid}_asr.json`
|
||||
* **結構**: Array of Pre-Chunk
|
||||
* **輸出檔名**: `{uuid}_asr.json`
|
||||
* **結構**: Array of Pre-Chunk
|
||||
|
||||
```json
|
||||
[
|
||||
@@ -144,8 +144,8 @@ ASR 產出主要是文字片段,因此歸類為 `Pre-Chunk`。
|
||||
### 2.2 Face (人臉偵測) -> Frame
|
||||
人臉位置可能每幀微動,因此以 `Frame` 記錄最精確。
|
||||
|
||||
* **輸出檔名**: `{uuid}_faces.json`
|
||||
* **結構**: Object containing Array of Frames
|
||||
* **輸出檔名**: `{uuid}_faces.json`
|
||||
* **結構**: Object containing Array of Frames
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -170,8 +170,8 @@ ASR 產出主要是文字片段,因此歸類為 `Pre-Chunk`。
|
||||
### 2.3 OCR (文字辨識) -> Frame
|
||||
通常以抽樣 (Sample) 方式進行 (如每 30 幀抽 1 幀)。
|
||||
|
||||
* **輸出檔名**: `{uuid}_ocr.json`
|
||||
* **結構**: Array of Frames
|
||||
* **輸出檔名**: `{uuid}_ocr.json`
|
||||
* **結構**: Array of Frames
|
||||
|
||||
```json
|
||||
[
|
||||
@@ -191,8 +191,8 @@ ASR 產出主要是文字片段,因此歸類為 `Pre-Chunk`。
|
||||
### 2.4 Cut (鏡頭切割) -> Pre-Chunk
|
||||
鏡頭切割定義了場景的邊界,是典型的 Pre-Chunk。
|
||||
|
||||
* **輸出檔名**: `{uuid}_cuts.json`
|
||||
* **結構**: Array of Pre-Chunk
|
||||
* **輸出檔名**: `{uuid}_cuts.json`
|
||||
* **結構**: Array of Pre-Chunk
|
||||
|
||||
```json
|
||||
[
|
||||
@@ -215,10 +215,10 @@ ASR 產出主要是文字片段,因此歸類為 `Pre-Chunk`。
|
||||
|
||||
為確保產出符合規範,寫入資料庫前需執行以下檢查:
|
||||
|
||||
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`
|
||||
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`
|
||||
|
||||
---
|
||||
|
||||
@@ -227,9 +227,9 @@ ASR 產出主要是文字片段,因此歸類為 `Pre-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` 表 (具備語意向量)
|
||||
* **Input**: 多個 Pre-chunks / Frames
|
||||
* **Process**: 合併 (Merge)、摘要 (Summarize)、嵌入 (Embedding)
|
||||
* **Output**: `chunks` 表 (具備語意向量)
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
@@ -490,4 +490,4 @@ pub mod ocr {
|
||||
|
||||
*Template Version: 1.0*
|
||||
*Last Updated: 2026-03-27*
|
||||
*Based on: AI-Driven Processor Contract v1.0*
|
||||
*Based on: AI-Driven Processor Contract v1.0*
|
||||
|
||||
@@ -465,16 +465,16 @@ class UnifiedAudioProcessor:
|
||||
```python
|
||||
# Mac Studio 多處理器並行
|
||||
class ParallelVideoProcessor:
|
||||
def process_all(self, video_uuid):
|
||||
def process_all(self, file_uuid):
|
||||
# 同時運行所有處理器
|
||||
with ThreadPoolExecutor(max_workers=8) as executor:
|
||||
futures = {
|
||||
"audio": executor.submit(self.run_asrx, video_uuid),
|
||||
"ocr": executor.submit(self.run_ocr, video_uuid),
|
||||
"yolo": executor.submit(self.run_yolo, video_uuid),
|
||||
"face": executor.submit(self.run_face, video_uuid),
|
||||
"pose": executor.submit(self.run_pose, video_uuid),
|
||||
"scene": executor.submit(self.run_scene, video_uuid)
|
||||
"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()}
|
||||
@@ -486,7 +486,7 @@ class ParallelVideoProcessor:
|
||||
# 新 API 端點
|
||||
POST /api/v1/process
|
||||
{
|
||||
"video_uuid": "...",
|
||||
"file_uuid": "...",
|
||||
"processors": ["audio"], # 統一使用 ASRX large
|
||||
"mode": "auto" # 或 "fast" / "professional"
|
||||
}
|
||||
@@ -494,7 +494,7 @@ POST /api/v1/process
|
||||
# 向下兼容
|
||||
POST /api/v1/process
|
||||
{
|
||||
"video_uuid": "...",
|
||||
"file_uuid": "...",
|
||||
"processors": ["asr"] # 自動映射到 "standard" profile
|
||||
}
|
||||
```
|
||||
@@ -618,4 +618,4 @@ python3 scripts/test_stability_24h.py
|
||||
- 處理速度:提升 3-5 倍
|
||||
- 用戶等待時間:減少 70-80%
|
||||
- 維護成本:降低 50%
|
||||
- 功能完整性:100%(所有功能啟用)
|
||||
- 功能完整性:100%(所有功能啟用)
|
||||
|
||||
@@ -162,7 +162,7 @@ ai_query_hints:
|
||||
|
||||
## 💡 使用建議
|
||||
|
||||
### 推薦使用自實作 ASRX 如果:
|
||||
### 推薦使用自實作 ASRX 如果
|
||||
|
||||
- ✅ 需要快速處理(96x 實時)
|
||||
- ✅ 不想配置 HuggingFace token
|
||||
@@ -172,7 +172,7 @@ ai_query_hints:
|
||||
|
||||
---
|
||||
|
||||
### 推薦使用 pyannote.audio 如果:
|
||||
### 推薦使用 pyannote.audio 如果
|
||||
|
||||
- ✅ 需要最高準確度(90-95%)
|
||||
- ✅ 需要處理重疊說話
|
||||
|
||||
@@ -917,4 +917,4 @@ python -c "from speechbrain.inference.speaker import EncoderClassifier; print('S
|
||||
---
|
||||
|
||||
**更新日誌:**
|
||||
- 2026-04-06: V1.0 初始版本,完整分析 ASR/ASRX 和聲紋模型
|
||||
- 2026-04-06: V1.0 初始版本,完整分析 ASR/ASRX 和聲紋模型
|
||||
|
||||
@@ -222,4 +222,4 @@ class ASRProcessor:
|
||||
|
||||
*Document Version: 1.0*
|
||||
*Last Updated: 2026-03-27*
|
||||
*Next Review: 2026-04-27*
|
||||
*Next Review: 2026-04-27*
|
||||
|
||||
@@ -182,4 +182,4 @@ def get_whisper_model(model_name="base"):
|
||||
|
||||
*Last Updated: 2026-03-27*
|
||||
*Status: Planning Phase*
|
||||
*Owner: Warren (Technical Lead)*
|
||||
*Owner: Warren (Technical Lead)*
|
||||
|
||||
@@ -345,4 +345,4 @@ ASR (tiny) < ASR (base) < ASRX < ASRX (large)
|
||||
|
||||
- [faster-whisper](https://github.com/SYSTRAN/faster-whisper)
|
||||
- [whisperx](https://github.com/m-bain/whisperX)
|
||||
- [pyannote.audio](https://github.com/pyannote/pyannote-audio)
|
||||
- [pyannote.audio](https://github.com/pyannote/pyannote-audio)
|
||||
|
||||
@@ -526,7 +526,7 @@ config/audio_profiles.json
|
||||
# API 端點
|
||||
POST /api/v1/process
|
||||
{
|
||||
"video_uuid": "...",
|
||||
"file_uuid": "...",
|
||||
"processors": ["audio"],
|
||||
"audio_config": {
|
||||
"profile": "diarized" # 或自定義配置
|
||||
@@ -536,7 +536,7 @@ POST /api/v1/process
|
||||
# 向下兼容
|
||||
POST /api/v1/process
|
||||
{
|
||||
"video_uuid": "...",
|
||||
"file_uuid": "...",
|
||||
"processors": ["asr"] # 自動使用 "standard" profile
|
||||
}
|
||||
```
|
||||
@@ -783,4 +783,4 @@ def main():
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
```
|
||||
|
||||
@@ -422,28 +422,28 @@ impl VideoProcessor {
|
||||
# 快速轉錄(預設)
|
||||
POST /api/v1/process
|
||||
{
|
||||
"video_uuid": "...",
|
||||
"file_uuid": "...",
|
||||
"processors": ["asr"] # 使用 ASR tiny
|
||||
}
|
||||
|
||||
# 準確轉錄
|
||||
POST /api/v1/process
|
||||
{
|
||||
"video_uuid": "...",
|
||||
"file_uuid": "...",
|
||||
"processors": ["asr:medium"]
|
||||
}
|
||||
|
||||
# 說話人分離
|
||||
POST /api/v1/process
|
||||
{
|
||||
"video_uuid": "...",
|
||||
"file_uuid": "...",
|
||||
"processors": ["asrx"] # 使用 ASRX base
|
||||
}
|
||||
|
||||
# 完整分析
|
||||
POST /api/v1/process
|
||||
{
|
||||
"video_uuid": "...",
|
||||
"file_uuid": "...",
|
||||
"processors": ["asrx:large"]
|
||||
}
|
||||
```
|
||||
@@ -501,4 +501,4 @@ AudioProcessor
|
||||
- 統一 API
|
||||
- 靈活配置
|
||||
- 向下兼容
|
||||
- 降低維護複雜度
|
||||
- 降低維護複雜度
|
||||
|
||||
@@ -655,4 +655,4 @@ pip install opencv-python
|
||||
---
|
||||
|
||||
**更新日誌:**
|
||||
- 2026-04-06: V1.0 初始版本,完整分析三種模型
|
||||
- 2026-04-06: V1.0 初始版本,完整分析三種模型
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
- `GET /api/v1/face/list`: 列出所有人臉身份
|
||||
- `GET /api/v1/face/{face_id}`: 獲取人臉詳情
|
||||
- `DELETE /api/v1/face/{face_id}`: 刪除人臉身份
|
||||
- `GET /api/v1/face/results/{video_uuid}`: 獲取處理結果
|
||||
- `GET /api/v1/face/results/{file_uuid}`: 獲取處理結果
|
||||
|
||||
### ✅ 6. 數據庫函數
|
||||
- `find_similar_faces()`: 向量相似度搜索
|
||||
@@ -137,7 +137,7 @@ curl -X POST http://localhost:3002/api/v1/face/register \
|
||||
curl -X POST http://localhost:3002/api/v1/face/recognize \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"video_uuid": "video-123",
|
||||
"file_uuid": "video-123",
|
||||
"enable_recognition": true,
|
||||
"enable_tracking": true
|
||||
}'
|
||||
@@ -215,4 +215,4 @@ export MOMENTRY_LOG_LEVEL=debug
|
||||
**系統狀態**: ✅ 生產就緒
|
||||
**測試覆蓋率**: ✅ 全面測試
|
||||
**文檔完整性**: ✅ 完整文檔
|
||||
**性能表現**: ✅ 優化完成
|
||||
**性能表現**: ✅ 優化完成
|
||||
|
||||
@@ -331,4 +331,4 @@ GET /api/v1/images/{uuid}/metadata
|
||||
**最後更新**: 2026-04-22
|
||||
**版本**: V1.0
|
||||
**狀態**: 設計階段
|
||||
**優先級**: 中
|
||||
**優先級**: 中
|
||||
|
||||
@@ -129,7 +129,7 @@ python3 scripts/scene_classifier.py \
|
||||
|
||||
3. **測試長影片**
|
||||
- 測試 Old_Time_Movie_Show (114 分鐘)
|
||||
- 評估記憶體使用和處理時間
|
||||
- 評估記憶體使用和處理時間
|
||||
|
||||
### 中期(1 週)
|
||||
|
||||
@@ -150,7 +150,7 @@ python3 scripts/scene_classifier.py \
|
||||
- 效能基準測試
|
||||
- 使用者回饋收集
|
||||
|
||||
7. **優化與部署**
|
||||
2. **優化與部署**
|
||||
- 根據測試結果優化
|
||||
- 文檔完善
|
||||
- 生產環境部署
|
||||
|
||||
@@ -147,5 +147,5 @@ python3 scripts/scene_classifier.py video.mp4 output.json \
|
||||
--min-scene-duration 3.0
|
||||
|
||||
# API 測試(Playground 啟動後)
|
||||
python3 scripts/test_scene_api.py <video_uuid>
|
||||
python3 scripts/test_scene_api.py <file_uuid>
|
||||
```
|
||||
|
||||
@@ -209,4 +209,4 @@ Search Index
|
||||
|
||||
**完成狀態**:✅ Phase 2.1 核心設計完成
|
||||
|
||||
**下一步**:修復現有 `types.rs` 文件的語法錯誤,然後進行 Phase 2.2 的處理器集成。
|
||||
**下一步**:修復現有 `types.rs` 文件的語法錯誤,然後進行 Phase 2.2 的處理器集成。
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
|
||||
### 1.1 目前行為
|
||||
目前系統的 Processor (如 YOLO, Face, OCR) **不支援高效續傳**。
|
||||
* **中斷處理**: 若處理過程因主動 (使用者取消) 或被動 (OOM, Crash) 中斷,重新執行時通常會**從頭開始 (Frame 0)**。
|
||||
* **效能瓶頸**: 對於長影片,中斷後重新解碼和運算前 90% 的幀是巨大的資源浪費。
|
||||
* **中斷處理**: 若處理過程因主動 (使用者取消) 或被動 (OOM, Crash) 中斷,重新執行時通常會**從頭開始 (Frame 0)**。
|
||||
* **效能瓶頸**: 對於長影片,中斷後重新解碼和運算前 90% 的幀是巨大的資源浪費。
|
||||
|
||||
### 1.2 缺失環節
|
||||
* **缺乏狀態記錄**: 處理器未記錄「已處理到第幾幀」。
|
||||
* **缺乏增量寫入**: 輸出檔案通常為全量 JSON,無法在尾部追加新數據而不破壞格式。
|
||||
* **缺乏跳轉指令**: Worker 啟動腳本時未傳遞 `--start-frame` 參數。
|
||||
* **缺乏狀態記錄**: 處理器未記錄「已處理到第幾幀」。
|
||||
* **缺乏增量寫入**: 輸出檔案通常為全量 JSON,無法在尾部追加新數據而不破壞格式。
|
||||
* **缺乏跳轉指令**: Worker 啟動腳本時未傳遞 `--start-frame` 參數。
|
||||
|
||||
---
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
|
||||
設計目標:**Checkpoints (檢查點) + Append Mode (追加模式)**
|
||||
|
||||
* **Checkpoint**: 定期將當前進度 (`current_frame`) 寫入獨立檔案或 Redis。
|
||||
* **Seek**: 啟動時若發現進度記錄,使用 OpenCV `set(CAP_PROP_POS_FRAMES)` 快速跳轉。
|
||||
* **Append**: 結果輸出採用 **JSON Lines (.jsonl)** 格式,避免中斷導致 JSON 結構損壞,且支援尾部追加。
|
||||
* **Checkpoint**: 定期將當前進度 (`current_frame`) 寫入獨立檔案或 Redis。
|
||||
* **Seek**: 啟動時若發現進度記錄,使用 OpenCV `set(CAP_PROP_POS_FRAMES)` 快速跳轉。
|
||||
* **Append**: 結果輸出採用 **JSON Lines (.jsonl)** 格式,避免中斷導致 JSON 結構損壞,且支援尾部追加。
|
||||
|
||||
---
|
||||
|
||||
@@ -48,7 +48,7 @@ output/vid_001/
|
||||
### 3.2 yolo_progress.json 結構
|
||||
```json
|
||||
{
|
||||
"video_uuid": "vid_001",
|
||||
"file_uuid": "vid_001",
|
||||
"processor": "yolo",
|
||||
"last_frame_index": 12500,
|
||||
"last_timestamp": 416.66,
|
||||
@@ -174,7 +174,7 @@ if is_resume {
|
||||
|
||||
#### B. 後處理 (Post-Processing)
|
||||
Processor 完成後,若輸出為 `.jsonl`,需轉換為系統預期的 `.json` (List of Objects) 以便存入 DB。
|
||||
* *Optimization*: 可以在 Rust 端直接 `BufRead` 解析 JSONL 並批次 Insert DB,無需轉換檔案。
|
||||
* *Optimization*: 可以在 Rust 端直接 `BufRead` 解析 JSONL 並批次 Insert DB,無需轉換檔案。
|
||||
|
||||
---
|
||||
|
||||
@@ -182,21 +182,21 @@ Processor 完成後,若輸出為 `.jsonl`,需轉換為系統預期的 `.json
|
||||
|
||||
目前的 `monitor_jobs` 和 `processor_results` 表需支援**部分完成**的語意。
|
||||
|
||||
* **新增欄位**: `processed_frames` (BIGINT) 於 `processor_results` 或 `jobs` 表。
|
||||
* **用途**: Worker 定期讀取 `progress.json` 並更新此欄位,以便前端顯示「處理進度 25%」。
|
||||
* **新增欄位**: `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` 讓腳本安全退出即可。
|
||||
1. **容錯性**: 即使伺服器斷電,重啟後僅損失最近 30 幀 (約 1 秒) 的運算結果。
|
||||
2. **I/O 效率**: 採用 Append 寫入,避免每次都重寫巨大的 JSON 檔案。
|
||||
3. **資源節約**: OpenCV 的 `seek` 操作比重新解碼快數百倍。
|
||||
4. **靈活性**: 支援主動暫停 (Pause),只需發送 `SIGINT` 讓腳本安全退出即可。
|
||||
|
||||
---
|
||||
|
||||
## 版本資訊
|
||||
|
||||
- 版本: V1.0
|
||||
- 建立日期: 2026-04-25
|
||||
* 版本: V1.0
|
||||
* 建立日期: 2026-04-25
|
||||
|
||||
321
docs_v1.0/PROCESSORS/_CORE/PROCESSOR_UPGRADE_ANALYSIS.md
Normal file
321
docs_v1.0/PROCESSORS/_CORE/PROCESSOR_UPGRADE_ANALYSIS.md
Normal file
@@ -0,0 +1,321 @@
|
||||
---
|
||||
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
|
||||
@@ -81,7 +81,7 @@ Job Worker 根據此配置決定何時觸發 Rule。
|
||||
```
|
||||
|
||||
**觸發邏輯**:
|
||||
* 當 `dependencies` 中列出的所有項目狀態變為 `completed` 時,觸發該 Rule。
|
||||
* 當 `dependencies` 中列出的所有項目狀態變為 `completed` 時,觸發該 Rule。
|
||||
|
||||
---
|
||||
|
||||
@@ -89,47 +89,47 @@ Job Worker 根據此配置決定何時觸發 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` 表。
|
||||
* **用途**: 將 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` 表。
|
||||
* **用途**: 將零散的 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` 表。
|
||||
* **用途**: 基於鏡頭切換 (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)。
|
||||
* **用途**: 利用 LLM 生成場景或影片的摘要、5W1H 標籤。
|
||||
* **Input**: `chunks` 表中已完成的 Scene/Sentence Chunks。
|
||||
* **Logic**:
|
||||
1. 收集 Chunk 的文本、視覺標籤。
|
||||
2. 調用 **Translation/Summary Agent**。
|
||||
3. 將生成的摘要與標籤更新回 `chunks` 表的 `metadata` 欄位。
|
||||
* **Output**: 更新 `chunks` 表 (In-place Update)。
|
||||
|
||||
---
|
||||
|
||||
@@ -137,8 +137,8 @@ Job Worker 根據此配置決定何時觸發 Rule。
|
||||
|
||||
AI Agent 不再是獨立的「黑盒子」,而是作為 Rule 的執行引擎之一。
|
||||
|
||||
* **Prompt Injection**: Rule 負責組裝 Context (Input Chunks),注入預定義的 Prompt Template。
|
||||
* **Structured Output**: Agent 必須輸出符合 Schema 的 JSON,以便 Rust 寫入資料庫。
|
||||
* **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."
|
||||
@@ -147,5 +147,5 @@ AI Agent 不再是獨立的「黑盒子」,而是作為 Rule 的執行引擎
|
||||
|
||||
## 版本資訊
|
||||
|
||||
- 版本: V1.0
|
||||
- 建立日期: 2026-04-25
|
||||
* 版本: V1.0
|
||||
* 建立日期: 2026-04-25
|
||||
|
||||
Reference in New Issue
Block a user