
当数据湖里的多模态数据“沉睡”时我们到底在焦虑什么先看一个真实场景一家做智能交通的企业数据湖里存了三年多的卡口图片、监控视频片段、雷达轨迹、事故报告文本和语音调度记录。数据量接近 PB 级存储成本每年都在涨但真正被业务用起来的数据可能不到 5%。每当算法团队想做一个“恶劣天气下的交通事件识别”模型光是把数据找齐、清洗、标注就要耗费两三个月。更麻烦的是图片里的天气信息、视频里的车辆行为、文本里的事故描述彼此之间没有任何关联。它们静静躺在对象存储或 HDFS 上像一座只进不出的数据“冷库”。这不是个例。过去十年数据湖解决了“什么都能存”的问题却没有解决“存了怎么用”的问题。传统数据湖擅长存储和批量计算可以用 SQL 做结构化查询但对图片、视频、语音这类非结构化数据的理解能力几乎为零。它的索引、分区、元数据管理都是为二维表结构设计的。深度神经网络需要的是一种能把任意形态的数据压缩成机器可理解向量的表示方式。于是向量化进入数据湖的视野。核心思路并不复杂把图片、文本、音视频片段、甚至结构化记录通过嵌入模型映射成高维向量再对这些向量做索引、检索和相似度计算。这相当于给数据湖装上了一层“语义理解层”。AI 不再需要逐字节解析原始文件而是先在向量空间里快速锁定“语义相近”的数据再决定要不要读取原始数据。这篇文章不是泛泛聊概念而是从架构、工具、代码到落地路径拆清楚几个问题为什么传统数据湖“读不懂”多模态数据向量化究竟改变了哪些环节真实项目里应该在哪个层面做改造数据湖和向量数据库到底是替代关系还是协同关系以及如果想在自己的数据湖上试水第一步该怎么走。数据湖的困境恰恰是向量化的机会。两者结合让原本“沉睡”的图片、视频、语音在 AI 场景里变得可检索、可理解、可计算。这不是某个单一数据库产品的功能升级而是数据基础设施的一次架构级变化。1. 传统数据湖的局限能存、能算但“读不懂”很多团队最初搭建数据湖看中的是三点存储成本低格式开放支持大规模批处理。数据湖确实把这两点做到了。对象存储加 HDFS配合 Parquet、ORC 这类列式存储格式让企业能以极低成本积累海量原始数据。但一旦涉及多模态数据传统数据湖的短板就暴露得很明显。第一元数据能力太弱。传统数据湖的元数据本质上还是围绕“表、列、分区”来组织的。Hive Metastore、Hudi、Iceberg、Delta Lake 的核心抽象都是表格模型。图片的拍摄时间、地点的经纬度、画面里有没有行人这些信息很难用表的行列来表达。即使强行塞进结构化字段也会损失大量语义信息。第二非结构化数据检索基本靠“扫”。没有向量索引之前要从一百万张图片里找出“所有包含红色卡车”的图片只能先通过 OCR、目标检测等模型做批量预处理把结果写回标签表再走 SQL。每增加一种新的查询意图就要重新跑一遍预处理管线效率低成本高。第三数据之间的语义关联是断裂的。一段交通事故视频、对应的报警电话录音、事故处理报告文本三个不同模态的数据虽然描述的是同一件事但在数据湖里没有任何关联。传统方案通过“事故编号”这样的外键勉强关联但遇到模糊匹配、语义相似查询比如“找类似这个路口的拥堵视频”就完全无解了。如果用一句话概括数据湖擅长管理数据的“物理形态”不擅长理解数据的“语义内容”。而多模态 AI 应用恰恰最需要语义层面的理解和关联。2. 向量化的本质从“关键词匹配”到“语义匹配”向量化也叫 Embedding核心工作是把一段数据映射成一组固定长度的浮点数。比如一张图片被 ResNet 或 CLIP 编码成 512 维或 768 维的向量一段文本被 BERT 编码成同样维度的向量。这些向量在空间中的位置就代表了数据的语义。两个向量的点积或余弦相似度可以衡量它们在语义上的接近程度。“穿红衣服的行人”和“红衣行人”在文本关键词层面不匹配但在向量空间里距离很近。这就是向量化最大的价值它能理解同义表达和潜在语义而不只是做字面匹配。多模态数据融合里向量化的作用更明显。像 CLIP 这样的模型会把图片和文本映射到同一个向量空间。图片描述“一条雨天湿滑的高速公路”和一段真实的高速监控视频它们在空间中的距离会被拉得很近。这意味着用户可以用自然语言去搜索视频、搜索图片而不再依赖预先标注好的标签。数据湖引入向量化后数据处理的逻辑发生了根本变化写入链路原始数据写入对象存储或 HDFS 的同时多模态模型对数据做 Embedding向量和元数据一起写入。存储链路向量既可以直接存储在新增的向量列里也可以同步到专门的向量索引中。查询链路用户输入自然语言或上传参考图片系统先对查询内容做 Embedding然后在向量空间里做近似最近邻检索找出 Top-K 最相关的数据记录。这个模式本质上是在数据湖的量级之上叠加了一层“语义索引”。术语上常被称为“Lakehouse Vector Search”或“数据湖语义层”。3. 数据湖与向量数据库不是替代而是协同一个常见的困惑是既然向量数据库能直接存文本和图片的向量为什么还要扯上数据湖直接在 Milvus、Qdrant、Weaviate 里建集合往里塞向量不就行了这个观点有道理但忽略了真实数据场景的复杂性。向量数据库擅长的是海量向量的快速检索它不擅长存储原始文件。如果把几张原始图片、几段视频原文件都塞进向量数据库存储成本会很夸张。而数据湖的价值之一恰恰是低成本保存原始数据和历史版本。更合理的架构是原始多模态文件继续留在数据湖对象存储中。向量数据写入向量数据库或者数据湖新增的向量索引。向量检索返回结果的 payload 里保存原始文件在数据湖中的路径或 URI。需要原始内容时再从数据湖读取。这样向量数据库负责快速定位“哪些数据语义相近”数据湖负责提供完整、可靠、低成本的原始数据存储。两者是协同关系而不是替代关系。从另一个角度说现在的湖格式也在吸收向量能力。例如 Apache Iceberg、Delta Lake 的社区和商业版本都开始支持向量索引或向量检索功能。未来数据湖和向量数据库的边界会进一步模糊但短期内清晰的分工协作仍然是最务实的方案。4. 多模态向量化的完整技术栈做数据湖向量化改造不是引入一个组件就完事而是一整套技术栈的配合。下面按数据处理链路梳理。4.1 数据接入层原始数据可能来自消息队列、日志系统、业务数据库、文件上传服务。接入层需要把图片、视频、文本、语音等数据统一收拢写入数据湖的暂存区。常见组件包括 Kafka、Flink、Spark Structured Streaming以及各类 CDC 工具。4.2 嵌入模型层嵌入模型决定向量化的质量上限。文本BGE、M3E、Text Embedding、通义千问 Embedding 等中文场景更推荐 BGE 系列。图片CLIP、SigLIP、Chinese-CLIP其中 SigLIP 2 在图文对齐任务上有不错表现。视频通常的做法是抽帧后逐帧做图片向量化再对帧向量做聚合或序列建模。音频一般先做 ASR 转写文本再文本向量化也可以直接用音频 Embedding 模型。结构化数据把字段拼接成描述性文本再做 Embedding比如“车型卡车颜色红色地点G50 沪渝高速 K32”。关键点所有模态尽量映射到同一个向量空间这样跨模态搜索文本搜图、图搜视频才能成立。4.3 向量存储与索引层如果数据规模在百万级以下PostgreSQL 加 pgvector 插件就够用。千万级到亿级推荐 Milvus、Qdrant、Weaviate。如果不想引入额外组件可以先用数据湖的列存储保存向量配合全局暴力扫描在数据量不大时也能跑通场景。4.4 数据湖文件层原始文件建议继续使用 Parquet、ORC 等列式格式存储新增向量列时也和原表放在一起用 Iceberg、Hudi 或 Delta Lake 管理事务和快照。这样既保留数据湖的批处理分析能力又新增向量检索能力。4.5 查询与服务层对外提供两类 APISQL 查询基于 Spark SQL 或 Trino查询结构化字段和向量列。向量检索通过向量数据库客户端接收自然语言查询返回 Top-K 结果。在实际项目中这两类 API 通常会在一个统一服务里组合使用先向量召回再用 SQL 做过滤和聚合。5. 从零实现一个“数据湖 向量化”的演示项目下面用一个最小演示项目把整个流程串起来。场景设定为给交通数据湖图片库增加“以文搜图”能力。演示环境以 Python 为主模型用轻量的开源 Embedding 模型向量检索先用暴力扫描实现不引入重型数据库方便本地跑通。5.1 环境准备与依赖pip install numpy pillow torch transformers pip install pandas pyarrow模型部分使用clip-ViT-B-32或openai/clip-vit-base-patch32。如果你的机器不支持 GPUCPU 也能运行只是速度慢一些。下面的示例以 transformers 库加载 CLIP 模型为例。5.2 第一步构建图片嵌入索引假设数据湖里存放了一批交通监控图片路径结构为data/images/{date}/{hour}/{camera_id}.jpg。我们扫描目录生成每张图片的向量并把向量连同路径、时间、摄像头 ID 保存到 Parquet 文件。import os import numpy as np import pandas as pd from PIL import Image from transformers import CLIPProcessor, CLIPModel model_name openai/clip-vit-base-patch32 model CLIPModel.from_pretrained(model_name) processor CLIPProcessor.from_pretrained(model_name) image_dir data/images records [] for root, _, files in os.walk(image_dir): for file in files: if not file.lower().endswith((.jpg, .jpeg, .png)): continue path os.path.join(root, file) image Image.open(path).convert(RGB) inputs processor(imagesimage, return_tensorspt) with torch.no_grad(): image_features model.get_image_features(**inputs) # 归一化向量 vec image_features.cpu().numpy().flatten() vec vec / np.linalg.norm(vec) records.append({ path: path, camera_id: file.split(_)[0], vector: vec.tolist(), }) df pd.DataFrame(records) df.to_parquet(data/embedding_index.parquet) print(f共处理 {len(df)} 张图片)关键点向量必须做归一化这样点积相似度就等于余弦相似度方便后续检索。把向量直接存在 Parquet 里是为了让数据湖管理向量列数据量不大时可以直接暴力检索。5.3 第二步文本查询与相似度计算文本查询流程分两段先把查询文本用同一个 CLIP 模型映射为向量再和库里的图片向量做余弦相似度比较取 Top-K 返回。import numpy as np import pandas as pd from transformers import CLIPProcessor, CLIPModel model_name openai/clip-vit-base-patch32 model CLIPModel.from_pretrained(model_name) processor CLIPProcessor.from_pretrained(model_name) df pd.read_parquet(data/embedding_index.parquet) vectors np.stack(df[vector].values) def search_images(query_text, top_k5): inputs processor(text[query_text], return_tensorspt, paddingTrue) with torch.no_grad(): text_features model.get_text_features(**inputs) query_vec text_features.cpu().numpy().flatten() query_vec query_vec / np.linalg.norm(query_vec) scores vectors query_vec top_indices np.argsort(scores)[::-1][:top_k] results [] for idx in top_indices: results.append({ path: df.iloc[idx][path], score: float(scores[idx]), camera_id: df.iloc[idx][camera_id] }) return results results search_images(雾天高速公路上的车辆, top_k5) for r in results: print(r[path], r[score], r[camera_id])运行后你会看到返回的图片路径里大概率是雾天、低能见度或清晨场景的图片。这种能力在传统 SQL 检索里很难实现因为“雾天”不是图片自带的结构化字段。如果把图片换成视频片段思路也类似先抽帧再对关键帧做 Embedding最后把关键帧向量聚合为视频向量。常见的聚合方式是取平均、最大池化或者用视频级模型直接生成。5.4 第三步接入数据湖表格以 Parquet Iceberg 为例实际生产环境里不会用裸的 Parquet 文件管理向量索引。更常见的做法是把向量和元数据写入 Iceberg 或 Delta Lake 表。表结构大致如下CREATE TABLE traffic_image_index ( id STRING, path STRING, camera_id STRING, event_time TIMESTAMP, image_vector ARRAYFLOAT, PARTITION (event_time) );写入向量时用 Spark 的 Iceberg 数据源把 Parquet 数据批量写入 Iceberg 表。之后既可以用 Spark SQL 做传统的结构和向量列查询也可以把向量导出给 Milvus 或 Qdrant 建立专用索引。6. 性能优化数据量大了以后怎么办暴力扫描在百万级以下可以接受但数据量一旦上来就必须引入真正的向量索引。下面列出几条优化路径。6.1 使用 HNSW 或 IVF 索引向量数据库如 Milvus、Qdrant默认或主要支持 HNSW、IVF 等近似最近邻索引。HNSW 通过多层图结构把检索时间复杂度降到对数级。在 Qdrant 中创建带 HNSW 索引的集合只需要一个配置文件vectors: size: 512 distance: Cosine optimizers: indexing_threshold: 10000 index: type: HNSW hnsw: m: 16 ef_construct: 200ef_construct越高建索引越慢但召回率越高。m控制每个节点的连接数值越大图的连通性越强。6.2 混合检索向量召回 SQL 过滤一旦向量索引到位检索流程可以升级为两阶段先用向量召回 Top-N 条候选数据。再用结构化字段过滤比如时间范围、摄像头 ID、事件类型。这种策略在数据湖场景里非常实用。比如“找出 G42 高速 K102 附近今年 3 月所有雾天视频”可以先向量召回“雾天”相关视频再用location和event_time字段过滤。这样既保证语义相关性又保证查询条件的准确性。6.3 分批 Embedding 与增量更新多模态 Embedding 计算成本不低建议不要在数据写入时同步计算而是用异步任务批量处理。例如每 5 分钟从 Kafka 拉取一批新文件批量跑 Embedding写入向量索引。这样既避免阻塞写入链路又能控制计算资源的波动。7. 常见误区与工程坑点7.1 模型选型粗糙导致向量根本没有区分度有些人随便找个 BERT 模型做所有文本的向量化效果差是必然的。不同领域的文本用通用 Embedding 模型和用领域微调模型效果差距非常大。做交通领域数据最好在车辆描述、事故文本等数据上微调嵌入模型或者直接选用领域适配较好的中文模型。7.2 向量存储和原始数据脱节检索到了但取不回原文件这是最典型的架构错误。向量数据库里只存了向量和 ID但没存原始文件的 URI。结果检索出 100 条结果却不知道原始图片存在哪个桶、哪个目录。正确做法是把数据湖路径作为 payload 写入向量记录原始文件路径唯一。7.3 忽略了元数据管理向量本身没有业务含义。比如图片向量不能告诉业务方“这张图属于哪个项目、哪个摄像头、哪个时间段”。元数据必须伴随向量一起管理否则向量只是一个没有上下文的浮点数组。7.4 真实场景的召回率问题HNSW 或 IVF 都是近似检索不是精确检索。用百万级数据测试召回率通常能做到 95% 以上但对那些语义高度相似的边界样本近似的误差可能带来漏召回。如果业务对召回率要求极高建议先做精确检索压测再决定索引参数。7.5 成本意识缺失Embedding 模型推理需要 GPU 资源尤其是视频抽帧和多模态模型成本不能忽视。建议先在小样本上验证效果再规划全量计算预算。另外向量索引的内存开销也要算清楚512 维的浮点向量单条约 2KB 原始大小一亿条就是 200GB 量级需要评估内存或 SSD 成本。8. 多模态数据湖落地的分阶段路线如果要在真实项目里推进数据湖向量化不建议一步到位建议按三个阶段走。8.1 试点验证阶段选择一个高价值、数据量可控的场景比如“智能交通图片库跨模态搜索”。数据量控制在百万级以内用 pgvector 或 Qdrant 单机版本验证语义检索的效果。这个阶段的重点是回答三个问题向量化之后业务方是否觉得搜索比原来好用信息召回准确率是否达到可用水平全流程成本是否可接受8.2 平台化建设阶段试点验证通过后把向量化能力固化到数据平台里。数据接入、Embedding、索引构建、检索 API 都做成可复用的服务。此时引入 Milvus 或 Qdrant 集群接入 Iceberg 表和元数据管理。这个阶段要建立监控指标向量构建延迟、索引更新延迟、检索 p99 响应时间、召回率、资源使用率。8.3 规模化和生态接入阶段当向量检索成为数据平台的基础能力后各种 AI 应用都可以直接调用统一语义检索接口而不需要各自建索引。这个阶段还会面临更大的数据量建议评估分布式向量集群的容量规划、数据压缩、冷热分层策略。从成本优化角度高频访问的向量放内存或 NVMe SSD低频访问的向量可以放到对象存储只在需要时加载。9. 向量化不是终点而是数据湖通向 AI 的桥梁回到开头的智能交通场景。数据湖里沉积三年的图片、视频、文本一旦完成向量化就变成 AI 模型可以直接“翻阅”的记忆库。算法团队不再需要从零开始清洗标注而是通过语义检索快速构造高质量训练集。这带来的价值不只是省了几个月时间而是让过去根本没有利用空间的数据真正进入了 AI 应用的生产链路。数据湖和向量化的结合并不需要推翻现有基础设施。它更像是在原有存储上面加了一层“语义索引”让数据不再只是字节而是可理解和可检索的语义单元。给团队的落地建议可以总结为四句话别急着上重型向量集群先在一个小场景里跑通端到端效果。向量存储之前先想清楚原始数据的路径怎么关联。模型选型决定效果上限领域场景最好做模型微调。数据湖的批处理能力和向量数据库的检索能力各司其职不要互相替代。多模态数据“沉睡”的问题本质上不是一个存储问题而是一个语义理解问题。向量化提供的正是数据湖从“存储底座”走向“AI 基础设施”的关键一环。对于正在搭建数据平台、又不想被多模态数据困扰的团队来说现在正是把向量化纳入规划的最佳时机。