前两节课我们理解了“多模态的本质”和“模态对齐的难题”。这节课我们聚焦模型的“具体构造”——多模态模型是如何通过设计结构来处理文本、图像等不同模态的?我们会拆解3类核心模型的内部结构细节和模态处理过程,用“庖丁解牛”的方式讲透它们的工作原理。
一、跨模态检索模型:让文本和图像“互搜”(以CLIP为例)
跨模态检索的核心是“让文本和图像在同一个‘特征空间’里可比”,CLIP(Contrastive Language-Image Pretraining)是这一领域的里程碑模型。我们不仅要知道它能做什么,更要搞懂它“内部的齿轮是如何咬合的”。
1. 核心目标:让“语义相关”的文本和图像在特征空间“挨得近”
比如“猫”的文本和猫的图像,它们的特征向量要尽可能接近;而“猫”的文本和狗的图像,特征向量要尽可能远离。这需要模型同时“读懂文本”和“看懂图像”,并学会用统一的“度量标准”判断相关性。
2. 结构:两个编码器+对比学习目标(早期对齐的典型)
CLIP的结构像“两台精密的翻译机”,分别把文本和图像翻译成同一种“特征语言”,再通过训练让它们“说同一种方言”。
-
(1)文本编码器:把文字变成特征向量
文本编码器的核心是一个Transformer模型(和GPT的基础结构类似),具体处理步骤:
① 分词与嵌入:输入文本(如“a red apple”)先被拆分成词元(tokens):[“a”, “red”, “apple”];每个词元通过“词嵌入层”转换成低维向量(比如768维),同时加入“位置编码”(标记词的顺序,比如“red”在“apple”前面)。
② Transformer编码:嵌入后的向量进入多层Transformer(包含多头自注意力和前馈网络)。自注意力让每个词元“关注”其他相关词元(比如“red”会重点关注“apple”),最终输出整个文本的“语义特征向量”(768维,浓缩了“红色苹果”的核心含义)。 -
(2)图像编码器:把图片变成特征向量
图像编码器用的是视觉Transformer(ViT),处理步骤类似“把图片拆成拼图再理解”:
① 图像分块:输入图像(比如224×224像素的照片)被分成16×16的小方块(patch),共14×14=196个块(像把一张图切成196张小图)。
② 线性投影:每个块(16×16×3像素,3是RGB颜色通道)通过线性层转换成768维向量(和文本特征维度一致,确保后续可比),再加入一个“类别嵌入”(class token,代表整个图像的全局特征)。
③ Transformer编码:和文本编码器类似,通过多层Transformer的自注意力,让每个图像块“关注”其他相关块(比如苹果的红色区域会关注苹果的轮廓块),最终输出“类别嵌入”对应的向量作为图像的“视觉特征向量”(768维)。 -
(3)对比学习目标:监督两个编码器“对齐”
训练时,模型会同时输入一批文本(比如1000条)和一批图像(1000张),其中只有部分文本和图像是“配对的”(如“a cat”对应猫的图片)。模型通过“对比损失”监督学习:- 让配对的文本-图像特征向量的“余弦相似度”尽可能高(接近1);
- 让不配对的文本-图像特征向量的相似度尽可能低(接近0)。
就像老师告诉学生:“这两个词是近义词,要记在一起;那两个是反义词,要分开记”。
3. 完整处理流程(以“图搜文”为例)
假设我们有一张“小狗”的图片,想找到最匹配的文本描述(如“a dog”“a cat”“a bird”):
① 图像编码器将“小狗”图片转换成视觉特征向量V;
② 文本编码器将每个候选文本转换成语义特征向量T1(a dog)、T2(a cat)、T3(a bird);
③ 计算V与T1、T2、T3的余弦相似度:sim(V,T1)=0.9,sim(V,T2)=0.3,sim(V,T3)=0.2;
④ 相似度最高的T1(a dog)就是匹配结果。
4. 代码示例:用CLIP验证“特征对齐”效果
我们用代码直观看看CLIP的文本和图像特征是否真的“对齐”:
from transformers import CLIPProcessor, CLIPModel
from PIL import Image
import torch
# 加载模型和处理器
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
# 输入:1张猫的图片 + 3个文本
image = Image.open("cat.jpg")
texts = ["a cat", "a dog", "a bird"]
# 处理输入,得到特征向量
inputs = processor(text=texts, images=image, return_tensors="pt", padding=True)
outputs = model(** inputs)
image_feat = outputs.image_embeds # 图像特征向量(1×768)
text_feat = outputs.text_embeds # 文本特征向量(3×768)
# 计算余弦相似度(验证对齐效果)
similarity = torch.nn.functional.cosine_similarity(image_feat, text_feat)
print("文本特征与图像特征的相似度:", similarity.detach().numpy())
预期结果:[0.89, 0.31, 0.25]
(“a cat”与猫的图像特征相似度最高),证明CLIP的特征确实对齐了。
5. CLIP的核心特点
- 结构关键:文本Transformer + 图像ViT,通过对比学习实现早期对齐;
- 优势:简单高效,能直接用于跨模态检索;
- 局限:只能“匹配”,不能理解复杂语义(比如无法回答“图中猫的颜色是什么”)。
二、视觉-语言理解模型:让图文“深度对话”(以BLIP为例)
跨模态检索只能判断“是否相关”,但现实中我们需要模型“理解图文的深层关系”(比如看图回答问题)。BLIP(Bootstrapping Language-Image Pre-training)通过设计“交叉注意力机制”,让文本和图像能像“对话”一样交互。
1. 核心目标:让文本和图像“互相理解细节”
比如输入图片(“3只黑色的猫”)和问题(“图中有几只猫?它们是什么颜色?”),模型需要:
- 图像告诉文本:“这里有3只猫,都是黑色的”;
- 文本告诉图像:“我需要关注数量和颜色”;
- 最终融合信息输出答案:“3只,黑色”。
2. 结构:图像编码器+文本编码器+交叉注意力(晚期对齐的典型)
BLIP的结构比CLIP更复杂,核心是“交叉注意力层”——它像“翻译官”,让文本和图像能“指着对方的细节交流”。
-
(1)图像编码器:提取图像的“区域特征”
BLIP用CNN(如ViT或ResNet) 提取图像特征,但和CLIP不同,它会输出“图像的区域特征”(而不只是全局特征):
① 输入图像经过CNN处理后,得到一个“特征图”(比如14×14×768,每个点代表图像中一个小区域的特征);
② 把特征图展平成196个“区域特征向量”(每个768维,对应图像的不同区域,比如猫的头部、身体、背景等)。 -
(2)文本编码器:提取文本的“词特征”
用BERT-like Transformer处理文本,输出每个词的特征向量:
① 输入文本(如“图中有几只猫?”)分词后,通过嵌入层和自注意力,得到每个词的特征向量(比如5个词,输出5×768的向量); -
(3)交叉注意力层:让图文“互相关注”
这是BLIP的“灵魂”,它能让文本的每个词“关注”图像的相关区域,同时让图像的每个区域“回应”文本的相关词。具体来说:- 交叉注意力的“查询(Q)”来自文本的词特征,“键(K)”和“值(V)”来自图像的区域特征;
- 计算每个词对所有图像区域的“注意力权重”(比如“猫”这个词会对图像中猫的区域分配高权重);
- 用权重加权求和图像区域特征,得到“文本感知的图像特征”(即图像中与文本相关的部分);
- 反过来,也可以让图像区域“关注”文本词(根据任务调整),最终融合成“图文交互特征”。
3. 完整处理流程(以视觉问答VQA为例)
输入:图片(“2只白猫在沙发上”)+ 问题(“猫是什么颜色?”)
① 图像编码器输出196个区域特征(包含猫的白色毛发区域、沙发区域等);
② 文本编码器输出问题的词特征:“猫”“是”“什么”“颜色”“?”(5个词向量);
③ 交叉注意力层工作:
- “颜色”这个词作为Q,图像区域特征作为K和V;
- 计算“颜色”对所有图像区域的注意力权重(白色毛发区域权重最高);
- 加权求和得到“与颜色相关的图像特征”(白色毛发的特征);
④ 融合后的特征输入分类器,输出答案:“白色”。
4. 代码示例:用BLIP实现视觉问答
from transformers import BlipProcessor, BlipForQuestionAnswering
from PIL import Image
# 加载BLIP问答模型
processor = BlipProcessor.from_pretrained("Salesforce/blip-vqa-base")
model = BlipForQuestionAnswering.from_pretrained("Salesforce/blip-vqa-base")
# 输入:图片 + 问题
image = Image.open("two_white_cats.jpg") # 两只白猫的图片
question = "what color are the cats?"
# 处理输入(图像+问题)
inputs = processor(image, question, return_tensors="pt")
# 模型输出答案
outputs = model.generate(**inputs)
answer = processor.decode(outputs[0], skip_special_tokens=True)
print("答案:", answer) # 预期输出:"white"
5. BLIP的核心特点
- 结构关键:区域特征+词特征+交叉注意力,实现晚期对齐;
- 优势:能理解图文细节关系,支持问答、caption等复杂任务;
- 局限:生成能力弱(比如不能根据文本生成全新图像)。
三、多模态生成模型:从“描述”到“创造”(以DALL·E 2为例)
前两类模型是“理解现有信息”,而多模态生成模型是“创造新信息”(如文本生成图像)。DALL·E 2的核心是“把文本的抽象语义,一步步转化为具体的视觉细节”。
1. 核心目标:让文本“指挥”图像生成
比如输入“一只穿西装的企鹅坐在办公桌前”,模型需要:
- 先理解文本的语义(企鹅、西装、办公桌、坐姿);
- 再把语义转化为视觉元素(企鹅的形态、西装的款式、办公桌的布局);
- 最终生成一张符合描述的、从未存在过的图像。
2. 结构细节:文本编码器+先验模型+扩散解码器(生成式对齐)
DALL·E 2的结构像“一条流水线”,分三步把文本“翻译”成图像:
-
(1)文本编码器:提取文本的“语义特征”
和CLIP的文本编码器一样,用Transformer把文本(如“a penguin in suit”)转换成768维的语义特征向量(确保准确捕捉文本含义)。 -
(2)先验模型:把文本语义“映射”成图像特征
这是DALL·E 2的“桥梁”,作用是:“根据文本语义,预测CLIP图像编码器会输出什么样的图像特征”。- 输入:文本语义向量(768维);
- 输出:对应的“CLIP风格的图像特征向量”(768维,即如果真有一张“穿西装的企鹅”图片,CLIP的图像编码器会输出的向量);
- 本质:学习“文本语义→图像特征”的映射关系(类似“根据文字描述,画出素描稿”)。
-
(3)扩散解码器:把图像特征“渲染”成高清图像
这是生成的“最后一步”,用扩散模型(Diffusion Model) 把先验模型输出的图像特征,转换成具体的像素图像:
① 扩散模型的核心是“从噪声到图像”的迭代过程:- 初始输入:随机噪声图(看起来像雪花);
- 迭代优化:模型根据图像特征向量,一步步“去除噪声”并“添加细节”(比如先模糊地画出企鹅轮廓,再添加西装纹理、办公桌细节);
② 解码器用U-Net结构(包含编码器和解码器,通过跳跃连接保留细节),最终输出256×256或512×512的高清图像。
3. 完整处理流程(文本生成图像)
输入文本:“a panda holding a cup of coffee”(一只举着咖啡杯的熊猫)
① 文本编码器输出语义特征向量T;
② 先验模型根据T,预测出对应的图像特征向量I(即CLIP图像编码器看到这张熊猫图会输出的向量);
③ 扩散解码器启动:
- 第1步:输入随机噪声图;
- 第10步:噪声减少,隐约看到熊猫的轮廓和一个杯子的形状;
- 第50步:细节增加,熊猫的黑白毛色、咖啡杯的把手逐渐清晰;
- 第100步:生成最终图像(熊猫举着咖啡杯,背景可能有桌子等细节)。
4. 代码示例:用Stable Diffusion(类DALL·E 2模型)生成图像
from diffusers import StableDiffusionPipeline
import torch
# 加载模型(需GPU支持,CPU较慢)
pipe = StableDiffusionPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
torch_dtype=torch.float16
).to("cuda")
# 输入文本提示
prompt = "a panda holding a cup of coffee, in a cozy café, warm lighting"
# 生成图像(50步迭代)
image = pipe(prompt, num_inference_steps=50).images[0]
image.save("panda_coffee.png")
print("生成完成,图像保存为panda_coffee.png")
5. DALL·E 2的核心特点
- 结构关键:文本编码→先验映射→扩散生成,端到端实现模态转换;
- 优势:能创造全新内容,支持复杂文本描述生成;
- 挑战:需要平衡“语义准确性”(符合文本)和“视觉合理性”(图像不违和)。
四、三类模型的结构与处理过程对比
模型类型 | 核心结构模块 | 模态处理流程核心步骤 | 对齐方式 | 核心能力边界 |
---|---|---|---|---|
跨模态检索(CLIP) | 文本Transformer + 图像ViT + 对比损失 | 文本→语义向量;图像→视觉向量;计算相似度匹配 | 早期对齐 | 只能匹配,无法理解细节或生成内容 |
视觉-语言理解(BLIP) | 图像区域特征 + 文本词特征 + 交叉注意力 | 图像→区域向量;文本→词向量;交叉注意力互相关注;融合输出 | 晚期对齐 | 理解图文细节,支持问答、caption |
多模态生成(DALL·E 2) | 文本编码器 + 先验模型 + 扩散解码器 | 文本→语义向量;语义→图像特征;特征→像素图像 | 生成式对齐 | 创造新内容,支持文本→图像等模态转换 |
总结
这节课我们深入拆解了三类经典模型的“内部结构”和“模态处理细节”:
- CLIP通过“双Transformer编码器+对比学习”,让文本和图像在早期就对齐到同一特征空间,实现跨模态检索;
- BLIP通过“交叉注意力”让文本和图像的细节互相关注,实现深层语义理解,支持问答等复杂任务;
- DALL·E 2通过“文本编码→特征映射→扩散生成”的流水线,把抽象语义转化为具体图像,实现创造性生成。
理解这些结构的差异,就能明白为什么不同模型能胜任不同任务——结构决定功能,而功能的进化(从匹配到理解再到生成),正是多模态技术发展的主线。下一节课,我们会进一步探讨这些模型的核心能力在实际场景中的应用。