Netflix 视频搜索背后最难的不是 AI,而是把时间线对齐

今天读了 ByteByteGo 讲 Netflix 多模态视频搜索的文章。看完之后,我最大的感受不是”AI 真厉害”,而是:真正难的从来不是模型,而是管道。
2.16 亿帧素材摆在面前,一个剪辑师要找”Joey 在厨房”的瞬间。规模是第一道坎,多模态是第二道。但真正麻烦的那个跟 AI 没什么关系——它是怎么让一堆各干各的模型,在同一秒钟上说话。
多模型的格式鸿沟
Section titled “多模型的格式鸿沟”Netflix 没用一个大模型包揽所有任务。人脸识别、场景分类、对话转录、物体检测,全是独立的专用模型。原因很简单:专用模型在自己那件事上就是比通用模型准。
但这也带来一个很多人没想过的问题——
这些模型的输出,完全不是一个世界的东西。
人脸模型吐出来一个文本标签:“Joey”。场景模型吐出来一个 512 维向量。对话模型吐出来一串带时间戳的字幕。物体检测又是一个东西。你要搜”Joey 在厨房”,这三个输出怎么在同一个查询里对上?

如果只有一个模型,这件事不存在。但当你有四个、六个、十个模型在同一个视频上同时跑,格式鸿沟就成了系统架构的第一驱动力。
三层流水线的真正分工
Section titled “三层流水线的真正分工”ByteByteGo 画了一个三层架构,但我想把每一层”为什么单独存在”这件事说清楚。
第一层,Cassandra 原样写入。 不管哪个模型的输出,来了就存,零变换。这层只做一件事:保证数据不丢。为什么不在这层做处理?因为计算重。如果写入时还要做融合,实时摄入就会被瓶颈卡住。Meenakshi Jindal 写原文的时候特意强调了这个解耦——2000 小时素材产生的数据量,写入层扛不住额外的计算负担。
第二层,离线数据融合。 这才是整篇文章的心脏。异步 job 从 Cassandra 拉出原始数据,做时间对齐和交叉融合。核心技术叫 temporal bucketing:把所有模型的输出都塞进 1 秒一个的桶里。
这一步解决两个问题。第一,不同模型的时间切片不同步——人脸模型说 Joey 在第 2 到第 8 秒,场景模型说厨房在第 4 到第 9 秒,没有共享时间线。1 秒桶强制对齐。第二,同一个桶里多个模型的标注要合并——Joey 和厨房出现在同一个 1 秒桶里,融合成一条”Joey 在厨房”的记录。
720 万个桶,每个桶可能承载多个模型的标注。1 秒这个粒度不是拍脑袋定的——更细的话记录数爆炸,更粗的话丢失精度。
这个设计有一个很工程化的味道:它不追求”最优”,而是追求”能工作”。学术论文里你很少看到讨论 1 秒还是 0.5 秒这种”脏”决策,但生产系统就是由这种决策堆出来的。你选了一个能工作的粒度,然后围绕它构建一切,而不是追求一个理论上更漂亮的方案然后发现它跑不起来。

第三层,Elasticsearch 搜索。 融合好的桶写进 ES,嵌套文档结构支持跨标注查询。搜”Joey in the kitchen”,ES 在同一个父桶里同时匹配角色标注和场景标注,一条查询搞定。
这里有个容易被忽略的细节:upsert 操作。如果某个 1 秒桶已经存在(比如之前的模型跑过),就更新而不是插入。这保证了同一秒的单一事实来源,也让系统能随时接入新模型而不用重建整个索引。
搜索的混合引擎
Section titled “搜索的混合引擎”融合层对齐了时间线,搜索层才有东西可查。
“Joey”是专有名词,需要精确关键词匹配。“kitchen”是语义概念,需要向量相似度比较。纯关键词搜索会漏掉语义相近的场景,“餐厅”和”厨房”是近义词但关键词匹配不知道。纯向量搜索搞不定专有名词,“Joey”和”Jerry”在向量空间里可能很近,但不是同一个人。
所以需要混合搜索:关键词匹配 + 向量相似度,两条路并行跑,结果合并。

Netflix 把这个混合引擎的控制权交给了用户。exact k-NN 和 approximate NN 可以切换,距离度量可以在 cosine 和 Euclidean 之间选,置信度阈值也能调。他们没替用户做选择,把 tradeoff 摆在桌面上——精确但慢,还是快但可能漏几个,用户自己决定。
对话搜索也有意思。slop 参数控制搜索词之间可以隔多少个词仍然算匹配。人记台词经常差几个字,slop = 3 意味着关键词之间最多隔 3 个词也算命中。加上多语言 stemming 和模糊匹配容忍转录错误,这个系统对人的记忆不准这件事做了宽容。
MediaFM:另一条路
Section titled “MediaFM:另一条路”文章后半段提到了 MediaFM,Netflix 自研的三模态基础模型。这代表了另一种思路——与其用多个专用模型再费劲对齐,不如训练一个统一模型同时理解音频、视频和文本。
MediaFM 的架构:SeqCLIP 编码视频帧,wav2vec2 编码音频,text-embedding-3-large 编码字幕。三个 embedding 拼起来得到 2304 维融合向量,喂进一个类似 BERT 的 Transformer,最多处理 512 个 shot 的序列。训练用 Masked Shot Modeling,随机遮蔽 20% 的 shot,让模型预测被遮蔽的 embedding。
在广告相关性、剪辑评分、语调分类、流派分类、剪辑检索等任务上,MediaFM 全面超越基线。而且那些更需要叙事理解的任务——比如给广告推荐找最合适的广告位——提升幅度最大。这说明把上下文信息喂给模型,比单帧独立分析,确实带来了质的变化。

但 Netflix 没有停掉专用模型方案。他们同时在走两条路。这个选择本身比任何技术方案都说明问题——这个领域的答案还没定。
回到我最开始那个观点。
大多数人聊 AI 系统,焦点都在模型上。Netflix 这个案例暴露了一个不性感的现实:当多个 AI 模型对同一个实体产生不同类型的数据时,最难的不是模型本身,而是那个把它们持久化、对齐、索引到同一个查询引擎里的管道。
模型会过时。MediaFM 之后会有 MediaFM v2、v3,可能有 Qwen3-Omni 或其他开源模型可以替代某个专用组件。但那三层流水线——写入解耦、离线融合、搜索索引——这套架构模式不会因为模型换代就失效。它跟用什么模型没有关系,它解决的是”多个独立信息源如何在同一个时间坐标下对齐”这个通用问题。
我之前做项目的时候,总想着用一个最强模型搞定一切。后来发现,强模型 + 烂管道,比中等模型 + 好管道,差得不是一点半点。你花 80% 的精力把模型从 95% 提到 97%,但如果管道没对齐,那 3% 的提升在下游根本看不到——因为不同模型的数据对不上时间线,模型越准,融合结果反而越乱。
Hacker News 上有人评论说,用 Supabase + PG_Vector + Whisper 就能搭一个类似的系统。技术上确实可以。三年前需要 Netflix 级别工程团队才能做到的事,现在开源生态已经把核心积木搭好了。缺的不是模型,而是知道怎么把这些积木拼成一个能工作的系统。
如果你的团队也在用 AI 处理多模态数据,你们的数据对齐层是怎么做的?时间线问题怎么解决?欢迎聊聊。
ByteByteGo: How Netflix is Using Multimodal AI to Power Video Search https://blog.bytebytego.com/p/how-netflix-is-using-multimodal-ai
Netflix TechBlog: Synchronizing the Senses — Meenakshi Jindal & Munya Marazanye, Apr 2026 https://netflixtechblog.com/powering-multimodal-intelligence-for-video-search-3e0020cf1202
Netflix TechBlog: MediaFM — Avneesh Saluja et al., Feb 2026 https://netflixtechblog.com/mediafm-the-multimodal-ai-foundation-for-media-understanding-at-netflix-e8c28df82e2d