跳到主要内容
长记忆大模型系统

第6章:多模态语义记忆与 Embedding 协同存储

embedding 与 blob 双流共生模型 + 列式多模态格式(Lance/Parquet) + 多模态向量库 + CLIP-style 检索 + GPUDirect Storage 直通——长记忆系统里多模态那一档怎么落地

多模态记忆 embedding Lance LanceDB CLIP GPUDirect Storage blob 存储

第 5 章把”向量索引”讲透了——但向量索引只是多模态长记忆的索引层,真正占容量、决定带宽的是底下的原始 blob(图像 / 音频 / 视频 / 长文档)。一份多模态长记忆的物理形态是embedding(KB 级,高频检索)+ blob(MB-GB 级,低频访问)的双流共生——两者元数据共享、生命周期一致,但访问模式南辕北辙。本章把多模态长记忆这一档的存储设计讲清:双流共生模型、Lance 这类列式多模态格式、CLIP-style 跨模态检索的存储侧含义、GPUDirect Storage 给”按需取一张图”的低延迟通路、视频/长音频的特殊性。读完本章你能回答两个工程问题:多模态向量库选 LanceDB / Milvus / Weaviate 哪个? 以及 生产 Agent 系统如何让”取一张图”的端到端延迟卡在 50 ms 以下?

📑 目录


1. 多模态长记忆的新挑战

1.1 单模态时代的”够用”在多模态时代不够

维度单模态长记忆(文本)多模态长记忆
单条对象大小KB 级 token 序列embedding KB + blob MB-GB
总容量(中型 Agent)GB 级TB 级
每次查询访问数据命中条目 tokenembedding 命中 + 偶发拉 blob 给模型看
写入模式流式追加文本流式 + 批量(用户上传一批照片)
容量增长人类打字速度上限手机相机 / 摄像头 —— 几 GB / 天

🌟 核心转变:容量从 GB 级跳到 TB 级——这不是量变,是介质必然要变。再大的 DRAM 也装不下个人级多模态记忆,SSD 是必然落点;同时 embedding 检索路径还要快——这就强迫”embedding 与 blob 分流”。

1.2 三类典型多模态长记忆场景

场景数据特征关键约束
个人 Agent 相册记忆图片为主,数千-数十万张按时间/地点/事件检索,大对象偶发拉
企业多模态知识库文档(含图表)、产品图片、培训视频强权限过滤,跨模态联合检索
多模态客服 / 监控 Agent实时图像/视频流 + 历史归档写入吞吐 + 长期归档分层

观察:三类场景对存储的要求完全不同——通用方案做不到”一种规格全适配”,分层 + 分模态 + 分场景 是基本设计原则。


2. 双流共生模型:embedding 与 blob

2.1 概念图

   一条多模态长记忆 = (embedding, blob, metadata)
                         │      │       │
                         │      │       └─ 时间 / 用户 / tag
                         │      │
                         │      └─ 原始字节(图/音/视频)

                         └─ 高维向量(检索用)

   生命周期相同   |   访问频率不同   |   存储介质不同

2.2 两条流各自的访问模式

大小访问频率访问粒度存储倾向
embedding 流KB 级 / 条高(每次召回都用)单向量DRAM 主导,热点 HBM
blob 流MB-GB 级 / 条极低(只在需要时拉)大块顺序读SSD 主导,极热 DRAM

🍎 直觉比喻:embedding 是一本书的目录,blob 是正文 —— 读者(LLM / Agent)频繁翻目录,只有真正决定看某一章时才翻正文。把目录和正文都印在牛皮纸上太奢侈,把目录也丢柜子里又找不到。

2.3 关键设计原则:metadata 一致 + 物理分流

        ┌──────────────────────────────────┐
        │      统一 metadata 层             │
        │  obj_id → (emb_loc, blob_loc, …) │
        └──────────────────────────────────┘
                 │             │
        ┌────────┘             └────────┐
        ▼                               ▼
   embedding 池                       blob 池
   (DRAM 主 + HBM 热点)              (SSD 主 + DRAM 极热)
   按向量索引组织                    按 chunk / 列式组织

🌟 核心准则:embedding 与 blob 物理分开存,metadata 共享同一个 ID 空间。这样:

  • 检索路径(走 embedding)与原始访问路径(走 blob)各自最优
  • 升级 / 重建 embedding 时不影响 blob
  • 删除 / 归档时按 ID 一起处理,不丢失对应关系

2.4 反例:错误把它们塞一起的代价

如果把 embedding 和 blob 紧邻存(比如同一个 row 里):

  • 检索 cache miss 频繁 —— 每次拉 4 KB embedding 顺带把 5 MB blob 拉到 page cache,DRAM 命中率崩
  • 写入放大 —— 加一个新 embedding 要写一个 row,row size 几 MB
  • 不能独立量化 —— embedding 想 PQ,blob 想 JPEG,共享 row 没法协同

📍 工程教训:双流物理分开是非协商项


3. 列式多模态格式:Lance / Parquet / Arrow

3.1 列式格式的核心优势

传统行式格式(JSON Lines, CSV)的问题:所有字段挤在一起,读 embedding 必须扫完整 row。列式把每个字段独立存放,只读 embedding 列就只读 embedding 列对应的物理块——SSD IO 立即降一个量级。

3.2 三种主流列式格式对照

格式出身多模态友好度关键特性
Apache ParquetHadoop 生态强压缩、统计推断,大数据分析标配
Apache Arrow内存格式零拷贝跨语言、Python/Spark/Dask 通用
Lance / LanceDB多模态原生向量列原生支持、版本化、Python 友好

🌟 Lance 的关键差异化:它把向量列作为一等公民,在格式层就支持 ANN 索引(IVF / HNSW),不需要外挂向量库——这正好契合多模态长记忆的场景。

3.3 Lance 的多模态长记忆适配点

表结构示例(Lance):
┌──────┬──────────────┬──────────┬──────────┬─────────────┐
│ id   │ embedding    │ blob_uri │ ts       │ tags        │
│      │ (float[768]) │ (str)    │ (int64)  │ (list[str]) │
├──────┼──────────────┼──────────┼──────────┼─────────────┤
│ 001  │ [0.12,…]     │ s3://… │ 2025-…   │ [photo,kid] │
│ ……   │ ……           │ ……       │ ……       │ ……          │
└──────┴──────────────┴──────────┴──────────┴─────────────┘

物理上:
   embedding 列  ── 独立 chunk,可直接被向量库索引扫
   blob_uri 列   ── 紧凑字符串,定位到 SSD/对象存储
   ts/tags 列    ── 用于过滤的小列,常驻内存可能

🧠 关键洞察:列式 + 向量列原生 = 检索路径与原始数据路径自然分流。这是 Lance 比”Parquet + 外挂 FAISS”组合更适合长记忆的根本原因。

3.4 列式格式 vs 传统对象存储

维度对象存储(S3 / OSS)列式格式(Lance)
单 blob 访问优(一次 GET 拿到)中(要解压 column block)
批量检索极差(N 次 GET)优(一次扫一个 chunk)
元数据查询极差(单独索引层)优(自带列统计)
embedding 检索不支持(要外挂)原生支持

📍 决策准则:embedding + 小元数据 → Lance;大 blob → 对象存储 / 本地 NVMe。两层各取所长。


4. 多模态向量库的工业化方案

4.1 主流选项速查

系统出身多模态原生适合规模关键特性
MilvusZilliz 开源部分十亿级分布式、多种索引
QdrantRust 实现部分千万-亿级filtering 强、payload 丰富
WeaviateGraphQL 风格千万-亿级模块化向量化器
LanceDBLance 之上千万-亿级列式 + 多模态原生 + 版本化
Marqo多模态优先中等规模内置 CLIP / 视觉 embedding
Chroma轻量 Python千万级嵌入式 / SDK 化

4.2 选型决策树

  你的场景:
    ├─ 单机 / 嵌入式 / 快速 prototype
    │   → Chroma / LanceDB

    ├─ 中规模 + filter 重 + 多 payload
    │   → Qdrant

    ├─ 十亿级 + 分布式
    │   → Milvus

    ├─ 多模态原生 + 列式 / 版本化重要
    │   → LanceDB

    └─ 多模态 + 内置 CLIP-style 模型
        → Marqo / Weaviate

🌟 观察:没有”最佳”答案——按场景选。但对长记忆 Agent 系统,LanceDB 是当前最贴的方案(列式 + 多模态原生 + 与 KV / blob 同源思路一致)。

4.3 通用 ANN 库 vs 多模态向量库

维度FAISS / DiskANN(底层 ANN)多模态向量库(Milvus 等)
抽象层级算法库服务化
metadata 过滤弱 / 后过滤内置
多模态不支持(要自己拼)原生
多租户自己做内置
写入流式自己做内置(部分)

决策建议:项目示范系统用 LanceDB / Milvus 等服务化方案做基线,真正性能瓶颈处下沉到 DiskANN / Vamana 等算法库——分层架构更容易出论文。


5. CLIP-style 跨模态检索的存储侧含义

5.1 跨模态检索基础范式

CLIP(OpenAI, 2021)证明:用大量”图像-文本对”对比学习,可以让两种模态的 embedding 落到同一个向量空间——查文本能找到图片,查图片能找到文本。

   文本编码器 ──> emb_text(768维)
                                       \
                                        \── cosine 相似度 ──> 检索
                                        /
   图像编码器 ──> emb_image(768维)    /

后续:SigLIP, EVA-CLIP, BLIP-2, CoCa, SigLIP2, Qwen2-VL embedding 等持续迭代。

5.2 跨模态检索给存储带来什么

好消息:所有模态的 embedding 维度统一——可以用同一个向量索引存,写入时只标 modality tag。

坏消息:距离度量必须严格 —— 跨模态对比学习的几何性质比单模态更敏感,不能随便量化(精度敏感性高)。

设计含义:

  1. embedding 量化(PQ)的档位要保守一些
  2. 不同模型版本的 embedding 不能混存(几何空间不同)
  3. 模型升级要考虑已存 embedding 的迁移——本质是”embedding 重建”工程问题

5.3 多向量(multi-vector)与晚期交互

范式代表存储成本
单向量(CLIP / dense retrieval)一个对象一个 emb
多向量(ColBERT / late interaction)一个对象数十-数百 emb数十×
多模态多向量(VL late interaction)图像 patch + 文本 token 各一个 emb100× 起

🌟 关键观察:多向量召回质量更高,但存储 100×——长记忆系统里要不要用,取决于场景。

📍 建议:热数据用单向量保速度,冷归档可考虑多向量保召回——分层策略本身可以驱动检索精度的弹性。

5.4 给本项目的启示

🌟 项目第一模块的统一抽象必须支持:

  1. 多种 embedding 模型版本共存(不能强制全平台升级)
  2. 多向量数据结构(列式格式天然友好)
  3. 量化档位精度感知(模态不同,容忍度不同)
  4. embedding 重建 pipeline(模型升级时的数据迁移)

6. 大对象的 GPUDirect Storage 直通

6.1 问题:从 SSD 拉一张图给 LLM 看,延迟在哪?

传统路径(无 GPUDirect Storage):

NVMe SSD ─── DMA ───> CPU bounce buffer ─── memcpy ───> GPU HBM
            ~ 100µs           ~ 几百 µs                ~ ms

加上 OS page cache、文件系统、可能的网络一跳——端到端可能 50-200 ms,对实时多模态 Agent 来说太慢。

6.2 GPUDirect Storage(GDS)的修复

NVMe SSD ────── DMA(直通) ─────────> GPU HBM
         绕开 CPU,无 bounce buffer
         ~ 100µs + 顺序带宽限制

📌 端到端可压到 几 ms 级别(对几 MB 图像),且 CPU 几乎不参与——CPU 释放出来给其它工作。

6.3 长记忆系统的具体用法

   ┌──────────────────────────────────┐
   │ Agent 决定"看一眼用户上传的图"  │
   └────────────┬─────────────────────┘


   ┌──────────────────────────────────┐
   │ 元数据查找(LanceDB / 自建):    │
   │   obj_id → blob_uri = "/nvme/…"  │
   └────────────┬─────────────────────┘


   ┌──────────────────────────────────┐
   │ GDS 直读到 GPU HBM               │
   │ 同时启动 LLM forward 的视觉编码  │
   └────────────┬─────────────────────┘


       Vision encoder 处理 → 给 LLM 当 token

6.4 工程要点

内容
文件系统支持NVMe over PCIe + GDS 兼容 FS(ext4 / xfs 在合适内核版本下 OK)
文件大小友好MB 级以上才显著(小文件 syscall overhead 主导)
与图像解码协同NVIDIA nvJPEG / DALI 可在 GPU 上做 JPEG 解码
与多模态 encoder 协同直接喂 ViT / CLIP encoder,链路全 GPU

设计含义:长记忆多模态系统的”取 blob”路径,理想形态是 SSD → GDS → GPU encoder → LLM 全程不经 CPU——这是模块零第 4 章 NIXL / Magnum IO 思路的多模态对应。


7. 视频与长音频长记忆的特殊性

7.1 视频:数据量再上一个数量级

  • 单分钟 1080p 视频 ≈ 数百 MB
  • 一个 Agent 一天的录像 ≈ TB 级
  • 检索粒度:帧 / 镜头 / 事件 / 片段 —— 不是整段视频

7.2 关键设计:多粒度索引

   原始视频(SSD)

        ├── 帧采样 → 帧 embedding(每秒一帧)
        ├── 镜头切分 → 镜头 embedding
        ├── 字幕 ASR → 文本 chunk + embedding
        └── 关键事件 → 事件 embedding + 时间戳

🌟 存储含义:索引层数据 = 几百 MB,原始层 = 几百 GB——比例 1:1000,典型的”索引常驻 + blob 按需取”。

7.3 长音频(会议、播客)

  • 比视频小一个量级,但仍是 GB / 小时级
  • ASR 转写后文本 chunk + 音频片段双流共生
  • 长 Agent 任务里(如”总结这场两小时会议”),需要按时间窗大块顺序读 → SSD 顺序 IO 友好

7.4 给本项目的启示

🌟 视频 / 长音频是多模态长记忆的容量主体——本项目示范系统设计时:

  1. 多粒度索引作为 design pattern,不只视频用
  2. 冷归档到对象存储是必要的(本地 NVMe 装不下太久)
  3. GDS + 流式解码对视频/音频回放至关重要

8. 多模态长记忆的 8 条设计准则

8.1 准则 1:embedding 与 blob 物理分流,metadata 共享 ID

不要塞一起,但要能通过 obj_id 互相定位。

8.2 准则 2:列式格式优先,大 blob 走对象存储 / 本地 NVMe

LanceDB 是当前最贴长记忆场景的选择,但 blob 可以仍然走 S3/OSS,只在 LanceDB 里存 URI。

8.3 准则 3:embedding 不同模型版本不混存

模型升级时新建 namespace,旧 embedding 与新查询不可比较。

8.4 准则 4:跨模态量化要保守

模态间几何关系比单模态敏感——PQ 档位、INT8 量化都要校验。

8.5 准则 5:多向量数据结构上层处理,存储层透明

底层只存 List,上层(检索算子)负责 late interaction 计算。

8.6 准则 6:大对象走 GPUDirect Storage,CPU 不参与数据搬运

multimodal LLM 推理时,blob 直接 SSD → HBM。

8.7 准则 7:视频 / 长音频用多粒度索引

帧 / 镜头 / 事件 / 文本 各自索引,查询融合。

8.8 准则 8:容量主体进对象存储 / 冷归档,本地 NVMe 是热缓存

TB 级别的多模态原始数据不可能全放本地 NVMe——架构必然是 “本地 NVMe(热)+ 对象存储(冷)“。


9. 给本项目的整合启示

9.1 已有可复用武器

武器来源用在哪
列式多模态格式Lance / LanceDB多模态长记忆主存储
跨模态 embeddingCLIP / SigLIP / Qwen2-VL检索基础模型
GDS 直通NVIDIA Magnum IOblob 取出路径
GPU 图像 / 视频解码nvJPEG / NVIDIA DALI端到端全 GPU
多模态向量库LanceDB / Marqo / Weaviate / Milvus服务化基线
多粒度索引视频检索经典做法视频 / 长音频长记忆

9.2 本项目要补的拼图

缺口内容难度
⭐⭐⭐ embedding 与 KV 同源 metadata 层一份多模态对象在 KV(若被检索回来用作上下文) + embedding + blob 三处的统一 ID
⭐⭐⭐ 跨层级演化协同用户 X 的”近期高频图片”集体升 DRAM,Ta 的 KV 也跟着升中-高
⭐⭐ 多模态量化的精度感知不同模态可承受的量化档位不同,统一抽象要支持
⭐⭐ 多向量数据结构List 在三级存储里的物理布局优化
⭐⭐ embedding 模型升级 pipeline平滑迁移已存数据中(工程为主)
GDS + 多模态 encoder 流水化SSD → GDS → encoder → LLM 全 GPU中(工程)
视频 / 长音频多粒度索引帧 / 镜头 / 事件统一编址

9.3 与第 4 章 KV 武器的协同视图

                ┌────────────────────────────────────┐
                │   长记忆数据统一抽象               │
                │   {KV, 向量索引, 多模态(emb+blob)} │
                └────────────────┬───────────────────┘

       ┌─────────────────────────┼──────────────────────────┐
       ▼                         ▼                          ▼
   KV 武器(Ch4)             向量武器(Ch5)             多模态武器(Ch6)
   - PagedAttention          - DiskANN/SPANN           - LanceDB 列式
   - LMCache 跨实例池        - Filtered DiskANN        - GDS 直通
   - InfiniGen 重要 token    - AlayaDB 算子级          - 多粒度索引
   - CacheGen 编码           - GPU-ANN
   - Pensieve 亲和

                    ┌────────────┴───────────┐
                    ▼                        ▼
              统一 metadata 层         跨层级演化协同
              (Ch8)                   (Ch10)


              单 token 边际成本(Ch11)

🌟 关键洞察:多模态这一章不能孤立看——它和 KV 战场、向量战场在 统一 metadata 层 相遇。这是 Ch8 的核心命题,也是项目第一模块最硬的科学问题。


✅ 自我检验清单

  • 多模态 vs 单模态:能列出至少 3 个容量 / 访问 / 写入维度的差异
  • 双流共生:能解释为什么 embedding 和 blob 必须物理分流但 metadata 共享
  • 列式格式价值:能说出 Lance 和”Parquet + 外挂 FAISS”对长记忆的差异
  • 多模态向量库选型:能给出 LanceDB / Milvus / Marqo / Qdrant 的适用场景
  • CLIP-style 范式:能解释统一向量空间对存储设计的好/坏消息
  • 多向量代价:能讲清 ColBERT / late interaction 100× 存储代价的来源
  • GDS 路径:能画出”SSD → GPU HBM”绕开 CPU bounce buffer 的图
  • 视频多粒度索引:能列出帧 / 镜头 / 事件 / 文本四种索引的关系
  • 8 条设计准则:至少能默写 6 条
  • 三战场协同:能讲清 Ch4(KV)+ Ch5(向量)+ Ch6(多模态)在 Ch8 统一 metadata 上汇合

📚 参考资料

列式 / 多模态格式

多模态 embedding 模型

  • CLIP(OpenAI, ICML 2021):arXiv 2103.00020
  • SigLIP(Google, 2023):arXiv 2303.15343
  • EVA-CLIP(2023):arXiv 2303.15389
  • BLIP-2(Salesforce, ICML 2023):arXiv 2301.12597
  • Qwen2-VL embedding / InternVL —— 主流多模态 LLM 自带 embedding

多向量与 late interaction

  • ColBERT / ColBERT-v2(Khattab et al., SIGIR 2020/2022) —— late interaction 经典
  • PLAID(Santhanam et al., 2022) —— ColBERT 的 SSD 加速

多模态向量库实现

NVIDIA 多模态加速

综述

  • A Survey on Multimodal Large Language Models(2024)
  • Multimodal Retrieval-Augmented Generation: Survey(2024)

本系列其它模块