RAG 多模态检索:支持“看图”找资料
《AI 知识卡片》第 13 期 · 多模态嵌入拆掉“模态墙”图和文字才能互相搜到在手机相册里搜“海边”它能把几年前那张海边的照片翻出来你没给照片起过名字也没打过标签——这个就叫以文搜图正是 RAG 处理图片的方式。为什么值得单独讲一期因为真实的知识库很少是纯文字的可能有产品图、界面截图、报表、流程图等。如果 RAG 只认文字这些资料就等于不存在——明明躺在资料库里却永远检索不到。为什么文字检索不到图片文字经过 Embedding 模型会变成一串数字落在一张“语义坐标图”上意思近的挨在一起。图片也一样可以变成向量问题是图片在另一张坐标图并不互通。文字模型画的坐标图和图像模型画的坐标图坐标系毫无关系。同一个概念在两张地图上的位置对不上算出来的距离也就没有意义——我们称之为模态墙专业表达为“模态鸿沟”Modality Gap。所以多模态检索要解决的不是“图片能不能变成向量”而是怎么让图和文字落进同一张地图实现跨模态对齐。怎么把图和文字凑到同一张坐标图上打破这堵墙的代表作是 OpenAI 的CLIP。它的做法说起来只有两步。第一步两个编码器。一个专管图片一个专管文字各自把输入变成向量。注意它们仍是两个模型——共享的不是模型是最终那个向量空间。图片那一侧是怎么算的简单说把图当成一句话来读。先把整张图切成网格小块比如 16×16 一块每一小块当作一个“词”然后照着处理文字的老办法让这些小块通过自注意力互相“环顾全图”。比如“一张汽车的图片”——车轮那一块会注意到车身和另一个车轮于是“这是一辆车”的信息就浮现出来。最后把所有块池化成一个向量这套结构叫视觉 TransformerViT。第二步用对比学习把两边对齐。这是核心部分训练时喂进一大批“图片 描述”的配对模型的目标很朴素让正确配对的向量彼此靠近让所有错误配对的向量互相远离。海量数据这么拉扯下来两个编码器就被逼着达成了默契比如描述“一只奔跑的狗”的文字和一张真的小狗奔跑的照片会落在地图上几乎同一个位置。这里有个容易误会的地方对齐是模型在预训练时就做完的不是你建库时要做的事。假如你手上有一批图片建库时把图片过一遍图像编码器encode_image(图片路径)它自己就能算出该落在哪儿也不需要你自己输入图片描述。查询时把文字过一遍文本编码器同样算出一个位置两边能比距离这就是模型预训练的魅力。这也是“零样本”的本意——零标注样本图不用配文字模型也不必见过你这批图。反过来说模型并不真“读懂”了你的图它只是把画面特征映射成一个位置。画面类型一旦超出它训练时见过的范围这个位置就会算歪。图片的存和检索图片一旦变成向量后面的流程和文字完全一样。向量库只认数字压根不关心它原来是文字还是图片。所以存一条记录 一个向量 一个指向图片的路径。图片本身不进库库里只有它的坐标和住址。查把问题变成向量 → 在同一个空间里找最近的几个 → 命中之后凭路径去把图取出来。唯一的前提是那句老规矩只是这次跨了模态存的时候和查的时候必须用同一个模型。同一个模型才保证同一个空间、同样的维度向量之间才有得比。用bge-visualized-m3模型本地实测发现图片配上文字说明一起编码语义表达最强图文组合之间的相似度达到 0.9058比纯图片之间的 0.8318 明显更高。如果你的图片本来就带标题、图注或周边说明别浪费把它们和图片一起编码。# 建库图片自带图注一起编码向量语义更饱满vecmodel.encode(imagebeach.jpg,text海滩上的日落)# 查询qmodel.encode(text海边日落)一句话总结图片进不了 RAG不是因为它不能变成向量而是因为它的向量和文字的向量不在同一张地图上多模态嵌入干的就是拆掉这堵墙。