✏️ 编者按:
对于短视频产品而言,提升视频去重性能、降低误杀率,是提升用户体验的必要环节。在此次 Milvus 社区发起的「Milvus 实战系列直播」中,我们有幸邀请到了 vivo 互联网服务器开发工程师马运杰,与大家分享开源向量数据库 Milvus 在 vivo 视频中的实践。
嘉宾简介:
马运杰,vivo 短视频后端架构师,负责 vivo 短视频服务端以及视频处理平台的系统架构设计,毕业于南京邮电大学,热衷新技术预研与难点攻坚。
业务背景
为什么要视频去重?
对于观众来说,良好的观看体验与视频内容有着很大的关系。当前,全网范围内主要精品视频主要来自于 MCN 机构,一些公司为了更快更好地去覆盖全网内容,会选择和内容代理合作,而代理手上会有很多重复的版权内容,导致重复内容出现。另外,搬运类视频也会产生重复内容。如果将重复的内容直接分发给用户,就会造成极差的用户体验,堪称「劝退」。所以,内容进行去重处理是非常有必要的。
目前,视频去重面临哪些痛点?
目前,基础样本数据已达到大几千万,在不久的将来会过亿。目前的难点是,在亿级样本数据的基础上支持百万级别的吞吐量,同时需要兼顾去重的精度以及高召回率。接下来,我将为大家介绍我们是如何应对这几个问题的。
算法流程设计
首先,进行视频特征提取,对视频进行抽帧。视频抽帧有多种策略,可以按照固定的时间间隔抽帧,或者抽取视频所有的关键帧等。我们首先对视频进行场景检测,优先抽取出场景切换中具有代表性的一些关键帧,然后利用图像算法提取关键帧的局部特征,之后再把这些局部特征去合并得到全局特征。全局特征是几千维的浮点型的向量,最后我们还会再进行一层哈希压缩,这层哈希压缩其实压缩了很多的数字量,但是也会给我们带来一些问题,后续会提到。除了视频特征之外,我们还会提取视频的音频指纹,作为比对的重要依据。
特征提取后,我们进行特征匹配。将历史提取的视频特征放在向量数据库 Milvus 中,经过 Milvus 数据库召回 topK 的向量,然后通过一定的策略进行过滤合并,得到相似的视频的候选集,经过细致的音频指纹的比对,基本可以得到相似视频的集合。最后,根据业务上的其他特征,如时长、标题等等特征的完整比对,最终形成相似视频集合。
识别效果需要同时兼顾召回和精度这两个方面。在视频召回的时候,我们会适当放宽整个限制,尽可能多地召回相似视频;而在音频比对当中,我们会更严格地进行筛选。这种策略有一定缺陷,比如短视频常用的“拍同款”功能中,拍出来的音频十分相似,比对结果可能不是很好。整体来看的话,这样的策略还是能达到 90% 以上的精度和召回率目标。
去重系统设计
整体系统架构如上图,分为三个服务、四个步骤。第一个部分是特征提取,主要是负责视音频特征的提取以及特征文件的管理,其中还包括了视频的镜头检测以及抽帧。第二个部分是去重策略,主要包括了业务上的逻辑以及去重的策略控制。第三个部分是特征召回部分,主要是作为 Milvus 数据库的客户端代理工作,工作内容主要是负责创建集合以及索引。第四个部分则是基于 Milvus 数据库搭建的检索集群,里面分为主集群和备集群。
在进行系统的详细介绍之前,我们先来看一组压测结果。从结果中可以看到,第一列向量数量、第三列向量维度和最终的 TPS 呈负线性相关。向量数量、向量维度和索引参数,是影响 TPS 的主要因素,也是我们后面去提升这个性能的主要方向。
我们所做的第一个工作是集群化部署。
从压测数据可以看出,单实例只能支持几百万的向量检索,也就是几十万的视频样本。虽然这种单机部署也会有它的一些优势,比如说部署起来非常简单,使用方便等等。但是对于全局去重的业务不合适的。我们选择使用 Mishards 插件来搭建分布式集群,通过不断地加入 Milvus 实例,来分担每个实例的查询数量,提升整个集群的吞吐量。Milvus 数据库内部处理请求的时候其实都是单线程的,如果要提升整个系统的并发能力,可以考虑右边这样多集群部署方式,提升我们整体的吞吐量。
除了集群化部署之外,创建索引也是提升性能的主要方式。上图左边表示精度,右边表示性能。可以看到,在添加索引之后会导致一些召回率上的损失,nlist 越小,损失越大,所以我们自然想把 nlist 设置得大一些。然而,Milvus 对二值型向量的支持比较弱,在构建索引的时候没有充分利用 CPU 资源,构建时间非常长。比如,nlist 等于 1024 的时候,索引构建时间已经达到一个小时左右。我们就只能妥协地降低 nlist 的大小,给我们带来了召回率上的一些损失。
此外,构建索引期间集群里面的数据无法正常写入的,只有等待整个索引构建完成之后后,才能够正常插入请求,这也是为什么我们需要 Milvus 备级群。我们把向量的读写分为三个状态:正常状态(对主集群进行读写)、索引构建时的状态(不能写入主集群,使用备集群,然后同时查询主集群及备集群)索引构建结束状态(主集群已经可以正常读写,需要把备用集群的数据迁移回主集群,迁移完成后,这个状态也就重新变成了正常的状态)。通过这样主备切换,我们解决了索引构建期间无法正常写数据的问题。
整个集群的样本数据量越来越大,集群的吞吐量会随着时间的迁移而变小。为了控制整个集群的吞吐量,我们选择通过业务上的一些规则进行了分支。比如,我们发现两个相同或者相似的视频,我们会是根据视频的发布时间以周为单位去进行分区。在召回的时候,选择该视频所在分区相近的几个分区进行查询。通过这样一种方式,我们对整个比对的数量进行了严格控制,从而保证了检索效率。以上就是我们基于 Milvus 数据库所做的系统设计和性能优化。
期待与总结
在识别效果方面,通过视音频特征的结合,采用宽视频阈值、严音频阈值的方式,目前我们去重识别的精度与召回都达到了 90% 以上;在系统性能方面,Milvus 集群的吞吐量和每台机器检索的数据量强相关,我们通过集群化部署、数据分区的方式,限制每台机器检索的向量数量,以此达到我们系统吞吐量 100 W/天的目标;在索引构建方面,我们遇到了比较多的问题,我们暂时以主备集群的方式满足系统可用性的条件,接下来我们会和社区持续沟通,解决二值索引的相关问题。
在未来,我们期待 Milvus 数据库对以下方向进行优化:
匹配分级:对匹配结果进行分级,对于低于阈值之下的视频通过视频处理、采集更细致的视频特征,进行二次匹配;
索引构建效率提升:与社区合作,针对二值索引的构建性能进行优化;
集群自动扩缩容:通过 Milvus 服务的自动注册与自动方向,解决集群静态扩缩容的问题;
系统高可用:通过多集群部署等方式,解决 Mishards 以及 Milvus 数据库写节点单点问题。
Zilliz 以重新定义数据科学为愿景,致力于打造一家全球领先的开源技术创新公司,并通过开源和云原生解决方案为企业解锁非结构化数据的隐藏价值。
Zilliz 构建了 Milvus 向量数据库,以加快下一代数据平台的发展。Milvus 数据库是 LF AI & Data 基金会的毕业项目,能够管理大量非结构化数据集,在新药发现、推荐系统、聊天机器人等方面具有广泛的应用。