多模态大模型技术原理:从CLIP到原生统一架构

多模态的意义 真实世界的信息本就是多模态的——文字、图像、声音、视频。纯文本大模型只能理解被"文字化"的世界,而多模态模型直接感知原始信号,能力上限更高。 技术演进路线 阶段一:双塔模型(CLIP时代) CLIP开创了图文对齐的标准范式: 图像 → Image Encoder → 图像向量 I ∈ R^d 文本 → Text Encoder → 文本向量 T ∈ R^d 对比损失: 最大化匹配对的相似度,最小化不匹配对的相似度 CLIP的核心贡献是证明了"大规模弱监督预训练"的有效性——用4亿图文对训练,不需要精细标注。 但双塔模型有根本限制:图文交互只在最终向量层发生,无法做细粒度的图文理解(如"图片左上角的红色物体是什么")。 阶段二:桥接模型(BLIP/LLaVA时代) 桥接模型用一个适配层将视觉特征"翻译"到语言空间: 图像 → ViT → 视觉特征 → MLP Projector → 语言特征 tokens ↓ 文本 prompt + 视觉tokens → LLM → 回答 LLaVA的关键创新: 用GPT-4生成图文指令数据 两阶段训练:先训projector,再SFT 证明了"视觉编码器+投影层+LLM"的简洁架构有效 局限: 视觉token数量固定,不能动态调整 投影层能力有限,可能丢失视觉信息 训练分阶段,无法端到端优化 阶段三:原生多模态(GPT-4V/Qwen-VL时代) 原生多模态模型将视觉编码器和语言模型在预训练阶段就联合训练: 关键设计: 视觉编码器提取多分辨率特征 视觉token可变长(根据图像复杂度动态生成不同数量token) 在预训练阶段就混合图文数据 支持任意位置插入图像token Qwen-VL的技术细节: 图像 → ViT(变体) → 图像token序列 → 位置感知的adapter → 与文本token拼接 → Qwen LLM处理 Qwen-VL支持动态分辨率:大图像生成更多token,小图像生成更少token。通过这种方式保留了图像细节。 ...

2026-07-16 · 1 min · 135 words · 硅基 AGI 探索者

多模态大模型技术演进:从CLIP到原生多模态架构

多模态融合的三个阶段 多模态大模型的发展经历了三个阶段:模态对齐(CLIP)、模态桥接(LLaVA)、原生多模态(GPT-4o)。每个阶段都代表着对"如何让模型同时理解图像和文本"这一核心问题的不同回答。 第一阶段:CLIP双塔对齐 OpenAI在2021年提出的CLIP开创了对比学习对齐范本。CLIP分别用图像编码器和文本编码器提取特征,通过对比损失拉正样本对、推负样本对: class CLIP(nn.Module): def __init__(self, image_encoder, text_encoder, dim=512): self.image_encoder = image_encoder self.text_encoder = text_encoder self.logit_scale = nn.Parameter(torch.ones([]) * np.log(1/0.07)) def forward(self, images, texts): image_features = self.image_encoder(images) text_features = self.text_encoder(texts) # 归一化 image_features = F.normalize(image_features, dim=-1) text_features = F.normalize(text_features, dim=-1) # 对比损失 logit_scale = self.logit_scale.exp() logits = logit_scale * image_features @ text_features.T return logits CLIP的局限在于它是"理解"而非"生成"——可以判断图文匹配度,但不能生成图像描述或根据文本生成图像。但它奠定了后续多模态模型的基础:CLIP的视觉编码器被广泛应用于Stable Diffusion、LLaVA等模型中。 第二阶段:桥接架构(LLaVA) LLaVA代表了"视觉编码器+LLM"的桥接架构。核心思路是将图像编码为"视觉token"插入LLM的输入序列: [文本token] + [视觉token1] [视觉token2] ... [视觉tokenN] + [文本token] 关键设计选择: 视觉编码器选择 大多数模型使用CLIP ViT-L/14作为视觉编码器。它经过4亿图文对训练,视觉特征质量高。但也有例外:Qwen-VL使用自研的视觉编码器,支持动态分辨率。 连接器设计 连接器负责将视觉编码器的输出适配到LLM的输入空间: 线性投影(LLaVA-1.5):简单MLP,2层即可 Q-Former(BLIP-2):使用可学习的query token提取视觉信息 像素打散(Fuyu):直接将图像patch展平作为token LLaVA-1.5的线性投影看似简单,但在实践中效果最好——简单即有效。 分辨率处理 标准CLIP使用224x224分辨率,这限制了对细节的识别。解决方案: 动态分辨率(Qwen-VL):根据输入图像大小动态调整patch数量 切片策略(LLaVA-NeXT):将高分辨率图像切成多个子图,分别编码 原生高分辨率(InternVL):使用原生支持高分辨率的ViT 第三阶段:原生多模态架构 GPT-4o代表了原生多模态的新范式:不是将视觉编码器"嫁接"到LLM上,而是从头训练一个统一处理所有模态的模型。 原生多模态的核心特征 共享表示空间:图像、文本、音频在同一个embedding空间中 统一Transformer:单一Transformer处理所有模态,无需模态特定的编码器 端到端训练:从预训练阶段就混合多模态数据 架构设计推测 基于公开信息,原生多模态模型的架构可能如下: class NativeMultimodalModel(nn.Module): def __init__(self, dim=4096, n_layers=32): # 统一的token化器 self.text_tokenizer = TextTokenizer() self.image_tokenizer = ImageTokenizer() # VQ-VAE或类似 self.audio_tokenizer = AudioTokenizer() # 统一Transformer self.transformer = Transformer(dim, n_layers) # 统一输出头 self.text_head = nn.Linear(dim, vocab_size) self.image_head = nn.Linear(dim, image_codebook_size) self.audio_head = nn.Linear(dim, audio_codebook_size) 关键挑战在于图像和音频的tokenization:如何将连续的高维信号离散化为token序列。VQ-VAE和其变体(VQ-GAN、FSQ)是主流方案。 ...

2026-07-16 · 1 min · 176 words · 硅基 AGI 探索者
多模态RAG:图文混合检索的架构设计

多模态RAG:图文混合检索的架构设计

为什么需要多模态RAG? 传统RAG只能处理文字,但现实世界的信息是多维的。技术文档里穿插架构图、产品手册里有演示截图、研究报告里有数据图表——这些信息,纯文本RAG完全丢失了。 用户问"系统的整体架构是什么样的?",纯文本RAG只会返回一段文字描述,而无法返回架构图。这就是多模态RAG要解决的问题。 多模态RAG架构全景 ┌─────────────────────────────────────────────────────────┐ │ 多模态RAG系统架构 │ ├─────────────────────────────────────────────────────────┤ │ │ │ 用户查询 │ │ │ │ │ ▼ │ │ ┌─────────────┐ │ │ │ Query 分析 │ 判断用户需要图片、文字、还是图文 │ │ └──────┬──────┘ │ │ │ │ │ ┌────┴────┐ │ │ ▼ ▼ │ │ [纯文本查询] [需要图片查询] │ │ │ │ │ │ ▼ ▼ │ │ 文本检索 多模态检索 │ │ (向量库) (CLIP/图片向量) │ │ │ │ │ │ └────┬────┘ │ │ ▼ │ │ ┌─────────────┐ │ │ │ 结果融合 │ 图文结果融合排序 │ │ └──────┬──────┘ │ │ │ │ │ ▼ │ │ 多模态LLM生成回答(可理解和描述图片) │ │ │ └─────────────────────────────────────────────────────────┘ 四种架构方案详解 方案1:独立双路检索(Easiest) 文本向量库 图片向量库 │ │ └──► 合并 ◄──┘ │ ▼ 多模态LLM生成 最简单也是最常见的方案:文本和图片分别Embedding,分别检索,然后合并结果交给多模态LLM生成回答。 ...

2026-06-30 · 4 min · 845 words · 硅基 AGI 探索者
multimodal rag image text hybrid retrieval

多模态 RAG 实战:图文混合检索的工程实现

为什么需要多模态 RAG 传统 RAG 只处理文本,但现实世界的信息以多种模态存在:技术文档包含图表、医疗记录附带影像、电商页面图文并茂。2026 年的多模态 RAG 已经成为企业级 RAG 系统的标配。 核心架构 多模态 RAG 的关键挑战是:如何让文本 Query 检索到相关图片,以及如何让图片 Query 检索到相关文本。 ┌──────────────────────────────────────────────┐ │ 多模态 RAG Pipeline │ ├──────────────────────────────────────────────┤ │ │ │ 文档处理层 │ │ ├─ 文本分块 → Text Embedding │ │ ├─ 图片提取 → Image Embedding (CLIP) │ │ ├─ 表格解析 → Table → Text + Structure │ │ └─ 图文对齐 → Cross-modal Alignment │ │ │ │ 检索层 │ │ ├─ 文本向量索引 (bge-m3) │ │ ├─ 图像向量索引 (CLIP ViT-L/14) │ │ └─ 融合重排序 (Cross-modal Reranker) │ │ │ │ 生成层 │ │ └─ 多模态 LLM (GPT-5.5 / Claude 4) │ │ │ └──────────────────────────────────────────────┘ 工程实现 1. 文档解析与多模态提取 from unstructured import partition_pdf from PIL import Image import torch from transformers import CLIPModel, CLIPProcessor class MultimodalDocProcessor: def __init__(self): self.clip_model = CLIPModel.from_pretrained("openai/clip-vit-large-patch14") self.clip_processor = CLIPProcessor.from_pretrained("openai/clip-vit-large-patch14") self.text_embedder = TextEmbedder(model="bge-m3") def process_document(self, file_path: str): # 1. 解析文档 elements = partition_pdf(file_path) results = [] for elem in elements: if elem.category == "Text": results.append({ "type": "text", "content": elem.text, "embedding": self.text_embedder.encode(elem.text), "metadata": {"page": elem.metadata.page_number} }) elif elem.category == "Image": # 提取图片并生成 embedding img = elem.image img_embedding = self._encode_image(img) # 同时用 VLM 生成图片描述文本 img_description = vlm.describe(img) text_embedding = self.text_embedder.encode(img_description) results.append({ "type": "image", "content": img, "description": img_description, "image_embedding": img_embedding, "text_embedding": text_embedding, "metadata": {"page": elem.metadata.page_number} }) elif elem.category == "Table": # 表格转为结构化文本 table_text = self._table_to_text(elem) results.append({ "type": "table", "content": table_text, "embedding": self.text_embedder.encode(table_text), "metadata": {"page": elem.metadata.page_number} }) return results def _encode_image(self, image): inputs = self.clip_processor(images=image, return_tensors="pt") with torch.no_grad(): features = self.clip_model.get_image_features(**inputs) return features[0].cpu().numpy() 2. 双索引构建 class MultimodalIndex: def __init__(self): self.text_index = MilvusIndex( dim=1024, # bge-m3 metric="IP" ) self.image_index = MilvusIndex( dim=768, # CLIP metric="IP" ) def add_documents(self, docs: list): for doc in docs: if doc["type"] == "text": self.text_index.add( id=doc["id"], embedding=doc["embedding"], metadata=doc["metadata"] ) elif doc["type"] == "image": # 图片同时加入两个索引 self.image_index.add( id=doc["id"], embedding=doc["image_embedding"], metadata={"description": doc["description"], **doc["metadata"]} ) self.text_index.add( id=f"{doc['id']}_text", embedding=doc["text_embedding"], metadata={"ref_image_id": doc["id"], **doc["metadata"]} ) 3. 混合检索与跨模态重排序 class MultimodalRetriever: def __init__(self, index: MultimodalIndex, reranker): self.index = index self.reranker = reranker def retrieve(self, query: str, top_k: int = 10): # 1. 文本检索 text_hits = self.index.text_index.search( embedding=self.text_embedder.encode(query), top_k=top_k * 2 ) # 2. 用 CLIP 做跨模态检索(文本→图像) clip_query_emb = self.clip_encode_text(query) image_hits = self.index.image_index.search( embedding=clip_query_emb, top_k=top_k * 2 ) # 3. 合并候选 candidates = self._merge(text_hits, image_hits) # 4. 跨模态重排序 reranked = self.reranker.rerank( query=query, candidates=candidates, top_k=top_k ) return reranked 图文混合检索效果对比 方法 文本 Recall@5 图像 Recall@5 MRR 纯文本 RAG 0.82 0.00 0.71 纯图像 RAG 0.00 0.68 0.55 简单双路合并 0.80 0.65 0.73 双索引+重排序 0.88 0.79 0.82 双索引+VLM描述增强 0.91 0.85 0.88 实际案例:技术文档智能问答 以一份 200 页的技术白皮书为例,包含大量架构图和流程图: ...

2026-06-28 · 3 min · 503 words · 硅基 AGI 探索者
鲁ICP备2026018361号