数据存下来了,然后呢?

企业里的数据正在变样。过去我们处理的主要是结构化的表格,如今图片、视频、文本、向量越来越多地进入数据平台。以智能驾驶为例,每辆测试车每天都在持续产生路面视频、传感器数据和运行记录,算法团队又在这些原始数据之上不断生成标签、特征和评测结果。

数据存下来只是第一步,真正的问题随之而来:业务人员和算法工程师怎样才能方便地找到需要的内容,并继续做分析?

这个问题之所以难,在于系统和业务看待数据的方式完全不同。

一段视频刚上传时,系统只知道它是一个文件——有路径、有大小、有上传时间。但业务真正关心的是里面发生了什么:有没有行人?是不是在下雨?有没有值得关注的异常场景?文件元数据回答不了这些问题。

用一个更具体的场景来说。

假设在一次道路测试中,团队发现某个模型版本在雨夜遇到车辆加塞时表现不够理想。

接下来要弄清楚的是:这个问题发生在什么条件下?已有的历史数据里有没有类似的片段?这些片段能不能支持分析和改进?回答这些问题,意味着要从海量的视频资产里,精准地找出"雨夜、加塞"相关的片段,并且把它们和车型、模型版本、评测记录关联起来。

这正是多模态数据湖检索要解决的问题。

本文将介绍 StarRocks 和 Paimon 在这个技术点上的整体思路、技术配合,以及在阿里集团和阿里云上的落地实践,最后回到雨夜加塞这个场景,完整走一遍从发现问题到验证改进的闭环。

整体思路:从原始对象到分析的完整链路

面对"存下来之后怎么找、怎么用"这个问题,我们的思路是:把原始对象的处理、数据存储,以及后续的检索和分析,连接成一条完整的链路。

从文件到可查询的数据

链路的第一步,是让文件里的内容变成可以查询的数据。

视频、图片这类原始对象进入平台后,系统首先要对它们进行处理:解析内容、生成场景描述和标签、提取向量特征。处理完成后,原始视频继续保留在对象存储里,而这些处理结果——文本、标签、向量——与原始对象建立关联。

MIP 从文件到可查询的数据流程示意图

这样一来,数据就有了两个层面:底层是不可变、大体量的原始对象,上层是可查询、可检索的处理结果。业务人员面对的不再是"一个不知道里面有什么的文件",而是一组可以被条件过滤、被关键词命中、被语义匹配的结构化信息。

按访问需求选择存储方式

处理结果产生之后,并不意味着所有数据都要放在同一个地方,需要根据访问需求选择存储方式。

访问频繁、延迟要求高的数据,可以放到 StarRocks 内表里,支撑低延迟的检索和分析。长期积累的大规模数据资产,则通过 Paimon 来管理,利用湖表的机制组织数据的快照和持续变化。如果企业已有 Lance 格式的数据,也可以考虑通过 StarRocks 去接入,直接做检索和分析,不必先搬迁数据。

检索不是终点

找到内容之后,业务往往还需要进一步的分析和计算。比如:这一类场景到底有多少?集中在哪些车型?和哪个模型版本相关?

这意味着检索结果一般都需要和业务数据进行混合分析,而不是查出几十条结果就结束。所以在设计这条链路时,检索和后续分析是被放在同一个查询过程里考虑的——这也是后面会反复出现的一个主题。

两个核心设计思想:尽早过滤,按需读取

StarRocks 全模态检索架构图

上面 StarRocks 多模态检索的架构图里,上方是统一的查询入口,下方是不同的数据存储,中间由 StarRocks 组织查询的执行。这个架构要运转得好,靠的是两个贯穿始终的设计思想。

尽早过滤:能排除的,尽早排除

用户提出的一个检索需求,里面可能同时包含多种条件:时间、车型这样的结构化条件;也包含关键词和向量相似度。系统需要判断:哪些条件可以先执行?从哪里找候选集?什么时候读取完整的数据?

举一个例子:要找某个车型最近一个月的雨夜行驶片段。"某个车型、最近一个月"这样的条件,如果能排除绝大多数无效数据,就应该尽早利用它,把后续检索的实际工作量降下来。反过来,如果一上来就对全量数据做向量计算或读取完整内容,绝大部分工作都会浪费在最终根本用不到的数据上。

按需读取:先拿标识和分数,后读大字段

第二个思路是按需读取。检索过程中,系统先传递候选数据的标识和相关性分数,等候选范围缩小以后,再读取需要展示和分析的业务字段,以及原始对象的引用。

图片和视频越大,这个思路的价值就越明显。这些大字段的读取成本远高于条件和相关性分数的计算,只有候选集足够小的时候读它们才划算。

这两个思想放在一起,要表达的核心理念是:让不同的检索方式进入统一的查询执行过程,同时考虑后面的关联和分析,减少各个系统之间反复搬运数据的工作量。

一条 SQL 背后的完整视角

用一条 SQL 加深上面的思路理解。这条 SQL 表达的核心需求是:在指定业务范围内,找到与"雨夜加塞"相关的驾驶片段,返回最相关的一批结果。

sql
SELECT
  clip_id, oss_uri, model_version
FROM paimon.driving_clips
WHERE tenant_id = 1001
  AND scene_text MATCH '雨夜 加塞'
ORDER BY hybrid_score(
  embedding, :query_vector)
LIMIT 20;

执行时,系统先确定查询的数据范围和快照,结构化条件与全文向量检索做混合分析,形成候选结果,然后再读取其他需要的业务字段。

这里有一个非常重要的点:系统能够看到完整的查询需求,因此可以在每个环节做全局的取舍。如果业务范围很小,就可以先利用过滤条件尽早收敛;如果候选结果还需要进一步排序,就要为排序保留合适的候选规模,不能砍得太狠;如果最后只返回少量结果,也可以推迟读取较大字段。

而且找到视频以后,查询并没有结束——还可以继续关联模型版本、评测指标和业务记录。这样一来,一个原本需要在多个系统之间来回操作的需求,就有机会通过一条相对完整的查询链路来处理,工程师也可以把更多的时间花在理解业务结果上。

湖上的数据怎么管,怎么查?

有了整体的架构后,接下来的问题是:Paimon 如何管理湖上的多模态数据,StarRocks 又如何查询这些数据?

湖上查询的老诉求

对于使用者来说,一个最直接的诉求是:数据放在湖上以后,能不能继续用熟悉的方式进行查询?比如按时间过滤,关联一张模型信息表,再统计不同版本的表现——我们的回答是,这些需求依然可以用 where、join 和聚合来表达。

在这套方案里,分工是这样的:通过 Paimon 的 Global Index 管理湖表的数据、快照以及持续变化的内容,通过 StarRocks 负责查询和分析。一张湖表里可以关联稳定的业务字段,也可以容纳模型生成的动态属性、文本和向量,以及图片视频的对象引用。业务人员拿到这一组有关联的数据之后,看到一个检索结果,就可以进一步知道它来自哪里、经过什么处理、对应哪个业务对象。

底层访问湖表的路径会有一些差异,但我们希望这些复杂性尽量由 StarRocks 系统层来处理,而不是暴露给使用者。

查书先看目录:Global Index 的工作方式

Paimon Global Index 的思路,可以用一个简单的类比来理解。

我们要查一本很厚的书,通常会先看目录或索引,找到相关的页,然后再去读正文,没有人会从头翻到尾。Global Index 也是这样:

  • 如果查询某个样本 ID,就通过索引直接定位相关数据——相当于按页码翻书;
  • 如果搜索一段文字,或者寻找语义相近的内容,就先得到一批候选数据的标识和相关性分数——相当于先圈出可能相关的页;
  • 接下来系统把候选结果做合并,再读取需要的业务列——相当于只读圈出来的那几页。

对于海量数据,这个过程的价值非常可观:用户最终可能只需要几十条结果,就应该尽量把读取范围缩小到相关数据。图里的 Row ID、Index、Split 是 Paimon 工程实现上的概念,不需要过度关注,核心思路只有一句话:先定位候选集,再按需读取。

一个样本的多个侧面,组合查询更自然

从业务的角度看,同一个样本通常有非常多的侧面。比如一段驾驶视频,会有采集时间、车型这些固定的字段,有模型生成的场景描述,也可能有不断增加的新标签和向量特征。

这些信息关联起来以后,我们就可以根据问题选择检索方式:

  • 知道准确编号时,直接点查;
  • 知道具体关键词时,做全文检索;
  • 只有一段自然语言描述,或者一个参考样本时,通过向量语义寻找相近的内容。

实际业务里,这些方式经常需要组合使用,比如先限定车型和时间,再找符合场景描述的视频。把它们放在同一套数据关系里,能够让这种组合查询更加自然——不需要在多个系统之间来回导出导入。

Tips:选型 Paimon 还是 Lance?

落到具体的实践上,首要会想到一个问题: StarRocks 跟 Paimon 结合得比较好,那在多模态数据这个领域,到底应该选择 Paimon,还是选择在海外比较火热的 Lance 数据格式?

我的建议是,先看自己已有的数据链路,以及最主要的访问方式。

如果已经有 Flink + Paimon 的湖仓体系,数据持续更新,同时还要做业务分析,建议优先选择 Paimon。链路和工具都是现成的,加入多模态检索是对现有体系的增强,而不是另起炉灶。

如果需要围绕 Python、Arrow 或者训练样本展开工作,特别是数据链路里已经有 Lance 相关的训练数据集,并且关注按行的读取以及特征加工,可以考虑对 Lance 做一个评估。这类工作流与 Lance 的设计取向更贴近。

最终选型时,还是要结合实际的读写方式、连接器的支持和运维成本来综合判断,没有脱离场景的标准答案。

还有一点值得一提:如果通过 StarRocks 去做一个整体的检索平台,内部的业务也可以根据不同的业务形态选择不同的湖格式——查询入口统一,底下的存储选型可以是多样的。

落地实践:从集团内部到云上行业

前面讲了整体架构和与 Paimon 的配合细节,这一部分看落地。这套多模态检索架构在阿里集团内部和阿里云上都已经有了实际应用。

阿里集团 A Lake:训练前的数据检索与样本准备

第一个场景是阿里集团内部的 A Lake 平台,StarRocks 在其中扮演的角色主要是训练前的数据检索和样本准备。

训练数据集合里可能同时有文本、图片、音频和视频,还会持续生成新的标签和特征。需要把这些内容围绕样本组织起来,才能进一步筛选。A Lake 的做法是:使用 Paimon 宽表关联多模态样本与特征,再通过 StarRocks 提供混合检索和数据筛选。

举个例子,要准备某个专项训练集,可以先限定数据来源、质量和场景,再通过关键词或者语义检索找到候选集合。找到候选集合以后,工作还没完——还需要检查相关性和覆盖度:有些样本很相似,但重复太多;有些样本数量少,却恰好覆盖了模型的薄弱场景。所以检索并不是简单地"找出来",而是参与了训练数据的选择过程,帮助算法工程师更快地找到值得进一步评估和使用的数据。

AI Data 平台:两类不同的检索需求

第二个案例是阿里集团 AI Data 平台,它提出了两类很不一样的需求。

第一类是大规模候选召回。这个场景涉及百亿级的向量和 TOP 500 万的召回需求,主要用于人群圈选。这和日常搜索只返回十几条结果很不一样:候选数量非常大,而且召回之后通常还要继续过滤、关联和分析,对整个查询执行的链路提出了非常高的要求。

第二类是 agent 可观测。排查一次 agent 调用时,可以先用 request id 或 trace id 定位,再结合时间、工具和状态缩小范围,接着通过错误文本或语义相似度,查找类似的问题。

这两类场景说明了同一个关键点:现在的检索,向量、全文、标量组合在一起的混合检索会更常见,单一检索方式很难独立覆盖真实需求。

云上行业:数据不同,问题相同

除了集团内部,阿里云上也有大量行业有类似需求:汽车行业围绕座舱多模态数据做点查和筛选,智能硬件围绕原始对象组织训练数据,文娱行业则把分镜解析、特征生成和素材的召回连接起来。

这些行业的数据各不相同,但共同面临的相同挑战:把原始内容、模型生成的信息和业务记录关联起来。这正是我们方案的价值所在。

接下来,展开讲智驾业务场景,把前面提到的所有内容完整串起来。

深入一个场景:智驾数据的完整闭环

之所以选智驾,是因为这是最适合说明多模态数据价值的场景:车辆会持续产生视频、传感器数据和运行记录,算法团队也在持续生成标签、特征和评测结果。随着数据越来越多,工程师面临的实际问题是:当模型出现某一类问题时,怎样从已有数据里找到真正相关的样本?

从 Bad case 定位到样本补充、训练评测的完整数据闭环

具体来说,回到开头那个问题:在一次道路测试中,团队发现某个模型版本在雨夜遇到车辆加塞时,表现不够理想。接下来要弄清楚的是两件事——这个问题发生在什么条件下?已有的数据能不能支持分析和改进?为了回答这两个问题,整个流程通常会分为下面几步。

第一步:定位和分析 Bad case

所谓 Bad case,就是表现不符合预期的样本。工程师可能先从一次接管事件,或者一条评测失败记录进入,找到对应的视频片段,再关联当时使用的模型版本和处理记录。

看完之后往往会发现,"雨夜加塞"这个描述其实比较宽泛,真正需要关注的是更具体的条件:雨比较大,路面反光明显,旁边一辆车以较短的距离切入本车道,而且当时还有一定遮挡。只有把这些条件逐步明确,后续找数据才更有针对性。

这一步里,结构化分析和视频内容需要配合起来:既需要看到发生了什么,也需要知道它发生在什么时间、什么车型以及什么模型版本上。还可以进一步统计:类似的问题是集中在某个版本上,还是在多个版本里都存在?这样团队对问题的范围会更有判断。

第二步:寻找相似的历史样本

找到 Bad case 之后,下一步是寻找相似的历史样本。这时候单纯依赖人工标签会遇到困难:同样的情况,有人标成"加塞",有人标成"车辆切入";有些数据采集得比较早,还没有细致的场景标签。只用一个关键词去搜索,可能会漏掉非常有价值的数据。

因此可以把几种检索方式结合起来:先用车型、采集时间等条件做范围限定,再利用已有的场景描述和标签做全文检索,最后通过向量寻找内容上相似的片段。工程师可以输入"雨夜近距离车辆切入"这样的描述,也可以拿已经发现的问题片段作为参考,继续寻找相似场景。具体采用什么方式,要结合使用的模型和数据处理链路来设计。

返回结果以后,还要继续看它们的分布:是不是大部分都来自同一条路线?是不是集中在少数几辆车?有没有不同雨量、不同光照条件下的样本?这一步会用到关联和聚合——我们希望找到的训练候选集能够覆盖需要关注的场景,而不是收集很多内容几乎一样的视频。

第三步:复用,还是定向补采

拿到场景化的视频片段之后,流程一般分为两种情况。

如果已有数据里有合适的样本,就进入人工修复阶段,补充标注和质量检查。有些原始片段其实早就存下来了,只是当时没有围绕这个问题来组织,现在通过新的标签、描述和特征,可以把它们重新找出来,用于新的专项任务。这意味着同一份原始数据,可以随着模型能力和业务需求的变化,持续产生新的用途。

如果现有数据没有覆盖我们需要的条件,或者数量明显不足,就把缺失条件整理成更明确的定向采集需求——比如需要补充哪些天气和光照条件、哪些道路环境下的样本,并按规范组织采集和后续的质检。

这里有一个需要注意的点:检索没有命中,也可能和标签、特征、检索条件有关,因此团队要先检查检索范围和数据处理的情况,再判断数据是不是真的缺了。这个判断做扎实之后,采集才更有针对性,也能减少重复收集已经足够丰富的场景。

第四步:训练、评测与版本管理

样本补齐之后,进入训练和评测。这个阶段,团队需要准确知道:这次训练到底用了哪些数据?标签是哪一版?哪些样本是这次新加入的?

因此需要围绕业务上的 data id,把原始片段、处理记录和标注结果关联起来,同时保存数据集的版本。这里要区分两个层次:Paimon 的快照帮助我们管理底层数据状态,业务上仍然需要明确记录训练集的组成,以及它和模型版本的对应关系。这样当新模型的表现发生变化时,工程师才有依据去分析:是数据变化带来的,还是训练配置或者其他因素带来的。

评测时除了看整体指标,还要回到这次关注的专项场景:新模型对雨夜加塞的表现有没有改善?在其他已有场景里有没有出现退化?场景库和 Bad case 库的价值就在于这里——每解决一类问题,都把相关样本和评测条件沉淀下来,为后续版本提供持续的回归检查。

闭环之后:数据越用越厚

模型完成评测、满足部署要求之后,进入灰度发布和回传流程。后续仍然可能出现新的问题片段,这些数据又会进入下一轮分析。

随着这个过程持续运行,平台里积累的内容会越来越丰富:既有原始样本,也有场景描述、不同版本的训练集和评测结果。把这些资产关联起来以后,团队还可以分析整个过程的效率:从发现问题到形成可复用的训练数据集需要多长时间?时间主要花在找数据、标注还是质检上?已有数据的复用比例怎么样?哪些场景总是需要补采?这些问题都可以通过数据进一步分析,帮助团队改进研发效率。

总结:让数据回答四个问题

多模态数据进入企业之后,需要一条完整的数据使用链路:从原始对象里提取信息,把样本和业务记录组织起来,再通过检索找到相关内容,并继续展开分析。StarRocks 和 Paimon 的配合,就是围绕这条链路展开的。

在智驾这样的场景里,这套配合的分工很清晰:Paimon 承担数据资产和快照的管理,StarRocks 帮助工程师跨模态检索样本,并关联模型、评测和流程记录,开展分析。与采集、标注、训练和部署平台共同完成整个闭环。数据的价值,体现在每一次的问题定位、样本补充和模型评测当中。

最终,我们希望通过这套数据架构,帮助工程师更快地回答四个具体问题:

问题发生在哪里?相关的数据在哪里?数据是否足够?以及,改进以后有没有得到验证?

这也是多模态检索在智驾场景里最直接的价值——帮助团队更方便地使用已有的数据资产,让模型迭代有更充分的数据依据。

以上就是本次分享的全部内容,演讲文字版到此为止,现场的问答环节未能一一收录。如果你想对照着本文回看完整内容,欢迎浏览 “mirrorship.ai” 获取演讲 PPT和回放地址,里面有文中提到的架构图、SQL 示例和场景流程图。