为什么我们需要一个多模态原生引擎
从 PDF、图片到音视频,多模态数据的价值释放,往往需要经过解析、转换、模型计算和结果关联等多个环节。本文将介绍为什么这些处理流程需要一个多模态原生引擎,以及 Vane Data 如何将 SQL、Python 函数与 AI 能力组织成统一的数据流,让多模态数据处理像数仓 ETL 一样简单。从一行 import vane 开始,复用你熟悉的 Python 和 SQL,构建第一条多模态处理流程。
1. 数据库都在支持多模态,为什么还需要一个新引擎?
1.1 多模态搜索之外,还有多模态计算
一份 PDF 能够被语义检索,通常已经经过文本提取、段落切分和向量化;一张商品图片能按属性筛选,往往已经调用模型识别过内容,并将结果与商品记录关联起来。存储和检索承接了这些处理的结果。
因此,讨论“支持多模态”,还需要追问支持到了哪一步:文件保存在哪里,怎样检索,以及原始内容怎样变成可用数据?这些能力可以存在于同一系统中,但它们解决的问题不同。本文关注的是其中的计算过程。
1.2 从 PDF 到音视频,都需要数据处理流程
不同的数据形态,共享相似的处理结构:读取原始内容,解析或拆分,执行转换与模型计算,整理并关联结果,最后保存和使用。
| 任务 | 典型处理流程 |
|---|---|
| PDF 知识库 | 解析文档 → 切分段落 → 向量化 → 写入索引 |
| 商品图片处理 | 读取图片 → 调整尺寸 → 提取属性 → 关联商品信息 |
| 录音分析 | 解码音频 → 转写 → 提取要点 → 保存结构化结果 |
| 视频处理 | 提取画面与音轨 → 分别理解 → 时间对齐 → 汇总结果 |
具体步骤会变化,但都需要把多个操作组织成数据流。某个模型能够理解内容,只解决了其中一个环节。
1.3 数据特点与异构资源,带来不同的优化目标
文件进入计算流程后,工作量、数据数量和资源需求都可能发生显著变化。
- **单条数据的计算成本不均。**两页文本与几百页扫描件,在文件清单里都只占一行,但读取、解析和理解的成本可能相差很大。如果按文件数平均分配任务,有的工作进程很快空闲,有的却仍在处理长文档。批次包含多少行,也不足以说明它会占用多少内存、消耗多少模型计算。
- **数据会在处理中展开。**一个 PDF 变成页面,页面变成段落,每个段落又可能产生结构化字段和向量。这种一个输入生成多个输出的情况,称为 Fanout。系统需要控制的,既有原始文件,也有过程中不断产生的数据;限制入口文件数,并不等于限制住了中间结果。
- **不同阶段需要不同资源。**读取文件依赖 I/O,解析与解码消耗 CPU,本地模型可能需要 GPU,远程接口受到并发和限流约束。让所有阶段共用一种并发策略,很难同时照顾这些差异。某个阶段更快,还可能让下一个阶段积压得更严重。
针对这类任务设计引擎,需要把成本不均、数据展开和异构资源协调纳入执行控制。传统的数据库内核往往不是为这类负载而设计。
2. 自己用 Python 处理多模态数据,有什么问题?
2.1 开发者需要自己处理基础设施问题
用 Python 读取文件、调用模型、写出结果,很快就能完成第一版。为了持续运行,开发者还需要承担三类工作:
- **数据组织与流量控制。**文件怎样分批,同时处理多少个,阶段结果怎样传递?下游模型变慢时,上游是否需要暂停,以免中间结果持续积压?
- **资源调度与模型生命周期。**CPU 解析、GPU 推理与远程调用怎样衔接?昂贵的模型怎样加载一次、反复使用,连接怎样复用,并发与限流又怎样管理?
- **异常处理与运行保障。**某条数据失败后,哪些步骤可以重试,哪些结果应该保留,如何避免重复产生外部操作?这些都需要明确规则。
业务目标没有改变,脚本却逐渐承担了流量控制、资源调度、实例生命周期和故障恢复。**你正在为这条处理流程,补齐一套执行系统。**这些工作会不断影响新功能的开发,也会成为长期维护的负担。
2.2 脚本成本随流程复制和业务变化持续累积
处理少量文件时,脚本很容易跑通,但数据组织、步骤衔接和结果处理仍需要开发者安排。随着流程复制和业务变化,这些成本会进一步放大:
- **新流程重复建设。**第二条、第三条流程,往往又需要相似的批次、队列和重试逻辑。
- **局部变化牵动执行控制。**更换模型或调整处理步骤,可能需要重新配置批次、并发和资源。
- **调试和调优缺少统一边界。**各条脚本分别管理执行过程,定位积压、资源等待或失败原因时,需要逐一梳理。
3. 让多模态数据处理跟数仓 ETL 一样简单
Vane Data 是一个多模态原生数据引擎,它通过以下机制让多模态数据处理跟数仓 ETL 一样简单。
3.1 Relation:贯穿输入、中间结果和最终产物
Vane Data 通过 Relation,也就是带有字段和类型的数据集,组织业务 ID、文件引用、解析文本、结构化结果和向量。输入、中间结果和最终输出,都可以沿用这套表达。
处理 PDF 时,可以在展开段落的同时保留文档 ID 与页码;图片提取属性后,可以通过商品 ID 与业务表关联。模型结果因此能够继续参与筛选、关联和聚合。开发者需要在转换中明确保留哪些关联字段,而引擎提供统一处理它们的方式。文件经过多次计算,仍然属于同一条业务数据流。
3.2 原生多模态类型:统一接入文件、图片和音视频
Vane Data 的这些数据类型:File、ImageFile、AudioFile 和 VideoFile 让文件引用拥有明确类型,参与筛选与转换。构造引用本身不要求读取完整内容。文件可以保留在原有存储中,通过相应连接和凭据访问,按处理需要读取。
3.3 SQL + UDF + AI Function:统一表达计算流程
一个引擎能否融入现有开发方式,取决于业务代码能否继续使用。Vane Data 提供三种可以组合的计算表达:
- **SQL:组织数据。**表达筛选、展开、关联与聚合,让文件、业务字段和处理结果共同参与查询。
- **Python UDF:复用已有代码。**接入解析库和业务规则,把已有 Python 函数放入数据处理流程。
- **AI Function:接入模型计算。**将内容理解、生成和向量化纳入同一数据流,使模型输出可以继续参与后续处理。
SQL、Python UDF 与 AI Function 可以组成同一张执行图:上一步的输出直接进入下一步,来源与业务字段随数据保留。开发者定义解析、模型调用和结果处理逻辑,引擎统一安排执行与数据传递,减少各步骤之间的衔接代码。
3.4 对接现有数据系统
通过 DataSink 写入 Doris、Milvus 和 Qdrant;Lance、Iceberg、Paimon 等湖仓格式通过 provider 扩展接入,计算流程与存储选择保持开放,便于复用已有数据和下游应用。
4. 多模态引擎需要哪些执行机制?
4.1 批次控制与反压:适应数据大小和处理速度
当 PDF 解析快于向量服务的消费速度,增加解析并发只会加重积压。引擎需要同时控制批次大小与数据流动:
- **批次控制:每次交付多少工作。**根据内容大小与模型限制组织批次。
- **反压:什么时候继续交付工作。**将下游压力向上传递,暂缓上游生产,限制在途数据与中间结果。
两者配合,让各阶段持续衔接,并将积压控制在容量范围内。
4.2 异构资源并行:协调 I/O、CPU、GPU 与模型服务
I/O、CPU、GPU 和远程调用可以按阶段形成流水线:GPU 推理上一批数据,CPU 准备当前批次,I/O 读取下一批,减少资源等待。
Vane Data 通过执行后端和资源配置,让这些计算在条件允许时重叠运行,并配合反压协调阶段速度。资源应围绕瓶颈分配;远程接口已经限流时,增加 CPU 无法提高其吞吐。
4.3 模型生命周期:复用模型实例与连接
Vane Data 用 @vane.func 定义函数,用 @vane.cls 表达需要复用实例的计算,让模型与连接初始化后服务于多批数据,减少重复开销。
Ray 的 Task 与 Actor 分别支持任务计算和实例复用;实例数量需结合模型大小、设备容量与并发目标配置。
4.4 异常处理与容错:管理重试与恢复
短暂的服务故障,可以根据错误类型和重试策略,等待后再次尝试;损坏或无法处理的文件,需要明确停止还是隔离,避免无效重试或坏数据继续向下游传播。
Vane Data 提供任务重试、执行诊断和 AI Function 错误处理选项。恢复范围取决于执行路径与配置,安全重放条件仍需业务明确。
5. 从本地到 Ray 分布式运行
Vane Data 支持 Local Runner 和 Ray Runner,分别用于本地及进程内执行,以及基于 Ray 的分布式运行。
5.1 Ray Runner:支持大规模数据处理
Ray Runner 将处理任务分配到集群中的多个工作节点,利用多机 CPU、GPU 资源并行处理大规模数据。已有业务函数与查询逻辑可以继续复用,随着数据量增长扩展计算资源。
5.2 Local Runner:作为 Agent 内嵌的多模态分析引擎
离线生成的摘要、标签和向量,难以覆盖未来所有问题。例如,核对合同附件中的费用条件,可能仍需查看原始表格。提前提取所有潜在信息成本很高,因此 Agent 需要按当前任务选择相关文件或片段,重新解析和理解。
Local Runner 支持本地执行与进程内集成,让 Vane Data 可以作为 Python 库接入应用。Agent 能够调用封装好的流程,分析当前任务涉及的数据;本地开发也可以使用这套能力。
6. 多模态文件处理,从 import vane 开始
处理一份 PDF、一张图片或一段音频,都可以直接从 Vane Data 开始。在 Python 代码中 import vane,就能将文件读取、内容处理和模型调用组织成一条数据流,复用熟悉的 Python 函数和 SQL 语法,在本地运行。参考快速入门,跑通你的第一条流程。