顶点项目 12 —— 视频理解流水线(场景、问答、搜索)
Twelve Labs 把 Marengo + Pegasus 产品化了。VideoDB 出了 CRUD-for-video 的 API。AI2 的 Molmo 2 发布了开源 VLM checkpoint。Gemini 长上下文原生处理数小时的视频。TimeLens-100K 在规模上定义了时间定位。2026 年的流水线已经定型:场景切分、逐场景 caption + embedding、转写对齐、多向量索引,以及一个用 (start, end) 时间戳加帧预览作答的查询。这个顶点项目就是摄入 100 小时、刷公开基准、并衡量计数和动作类问题上的幻觉。
类型: Capstone 语言: Python(流水线)、TypeScript(UI) 前置要求: 第 4 阶段(CV)、第 6 阶段(语音)、第 7 阶段(transformer)、第 11 阶段(LLM 工程)、第 12 阶段(多模态)、第 17 阶段(基础设施) 涉及阶段: P4 · P6 · P7 · P11 · P12 · P17 预计时间: 30 小时
问题背景
长视频问答是 2026 年规模下最吃带宽的多模态问题。Gemini 2.5 Pro 能原生读一个 2 小时的视频,但把 100 小时视频摄入成一份可查询的语料,仍然需要一个场景级索引。生产形态把场景切分(TransNetV2 或 PySceneDetect)、用 VLM 做逐场景 captioning(Gemini 2.5、Qwen3-VL-Max 或 Molmo 2)、转写对齐(带词级时间戳的 Whisper-v3-turbo),以及一个把 caption、帧 embedding、转写并排存的多向量索引结合起来。查询流水线用 (start, end) 时间戳加帧预览作答。
基准是公开的(ActivityNet-QA、NeXT-GQA)加上你自己的 100 问自定义集。计数和动作类问题上的幻觉是出了名难的失败类别;这个顶点项目明确地衡量它。
核心概念
摄入时三条流水线并行跑。场景切分把视频切成场景。VLM captioning 为每个场景生成一个 caption,并从一个关键帧生成一个帧 embedding。ASR 对齐产出词级时间戳。这三条流按 (scene_id, 时间范围) 连起来。每个场景在一个多向量索引(Qdrant)里拿到三种向量类型:caption embedding、关键帧 embedding、转写 embedding。
查询时,自然语言问题对全部三种向量发起检索;结果用 RRF 合并;一个时间定位适配器(TimeLens 风格)在最佳场景内细化 (start, end) 窗口。VLM 合成器(Gemini 2.5 Pro 或 Qwen3-VL-Max)接收 查询 + 最佳场景 + 裁剪过的帧,用带引用的时间戳和一个帧预览作答。
幻觉的衡量很重要。计数(“有多少人进了房间?”)和动作类(“厨师是先倒再搅吗?”)问题是出了名地不可靠。把这类的准确率跟描述性问题分开报告。
架构
video file / URL
|
v
PySceneDetect / TransNetV2 (scene segmentation)
|
+--- per-scene keyframe --- VLM caption + frame embedding
| (Gemini 2.5 Pro / Qwen3-VL-Max / Molmo 2)
|
+--- audio channel --- Whisper-v3-turbo ASR + word timestamps
|
v
multi-vector Qdrant: {caption_emb, keyframe_emb, transcript_emb}
|
query:
dense queries against all three -> RRF merge -> top-k scenes
|
v
TimeLens / VideoITG temporal grounding (refine start/end within scene)
|
v
VLM synth: query + top scenes + frame previews
|
v
answer + (start, end) timestamps + frame thumbs + citations技术栈
- 场景切分:TransNetV2(2024-26 SOTA)或 PySceneDetect
- ASR:通过 faster-whisper 的 Whisper-v3-turbo,带词级时间戳
- VLM captioner + 作答器:Gemini 2.5 Pro 或 Qwen3-VL-Max 或 Molmo 2
- 时间定位:TimeLens-100K 训练的适配器或 VideoITG
- 索引:带多向量支持的 Qdrant(caption / 帧 / 转写)
- UI:Next.js 15,配 HTML5 视频播放器和场景缩略图
- 评测:ActivityNet-QA、NeXT-GQA、自定义 100 问手工标注集
- 幻觉基准:带手工标签的计数和动作类子集
cf-scene-index动手构建
摄入遍历器。 接收 YouTube URL 或本地 MP4。必要时降采样到 720p。持久化
\{video_id, file_path\}。场景切分。 跑 TransNetV2 或 PySceneDetect,产出
[\{scene_id, start_ms, end_ms, keyframe_path\}]。目标 100 小时:约 6k-8k 个场景。ASR 遍历。 在音频上跑 Whisper-v3-turbo;导出词级时间戳;切成逐场景的转写切片。
VLM captioning。 每个场景,用关键帧和一个简短的 caption 模板调 Gemini 2.5 Pro(或 Qwen3-VL-Max)。产出 caption + 帧 embedding。
多向量索引。 带三个命名向量的 Qdrant collection。payload:
\{video_id, scene_id, start_ms, end_ms, keyframe_url\}。查询。 自然语言问题发起三个 dense 查询;用倒数排名融合合并;top-k=5 个场景。
时间定位。 在最佳场景上跑 TimeLens 风格适配器,细化场景内的 (start, end) 窗口。
VLM 合成。 用 查询 + top-3 场景片段(作为图像或短片段)+ 转写 调 Gemini 2.5 Pro。要求
(video_id, start_ms, end_ms)引用。评测。 跑 ActivityNet-QA 和 NeXT-GQA。建一个 100 问自定义集。报告整体准确率 + 逐类别拆分(计数、动作、描述)。
实际使用
$ video-qa ask --url=https://youtube.com/watch?v=X "how many cars pass the intersection in the first minute?"
[scene] 23 scenes detected
[asr] transcript complete, 4m12s
[index] 69 vectors written (23 scenes x 3)
[query] top scene: scene 3 [01:32-01:54], confidence 0.84
[ground] refined window: [00:12-00:58]
[synth] gemini 2.5 pro, 1.4s
answer: 5 cars pass the intersection between 00:12 and 00:58.
citations: [scene 3: 00:12-00:58]
[frame preview at 00:14, 00:27, 00:44, 00:51, 00:57]拿去用
outputs/skill-video-qa.md 是交付物。给定一个 YouTube URL 或上传的视频,流水线给场景建索引,并用带时间戳的引用作答。
| 权重 | 标准 | 怎么衡量 |
|---|---|---|
| 25 | 时间定位 IoU | 留出定位集上的交并比 |
| 20 | 问答准确率 | NeXT-GQA 和自定义 100 问 |
| 20 | 摄入吞吐 | 每花一美元能处理多少小时视频 |
| 20 | UI 与引用体验 | 时间戳链接、缩略图条、跳转到帧 |
| 15 | 幻觉率 | 计数和动作类准确率分开算 |
| 100 |
练习
在 captioning 遍历上把 Gemini 2.5 Pro 换成 Qwen3-VL-Max。在一个 50 场景的人评样本上报告 caption 质量差值。
把逐场景帧 embedding 降成一个池化向量而不是多向量。衡量检索倒退。
做一个“计数严格”模式:合成器把每个被计数的实例连同时间戳抽出来,用户点击核实。衡量用户核实是否减少了幻觉。
给摄入成本跑基准:三种 VLM 选择下的 每美元处理视频小时数。挑那个甜点。
加说话人分离的转写:在音频上跑 pyannote 说话人分离,并对逐说话人转写做 embedding。演示“Alice 关于 X 说了什么?”这类查询。
关键术语
| 术语 | 大家嘴上怎么说 | 它实际是什么 |
|---|---|---|
| Scene segmentation(场景切分) | “镜头检测” | 在镜头边界处把视频切成场景 |
| Multi-vector index(多向量索引) | “caption + 帧 + 转写” | 每种表示一个命名向量的 Qdrant collection |
| Temporal grounding(时间定位) | “它到底什么时候发生的” | 为一个查询答案细化 (start, end) 窗口 |
| Frame embedding(帧 embedding) | “视觉表示” | 一个关键帧的向量 embedding;用于场景视觉相似度 |
| RRF fusion(RRF 融合) | “倒数排名融合” | 跨多个排序列表的合并策略;经典的混合检索技巧 |
| Counting hallucination(计数幻觉) | “数错了” | VLM 在“有多少 X”问题上的已知失败模式 |
| ActivityNet-QA | “视频问答基准” | 长视频问答准确率基准 |
延伸阅读
- AI2 Molmo 2 —— 开源 VLM checkpoint
- TimeLens (CVPR 2026) —— 规模化的时间定位
- Gemini Video long-context —— 托管参考
- VideoDB —— CRUD-for-video API 参考
- Twelve Labs Marengo + Pegasus —— 商业参考
- TransNetV2 —— 场景切分模型
- PySceneDetect —— 经典的开源替代
- ActivityNet-QA —— 参考评测基准