为什么需要多模态模型?
过去很长时间里,人工智能系统大多专注于处理单一类型的数据。
例如:
- 文本模型负责理解语言
- 图像模型负责识别图片
- 语音模型负责处理声音
这种方式推动了很多技术突破,但随着应用场景越来越复杂,仅依赖单一模态已经难以满足需求。
现实世界的信息并不是孤立存在的。
人类理解世界时会同时:
看
↓
听
↓
阅读
↓
行动
而不是只依赖一种信息来源。
因此,多模态模型逐渐成为人工智能发展的重要方向。
单模态模型的局限性
单模态模型(Single-modal Model)指的是:
一次只处理一种类型数据的模型。
例如:
文本模型:
arduino
输入:
"这是一只猫"
↓
输出:
识别语义
视觉模型:
输入:
猫的图片
↓
输出:
识别物体
这些模型虽然在各自领域表现优秀,但存在明显限制。
信息孤岛问题
不同模态之间无法直接共享知识。
例如:
文本模型:
知道"猫"
视觉模型:
知道猫长什么样
但:
文本理解
×
视觉理解
模型无法天然建立联系。
信息缺失问题
单一模态通常无法提供完整信息。
例如:
看到:
一个人举着手
可能意味着:
- 打招呼
- 提问
- 挥手告别
如果同时获得声音:
"老师,我有问题"
理解会更准确。
推理能力受限
复杂任务往往需要多个信息源。
例如:
看图回答问题
自动驾驶
机器人操作
这些任务无法依赖单一模态完成。
现实世界天然是多模态的
现实世界的信息本身就是多模态的。
例如:
一个简单场景:
一个人在雨天撑着红伞过马路
人类会同时利用:
视觉:
看到雨、伞、街道
听觉:
听到汽车声音
语言:
理解别人说"注意车辆"
这些信息共同构成认知。
对于人类来说:
diff
看
+
听
+
语言
↓
理解世界
这是自然过程。
机器人也是类似:
摄像头
麦克风
雷达
传感器
↓
决策
如果每种信息独立处理:
多个孤立系统
协作会变得困难。
因此:
现实世界要求模型能够统一处理多种信息来源。
多模态模型要解决什么问题
多模态模型(Multimodal Model)的目标并不仅仅是:
同时处理图片和文字
更重要的是:
让模型理解不同模态之间表达的是同一个世界。
核心问题包括:
跨模态理解
例如:
输入:
一只橘猫坐在沙发上
模型能够找到对应图片。
或者:
上传图片:
橘猫照片
模型能够生成:
"一只橘猫坐在沙发上"
实现:
文字
⇄
图片
统一表示
不同模态的数据形式完全不同:
文本:
Token序列
图片:
像素矩阵
音频:
波形信号
模型需要学习:
猫(文字)
≈
猫(图片)
≈
猫叫声
映射到统一语义空间。
跨模态推理
例如:
用户上传图片:
一个人拿着杯子
提问:
他接下来可能做什么?
模型需要:
diff
理解图片
+
调用常识
+
语言推理
得到:
喝水
多模态生成
例如:
输入文字
↓
生成图片
或:
输入图片
↓
生成描述
实现:
- 文生图
- 图生文
- 文生视频
- 图文对话
因此,多模态模型最终试图实现的是:
文本
图片
音频
视频
↓
统一表示
↓
统一理解
↓
统一推理
一句话总结:
单模态模型解决的是"如何理解一种信息",而多模态模型解决的是"如何统一理解世界"。
Embedding:从离散数据到向量表示
什么是Embedding?
Embedding是一种将文本、图像和音频等对象表示为连续向量空间中的点的方法,这些点在空间中的位置具有语义意义。
Embedding的工作原理
Embedding 的工作原理,本质上是:
把离散对象(文字、图片、音频等)映射成连续的数字向量,并让相似对象在向量空间中靠近。
可以从「映射 → 学习 → 应用」三个层面理解。
为什么要使用Embedding?
计算机本质上只能处理数字。
例如:
猫
狗
汽车
如果直接编码:
猫 = 1
狗 = 2
汽车 = 3
那么计算机会认为:
scss
狗(2)
更接近
汽车(3)
而不是
猫(1)
因为:
|2-3| = 1
|1-2| = 1
数字本身没有语义。
这种表示方式无法表达:
猫 ≈ 狗
猫 ≠ 汽车
所以需要 Embedding。
Embedding 的核心思想
把对象映射到高维空间中的一个点。
例如:
scss
猫
↓
(1.2, 3.5)
狗
↓
(1.4, 3.7)
汽车
↓
(8.8, 1.1)
在空间中:
狗 ●
猫 ●
汽车 ●
距离代表语义相似度:
- 猫 ↔ 狗:近
- 猫 ↔ 汽车:远
这就是 Embedding 的目标。
Embedding 是如何学习出来的?
开始训练时:
猫
↓
随机向量
狗
↓
随机向量
例如:
css
猫
[0.13, 0.82]
狗
[-0.67, 0.24]
完全没有规律。
训练过程中模型不断看到:
猫喜欢吃鱼
狗喜欢吃骨头
猫和狗都是宠物
模型发现:
猫
狗
经常出现在相似上下文。
于是通过反向传播不断调整参数。
最终:
csharp
猫
[0.12, 0.45]
狗
[0.15, 0.48]
变得靠近。
如何判断两个 Embedding 是否相似?
最常见的是余弦相似度。
CosSim(a,b)=∥a∥∥b∥a⋅b
结果范围:
diff
1 完全相同方向
0 无关
-1 完全相反
例如:
猫
与
狗
可能:
0.92
而:
猫
与
汽车
可能:
0.15
因此系统知道:
猫 ≈ 狗
哪些对象可以Embedding?
Embedding 的核心思想是:
只要一个对象包含信息,并且这种信息可以被模型感知和学习,就可以转换成向量(Embedding)。
理论上没有严格限制。
常见类型如下:
| 对象类型 | 示例 |
|---|---|
| 文本(Text) | 单词、句子、段落、文档 |
| 图片(Image) | 照片、截图、医学影像 |
| 音频(Audio) | 语音、音乐、环境声音 |
| 视频(Video) | 短视频、监控录像 |
| 代码(Code) | Python、Java、SQL |
| 用户(User) | 用户画像、行为记录 |
| 商品(Item) | 商品信息、商品属性 |
| 网页(Web Page) | 网站内容 |
| 图节点(Graph Node) | 社交网络用户、知识图谱实体 |
| 时间序列(Time Series) | 股票价格、传感器数据 |
| 生物数据(Bio Data) | DNA、蛋白质序列 |
例如:
csharp
"猫"
↓
Text Embedding
↓
[0.12, -0.45, 0.88, ...]
猫的照片
↓
Image Embedding
↓
[0.31, -0.22, 0.75, ...]
用户A
↓
User Embedding
↓
[0.89, 0.11, -0.42, ...]
编码器(Encoder):如何提取特征
不同模态的数据结构完全不同。
例如:
文本:
我喜欢人工智能
图片:
224×224×3 像素矩阵
音频:
时间变化的波形信号
神经网络无法直接理解这些原始数据。
因此需要:
Raw Data
↓
Encoder
↓
Feature Representation
↓
Embedding
编码器(Encoder)的任务就是:
从原始数据中提取有意义的特征,并转换成向量表示。
什么是 Encoder
Encoder 可以理解成:
把复杂原始输入压缩成机器可处理表示的函数。
输入:
原始数据
输出:
Feature Vector
例如:
csharp
猫的照片
↓
Encoder
↓
[0.32,-0.11,0.67,...]
或者:
arduino
"一只猫"
↓
Encoder
↓
[-0.22,0.81,...]
编码器本质上学习:
哪些信息重要
哪些信息可以忽略
可以抽象表示:
scss
Encoder(x)
↓
Embedding
其中:
x
=
文本 / 图片 / 音频 / 视频
文本编码器
以句子:
我喜欢人工智能
为例。
第一步:分词(Tokenization)
css
["我", "喜欢", "人工", "智能"]
转换成 Token ID:
yaml
[101, 2058, 8821, 776]
第二步:查 Embedding 矩阵
模型内部有一个巨大的参数矩阵:
yaml
词表大小 × 向量维度
50000 × 1536
例如:
csharp
101
↓
[0.12, -0.45, ...]
2058
↓
[0.88, 0.21, ...]
每个 Token 都会得到一个初始向量。
第三步:加入位置信息
因为:
我喜欢AI
和
AI喜欢我
词相同,但顺序不同。
因此模型会加入 Position Embedding:
diff
Token向量
+
位置向量
第四步:Transformer 编码
Transformer 通过 Self-Attention 学习上下文关系。
例如:
苹果很好吃
和:
苹果发布新手机
"苹果"这个词会根据上下文产生不同的语义表示。
经过多层 Transformer 后:
Token表示
↓
上下文化表示
第五步:生成句向量
把多个 Token 的结果聚合:
v1
v2
v3
v4
↓
Sentence Embedding
例如:
csharp
[0.23, -0.56, 0.12, ...]
这就是文本 Embedding。
图片编码器
输入图片:
224 × 224 × 3
本质上:
像素矩阵
例如:
css
[[255,128,64], ...]
神经网络并不能直接理解:
红色
边缘
猫
汽车
这些概念。
因此需要图像编码器提取视觉特征。
整体流程:
Image
↓
Feature Extraction
↓
Image Encoder
↓
Image Embedding
第一步:切分图像(Patch)
对于视觉 Transformer(ViT):
图片
↓
切成多个Patch
例如:
224×224
↓
16×16 Patch
变成:
erlang
Patch1
Patch2
Patch3
...
每个 Patch 类似:
视觉 Token
第二步:Patch Embedding
每个 Patch 被转换成向量:
Patch
↓
Linear Projection
↓
Patch Vector
例如:
csharp
Patch1
↓
[0.22,-0.14,...]
最终:
python
Patch1
Patch2
Patch3
↓
Vector Sequence
第三步:视觉特征提取
模型逐层学习视觉信息。
低层:
边缘
颜色
纹理
中层:
耳朵
轮廓
形状
高层:
猫
汽车
人物
过程可以理解成:
sql
Pixels
↓
Local Features
↓
Objects
↓
Semantics
第四步:视觉编码器
编码器进一步建模:
Patch之间关系
空间结构
全局信息
输出:
Image Embedding
例如:
csharp
[0.88,-0.14,0.73,...]
常见视觉编码器:
- CNN
- Vision Transformer(ViT)
- CLIP Vision Encoder
音频编码器
输入:
你好
实际上:
时间变化的波形
例如:
css
Amplitude
vs
Time
直接输入波形通常学习困难。
因此:
arduino
Waveform
↓
Feature Extraction
↓
Audio Encoder
↓
Audio Embedding
第一步:转换频谱
常见做法:
Waveform
↓
Mel Spectrogram
把声音转换成类似图片的形式。
原因:
频率变化
比
原始波形
更容易学习
例如:
声音:
你好
转换:
频率
×
时间
得到:
Spectrogram
第二步:提取音频特征
模型学习:
音高
频率
节奏
语速
进一步:
发音
单词
说话人特征
第三步:音频编码器
编码器学习:
时间关系
频率模式
上下文依赖
输出:
arduino
Audio Embedding
例如:
csharp
[0.67,-0.22,0.45,...]
常见音频编码器:
- Whisper Encoder
- wav2vec
- HuBERT
视频编码器
视频包含:
diff
图像
+
时间
+
声音
因此复杂度更高。
整体流程:
css
Video
↓
Frame Extraction
↓
Visual Encoding
↓
Temporal Modeling
↓
Video Embedding
第一步:抽取视频帧
例如:
30 FPS
视频:
Frame1
Frame2
Frame3
每帧:
图片
第二步:提取视觉特征
每帧:
Frame
↓
Image Encoder
↓
Frame Embedding
得到:
erlang
v1
v2
v3
...
第三步:建模时间关系
关键问题:
Frame顺序重要
例如:
人拿杯子
↓
喝水
与:
喝水
↓
放杯子
不是同一个事件。
因此需要:
Temporal Modeling
学习:
动作顺序
运动轨迹
事件变化
第四步:生成视频向量
最终:
css
Frame Embeddings
↓
Temporal Encoder
↓
Video Embedding
输出:
csharp
[0.31,0.55,-0.11,...]
常见视频编码器:
- Video Transformer
- TimeSformer
- VideoMAE
- 3D CNN
为什么不同模态需要不同编码器
核心原因:
不同模态的数据结构完全不同。
文本:
python
Token Sequence
特点:
离散
顺序重要
图片:
Pixel Matrix
特点:
空间结构
局部相关
音频:
Waveform
特点:
连续信号
时间变化
视频:
python
Frame Sequence
特点:
diff
空间
+
时间
因此:
sql
One Encoder
×
All Modalities
通常效果较差。
模型更倾向:
css
Text Encoder
Image Encoder
Audio Encoder
Video Encoder
分别学习:
最适合该模态的特征
最终:
css
Text Encoder
↓
Text Embedding
Image Encoder
↓
Image Embedding
Audio Encoder
↓
Audio Embedding
Video Encoder
↓
Video Embedding
然后:
Alignment
↓
Unified Semantic Space
一句话总结:
编码器的作用是把不同模态的原始数据转换成具有语义信息的特征表示,而由于不同模态的数据结构差异巨大,因此需要针对不同模态设计不同的编码器。
自注意力机制(Self-Attention)
前面提到:
文本
↓
Token
↓
Embedding
但仅仅得到 Embedding 还不够。
例如:
苹果很好吃
与:
苹果发布新手机
虽然:
苹果
是同一个词。
但语义不同。
问题在于:
Embedding
↓
只有词本身
×
没有上下文
因此模型需要:
让每个 Token 能够根据其它 Token 动态调整自己的表示。
这就是:
rust
Self Attention
什么是 Self-Attention
Self-Attention 可以理解成:
序列中的每个元素,都去关注序列中的其它元素,并决定应该关注多少。
例如:
句子:
我喜欢人工智能
模型不会独立处理:
我
喜欢
人工
智能
而是:
我
↓
看其它词
喜欢
↓
看其它词
人工
↓
看其它词
最终:
每个Token
↓
融合上下文
可以抽象成:
css
Input Tokens
↓
互相查看彼此
↓
重新计算表示
↓
Output Tokens
Self-Attention 的核心思想:
重要信息
权重大
无关信息
权重小
Query、Key、Value(QKV)
Self-Attention 的核心机制来自三个向量:
vbnet
Query
Key
Value
简称:
QKV
对于每个 Token:
模型都会生成:
css
Token
↓
Q
K
V
可以理解成:
Query(查询)
表示:
我想找什么信息
Key(键)
表示:
我能提供什么信息
Value(值)
表示:
真正传递的信息
例如:
句子:
小猫喜欢吃鱼
当:
喜欢
计算 Attention:
Query:
我需要寻找相关词
比较:
scss
喜欢(Q)
vs
小猫(K)
vs
吃鱼(K)
发现:
小猫
吃鱼
更加相关。
因此:
喜欢
↓
更多关注
小猫
吃鱼
Self Attention 的计算过程:
css
Q
×
K
↓
Similarity Score
↓
Softmax
↓
Attention Weight
↓
Weight × V
↓
Output
核心思想:
相关性高
↓
权重大
Self-Attention 如何理解上下文
Self-Attention 最大价值:
让同一个词在不同上下文中产生不同表示。
例如:
句子1:
苹果很好吃
句子2:
苹果发布新手机
对于:
苹果
模型看到:
句子1:
苹果
↓
关注
很好吃
于是:
水果语义 ↑
句子2:
苹果
↓
关注
发布
手机
于是:
公司语义 ↑
因此:
Same Token
↓
Different Context
↓
Different Representation
这使模型能够:
理解歧义
理解关系
理解组合语义
Contextual Embedding(上下文化表示)
传统 Embedding:
苹果
↓
固定向量
即:
苹果
=
同一个表示
Self Attention 后:
arduino
苹果很好吃
↓
[fruit vector]
苹果发布手机
↓
[company vector]
得到:
Contextual Embedding
即:
Embedding 不再固定,而是依赖上下文动态生成。
可以理解成:
rust
Static Embedding
↓
Self Attention
↓
Contextual Embedding
这是现代 Transformer 最大变化之一。
因为:
diff
Meaning
=
Word
+
Context
Self-Attention 与 Embedding 的关系
两者容易混淆。
实际上:
Embedding:
负责:
离散输入
↓
向量表示
Self Attention:
负责:
向量表示
↓
理解关系
↓
更新表示
流程:
rust
Text
↓
Tokenization
↓
Embedding
↓
Self Attention
↓
Contextual Embedding
举例:
输入:
猫喜欢鱼
Embedding 后:
猫
↓
v1
喜欢
↓
v2
鱼
↓
v3
Self Attention:
猫
←→
喜欢
←→
鱼
更新:
vbnet
v1'
v2'
v3'
这些新的表示:
包含上下文信息
因此:
rust
Embedding
=
初始表示
Self Attention
=
上下文建模
一句话总结:
Embedding 负责把数据变成向量,而 Self-Attention 负责让这些向量互相交流,从而生成具有上下文语义的表示。
这一章建议紧接在 Self-Attention 后面。
因为逻辑上:
rust
Self Attention
↓
同一模态内部交互
↓
Cross Attention
↓
不同模态之间交互
读者刚理解:
词如何关注词
继续理解:
图如何关注词
声音如何关注文字
会更自然。
可以这样写。
跨注意力机制(Cross-Attention)
前面介绍的 Self-Attention 解决的是:
同一组输入之间如何互相交流。
例如:
文本 Token
↓
关注
其它文本 Token
但多模态场景下:
图片
文字
音频
属于:
不同模态
问题变成:
一种模态如何利用另一种模态的信息?
这就是:
sql
Cross Attention
什么是 Cross-Attention
Cross-Attention 可以理解成:
让一种输入主动去关注另一种输入。
例如:
文本:
一只橘猫坐在沙发上
图片生成时:
模型需要知道:
当前正在生成什么区域
↓
应该关注哪个词
因此:
scss
Image Tokens
↓
关注
Text Tokens
这就是:
sql
Cross Attention
抽象表示:
css
Input A
↓
Query
Input B
↓
Key
Value
Attention
↓
Output
核心思想:
css
A 去关注 B
而不是:
css
A 关注 A
Self-Attention 与 Cross-Attention 的区别
Self-Attention:
css
Q
K
V
来自同一输入
例如:
css
Text Tokens
↓
Q K V
Cross-Attention:
css
Q
来自输入A
K V
来自输入B
例如:
vbnet
Image Tokens
↓
Query
Text Tokens
↓
Key Value
区别:
rust
Self Attention
Token ↔ Token
Cross Attention
Modality ↔ Modality
简单理解:
Self-Attention:
自己看自己
Cross-Attention:
看别人
Cross-Attention 如何实现多模态交互
多模态模型通常存在:
scss
Text Encoder
Image Encoder
得到:
scss
Text Embedding
Image Embedding
但:
得到向量
×
等于理解关系
仍需要交互。
Cross Attention 提供:
vbnet
Image Tokens
↓
Query
Text Tokens
↓
Key Value
计算:
Image Token
应该关注哪些文字
例如:
文字:
红色汽车停在路边
生成图像时:
某个区域:
车轮区域
可能关注:
汽车
而:
背景区域:
路面区域
可能关注:
路边
因此:
不同视觉区域
↓
关注不同文字
可以表示:
scss
Text Tokens
↓
Cross Attention
↑
Image Tokens
最终:
融合语义
Cross Attention 常见用途:
- 图文理解
- 图像问答
- 文生图
- 视频理解
- 多模态 Agent
为什么文生图离不开 Cross-Attention
现代文生图流程:
scss
Prompt
↓
Text Encoder
↓
Text Embedding
↓
Diffusion Model
↓
Image
问题:
Diffusion
如何知道
应该生成什么?
答案:
sql
Cross Attention
假设输入:
"一只橘猫坐在沙发上"
生成过程:
开始:
Random Noise
逐步生成:
轮廓
↓
物体
↓
细节
每一步:
模型不断询问:
当前区域
应该关注哪个词?
生成猫耳朵:
Attention
↓
橘猫
生成背景:
Attention
↓
沙发
生成颜色:
Attention
↓
橘
因此:
sql
Noise
↓
Cross Attention
↓
Guided Generation
↓
Image
没有 Cross Attention:
文本
×
无法有效控制图像
因此现代扩散模型通常:
diff
UNet
+
Cross Attention
+
Text Embedding
共同完成生成。
一句话总结:
Self-Attention 负责同一模态内部的信息交互,而 Cross-Attention 负责不同模态之间的信息交互,是现代多模态模型和文生图系统实现语义融合的核心机制。
多模态向量对齐(Multimodal Alignment)
多模态向量对齐(Multimodal Alignment)是多模态 AI 系统中的核心问题之一。
简单说:
让不同模态(文本、图片、音频、视频等)产生的向量能够落到同一个具有一致语义的空间中。
这样模型才能理解:
文字"猫"
≈
猫的照片
≈
猫叫声
表达的是同一个概念。
什么是多模态对齐?
多模态对齐(Alignment)的目标:
arduino
Text Encoder
↓
Text Vector
Image Encoder
↓
Image Vector
Audio Encoder
↓
Audio Vector
经过训练后:
文本猫
●
图片猫 ●
声音猫 ●
最终:
Same Semantic Region
即:
相同语义 → 向量靠近 不同语义 → 向量远离
没有对齐时:
scss
Text Space
猫 ●
Image Space
猫 ●
两个空间独立。
无法比较。
对齐后:
scss
Unified Space
猫(text)
猫(image)
猫(audio)
模型才能跨模态工作。
为什么需要对齐?
不同模态的数据在物理属性上完全异构:图像是像素矩阵,文本是离散的词序列,音频是声波波形。这些原始数据无法直接比较。多模态对齐充当了"翻译官"的角色,将所有不同格式的数据转换成统一的、可比较的向量形式。
对齐的价值体现在:
- 实现跨模态检索:用文本搜图片、用图片搜音频
- 支持多模态生成:根据文字描述生成图像或视频
- 增强模型理解能力:让模型能够整合多种感官信息进行推理
对齐的层次与方式
Representation Alignment(表示层对齐)
目标:
scss
Image Vector
≈
Text Vector
让不同编码器输出进入同一空间。
这是最基础层。
Feature Alignment(特征层对齐)
不仅对齐最终向量。
还对齐内部特征。
例如:
猫耳朵
猫眼睛
猫尾巴
视觉特征:
↓
文字描述
对齐。
Token-Level Alignment(Token级)
视觉:
Patch1
Patch2
Patch3
文本:
红色
汽车
建立局部对应:
红色
↓
图像红区域
常见于:
- VLM
- OCR
- Grounding
Semantic Alignment(语义层)
目标:
图片猫
文字猫
声音猫
↓
Cat Concept
这是最终目标。
核心挑战与难点
不同模态的信息结构完全不同
文本:
猫
本质是离散符号。
图片:
224×224×3
是像素矩阵。
音频:
16kHz波形
是时间序列信号。
它们的数据分布差异极大。
可以理解为:
中文
英语
音乐
三种完全不同的语言。
模型需要找到共同语义。
同一个概念表达方式很多
例如:
文本:
一只橘猫坐在沙发上
图片可能是:
- 正面
- 侧面
- 光线昏暗
- 部分遮挡
但都对应同一个语义。
模型需要学习:
不同视觉表现
=
同一个概念
这本身就很难。
语义鸿沟(Semantic Gap)
同样的概念在不同模态中表现形式差异巨大。"车"在图像中是形状、颜色、纹理;在文本中是符号序列;在音频中是引擎轰鸣。
例如:
图片里有:
足球
草坪
球门
观众
人类会理解:
足球比赛
但图片中并没有直接出现:
"足球比赛"
这个词。
模型需要跨越从视觉特征到抽象概念的鸿沟。
模态异质性与信息不对称
一张图包含的信息远多于一句描述。如何将图像的丰富细节压缩成文本向量能表达的形式?对于文本中没有出现的元素(如图中的"草"),其向量应该与什么对齐?
例如:
一张图片:
小女孩在雨天拿着红伞
包含:
- 性别
- 年龄
- 天气
- 动作
- 颜色
而文字:
一个人
只提供极少信息。
这会导致:
Image Embedding
包含的信息远多于:
scss
Text Embedding
如何对齐并不简单。
虚假关联(Spurious Correlation)
模型可能学到统计上的"捷径"而非真正的语义。例如,所有"雪"的图片都带有"冷"的标签,模型可能直接对齐"白色像素"和"冷"字,而非真正理解"雪"的概念。
组合语义理解的盲区
传统CLIP类模型缺乏对词序、空间关系、物体-属性关联等"组合语义"的理解。对比预训练容易使编码器学习"捷径",丢弃组合语义相关的特征。
对齐的代价与效率
高质量对齐需要海量配对数据(CLIP用了4亿个图文对),计算成本极高。
对齐是否总是有益的?
最新研究表明,对齐并非总是带来性能提升。在模态间独有信息占主导的任务中,过度对齐可能反而损害性能。
如何判断是否对齐了?
向量距离
相同语义:
arduino
猫(text)
猫(image)
应该:
Cos Similarity ↑
常用:
CosSim(a,b)=∥a∥∥b∥a⋅b
Retrieval Accuracy(检索任务评估)
例如:
输入:
dog
是否找到:
狗图片
指标:
css
Recall@K
Top-K Accuracy
Zero-shot 能力(零样本泛化能力)
是否能够:
没见过的数据
↓
正确匹配
例如:
"紫色机器人"
找到对应图片。
聚类效果
理想情况:
猫文字
猫图片
猫声音
聚成一团。
而:
汽车
远离。
多模态对齐是如何训练的
前面提到:
多模态对齐希望实现:
猫(文本)
≈
猫(图片)
≈
猫叫声
但问题是:
模型一开始
根本不知道
谁应该靠近
训练初期:
scss
Text Vector
Image Vector
通常:
随机分布
因此需要:
通过训练不断调整参数,让相同语义靠近、不同语义远离。
这是多模态训练最核心的问题。
对比学习(Contrastive Learning)
对比学习(Contrastive Learning)的核心思想:
学习"谁应该相似,谁应该不同"。
简单来说:
Positive Pair
距离 ↓
Negative Pair
距离 ↑
例如:
图片:
🐱
文字:
arduino
"a cat"
属于:
Positive Pair
而:
arduino
猫图片
+
"car"
属于:
Negative Pair
训练目标:
Positive Similarity ↑
Negative Similarity ↓
经过大量训练:
scss
Cat Image
↓
靠近
Cat Text
最终:
Unified Space
形成。
Contrastive Loss 的核心思想
Contrastive Learning 需要一个目标函数:
什么算近?
什么算远?
因此引入:
Contrastive Loss
核心思想:
Positive Pair
distance ↓
Negative Pair
distance ↑
可以理解成:
训练时不断推动:
Pull Positive
Push Negative
抽象表示:
vbnet
Anchor
↓
Compare
↓
Positive
Negative
目标:
scss
Sim(anchor,positive)
↑
Sim(anchor,negative)
↓
本质:
优化向量空间结构
InfoNCE Loss
现代多模态模型最常见:
InfoNCE
核心思想:
让正确匹配在所有候选中概率最大。
假设:
Batch:
Image1
Image2
Image3
Text1
Text2
Text3
其中:
Image1
↔
Text1
是真实匹配。
模型计算:
Image1
vs
Text1
Text2
Text3
希望:
scss
Similarity(Image1,Text1)
最大
训练目标:
Positive Score ↑
Negative Score ↓
核心思想:
Softmax
↓
maximize positive probability
简单理解:
正确答案概率
↑
错误答案概率
↓
InfoNCE 优点:
- 训练稳定
- 易扩展大规模数据
- 非常适合检索任务
因此:
css
CLIP
大量使用 InfoNCE
Cosine Loss
另一种更简单的方法:
Cosine Loss
核心思想:
直接优化:
Cos Similarity
公式:
Loss=1−CosSim(a,b)
余弦相似度:
CosSim(a,b)=∥a∥∥b∥a⋅b
表示:
方向越接近
Similarity 越高
训练目标:
Positive Pair
CosSim ↑
优点:
- 更简单
- 更低计算成本
- 对 Batch Size 要求低
缺点:
负样本利用较弱
因此:
LIFT
采用 Cosine Loss
降低训练复杂度。
正样本与负样本构造
训练效果很大程度取决于:
数据如何构造
正样本(Positive Pair)
表示:
应该相似
例如:
arduino
猫图片
+
"cat"
或者:
diff
视频
+
对应字幕
负样本(Negative Pair)
表示:
应该不同
例如:
arduino
猫图片
+
"airplane"
训练:
Positive
Pull Together
Negative
Push Apart
困难在于:
容易负样本(Easy Negative)
猫
vs
飞机
太容易。
价值有限。
困难负样本(Hard Negative)
橘猫
vs
虎斑猫
更难区分。
训练价值更高。
现代训练通常:
diff
Large Batch
+
Hard Negative Mining
提高效果。
最终训练流程:
scss
Image Encoder
↓
Image Embedding
Text Encoder
↓
Text Embedding
Positive / Negative Pair
↓
Contrastive Loss
↓
Backpropagation
↓
Better Alignment
一句话总结:
多模态对齐训练的核心思想是利用对比学习不断拉近正样本、拉远负样本,从而逐渐构建统一语义空间。
这一节建议不要只写"方案列表",而应该回答:
这些方案到底解决了什么问题?为什么要从一种方案发展到下一种方案?
这样读者才能看到技术演进路线。
建议改成下面这种结构。
现有方案
多模态对齐的发展,本质上是在不断解决一个问题:
如何让不同模态
既能共享语义
又能保留自身特征
技术路线大致经历:
sql
Contrastive Alignment
↓
Better Semantic Alignment
↓
Modality-specific Alignment
↓
Hierarchical Alignment
↓
Behavior Alignment
下面介绍典型方案。
CLIP及其变体
代表思想:
通过大规模对比学习,把图像和文本映射到统一向量空间。
核心结构:
scss
Image
↓
Image Encoder
↓
Image Embedding
Text
↓
Text Encoder
↓
Text Embedding
训练目标:
Positive Pair
Similarity ↑
Negative Pair
Similarity ↓
训练流程:
css
Image
↓
Encoder
↓
Vector A
Text
↓
Encoder
↓
Vector B
InfoNCE
↓
Backpropagation
例如:
输入:
arduino
猫图片
+
"a cat"
训练后:
scss
Cat Image Vector
≈
Cat Text Vector
CLIP 最大贡献:
统一语义空间
实现:
scss
Text Search Image
Image Search Text
成为可能。
Zero-shot 能力
例如:
训练没见过:
紫色机器人
仍可能:
正确检索
大规模可扩展
CLIP 使用:
海量图文对
训练。
能够:
Scaling
但 CLIP 存在问题:
组合语义较弱
例如:
红球在蓝盒左边
与:
蓝盒在红球左边
容易混淆。
因为:
更关注全局匹配
弱化关系建模
因此研究开始探索:
更强文本编码器
固定文本编码器:LIFT
核心思想:
既然 LLM 已经具备强语言理解能力,那么不要重新学习文本空间。
因此:
scss
LLM Text Encoder
(Frozen)
只训练:
Image Encoder
结构:
scss
Text Encoder (Frozen)
↓
Shared Space
↑
Trainable Image Encoder
传统方法:
scss
Train Text Encoder
Train Image Encoder
LIFT:
scss
Freeze Text
Train Vision
核心发现:
更强文本编码器带来更强组合语义
例如:
红色杯子
在蓝盒左边
LLM:
关系理解更强
复杂嵌入提取不是关键
发现:
markdown
Text Representation Quality
>
Extraction Complexity
Loss 可以简化
传统:
InfoNCE
LIFT:
Cosine Loss
仍能获得较强效果。
意义:
css
从
Train Everything
↓
Use Strong Foundation Model
不同模态采用不同策略:Stream-Omni
核心思想:
不同模态差异太大,不应该强制统一对齐方式。
传统思路:
scss
Image
Text
Speech
↓
Same Alignment
问题:
模态结构差异巨大
视觉对齐策略
视觉:
diff
Image Tokens
+
Text Tokens
↓
Sequence Concatenation
即:
vbnet
[IMG IMG IMG TEXT TEXT]
送入模型。
原因:
视觉
与文本
Token长度接近
可以直接融合。
语音对齐策略
语音:
scss
Speech Frames
>>
Text Tokens
问题:
序列太长
因此:
使用:
objectivec
CTC Mapping
实现:
Compress
↓
Align
意义:
Different Modalities
↓
Different Alignment
层次化跨模态对齐
核心思想:
语义对齐不是一步完成,而是逐层建立对应关系。
传统:
直接对齐最终向量
问题:
缺少细粒度对应
低层对齐
关注:
css
Pixel
Geometry
Position
例如:
文字:
红色区域
↓
图片:
对应红区域
中层对齐
关注:
css
Object
Phrase
例如:
arduino
"a red car"
↓
车区域
高层对齐
关注:
Concept
Semantics
例如:
比赛
运动
危险
等抽象概念。
整体:
vbnet
Low-level
↓
Mid-level
↓
High-level
逐层对齐。
优势:
更细粒度理解
实现:
Region
↔
Phrase
更强推理能力
因为:
不仅学习
最终向量
还学习
内部结构
演进趋势
整体来看:
css
CLIP
↓
LIFT
↓
Modality-specific Alignment
↓
Hierarchical Alignment
↓
Behavior Alignment
研究重点逐渐变化:
早期:
让向量靠近
现在:
让模型真正理解
一句话总结:
多模态对齐已经从早期"统一向量空间"的问题,逐渐演化为"如何建立跨模态语义理解与推理能力"的问题。
这一章实际上是在回答:
前面花了这么大篇幅讲 Embedding、Encoder、Attention、Alignment,最终有什么用?
最自然的落点就是:
文生图(Text-to-Image)
因为文生图几乎把前面所有概念都串起来了。
可以这样写。
多模态对齐如何支撑生成模型
前面介绍了:
rust
Embedding
↓
Encoder
↓
Self-Attention
↓
Cross-Attention
↓
Multimodal Alignment
这些技术最终服务于一个目标:
让模型能够理解人类输入,并生成符合语义的内容。
最典型的应用就是:
vbnet
Text-to-Image
即:
输入一句话
↓
生成一张图片
例如:
一只橘猫坐在沙发上
模型最终生成:
猫
沙发
橘色毛发
对应的图像。
从文本到图像:文生图流程
以提示词:
一只橘猫坐在沙发上
为例。
整体流程:
scss
Prompt
↓
Text Encoder
↓
Text Embedding
↓
Cross Attention
↓
Diffusion Model
↓
Image
第一步:
文本编码。
scss
Prompt
↓
Tokenizer
↓
Text Encoder
↓
Text Embedding
得到:
猫
橘色
沙发
对应的语义表示。
第二步:
语义对齐。
由于训练阶段已经完成:
scss
Text
↔
Image
对齐。
因此:
scss
猫(Text)
≈
猫(Image)
第三步:
生成模型开始工作。
从随机噪声:
Noise
逐步生成图像:
css
Noise
↓
Outline
↓
Object
↓
Detail
↓
Image
最终:
符合文本描述的图像
被生成出来。
扩散模型(Diffusion Model)
目前主流文生图模型:
- Stable Diffusion
- SDXL
- Flux
- Imagen
- DALL·E
大多属于:
Diffusion Model
即:
扩散模型
核心思想非常简单:
先学会把图片毁掉,再学会把图片恢复。
训练阶段:
不断向图片加入噪声。
Cat Image
↓
Noise
↓
More Noise
↓
Pure Noise
最终:
随机噪声
然后模型学习:
Noise
↓
Remove Noise
↓
Original Image
推理阶段则反过来:
Random Noise
↓
Denoise
↓
Denoise
↓
Denoise
↓
Image
因此:
扩散模型本质是在学习:
如何一步步去噪
而不是:
一次性生成图片
Cross-Attention 如何控制生成
这里出现一个关键问题:
扩散模型
如何知道
应该生成什么?
答案:
sql
Cross-Attention
假设输入:
一只橘猫坐在沙发上
编码后得到:
猫
橘色
坐
沙发
对应的文本向量。
扩散过程中:
模型会不断产生:
Image Tokens
此时:
vbnet
Image Token
↓
Query
Text Token
↓
Key
Value
形成:
sql
Cross Attention
例如:
生成猫耳朵区域:
Attention
↓
猫
生成颜色区域:
Attention
↓
橘色
生成背景:
Attention
↓
沙发
因此:
不同区域会自动关注不同词语。
Cat Region
↓
Cat Token
Sofa Region
↓
Sofa Token
最终实现:
文字
控制
图像生成
现代文生图模型几乎都依赖:
sql
Cross Attention
作为文本控制机制。
为什么需要潜空间(Latent Space)
如果直接在原始图片上生成:
例如:
yaml
1024 × 1024 × 3
图片。
数据量约:
300万像素
计算成本极高。
因此现代扩散模型通常不会直接生成图片。
而是:
Image
↓
VAE Encoder
↓
Latent
压缩到潜空间。
例如:
yaml
1024×1024×3
↓
128×128×4
得到:
Latent Representation
即:
潜变量表示
然后扩散过程发生在:
Latent Space
中。
Noise
↓
Latent Diffusion
↓
Latent Image
最后再恢复:
Latent
↓
VAE Decoder
↓
Image
这样带来几个好处:
降低计算成本
百万级像素
↓
数万级特征
加快训练速度
GPU需求下降
保留主要语义
潜空间会保留:
物体
结构
颜色
语义
而忽略:
部分冗余细节
因此像:
Stable Diffusion
本质上就是:
diff
Diffusion
+
Latent Space
的结合。
一句话总结:
多模态对齐让模型建立"文字 ↔ 图像"的语义映射,Cross-Attention让文本能够实时控制生成过程,而扩散模型则在潜空间中逐步去噪,最终生成符合文本描述的图像。
多模态技术的典型应用
经过 Embedding、编码器、注意力机制和多模态对齐后,模型终于具备了跨模态理解和生成能力。
这些能力已经广泛应用于搜索、推荐、内容生成、智能助手等领域。
从本质上看:
sql
Embedding
↓
统一表示
Alignment
↓
统一语义
Cross Attention
↓
跨模态交互
Generation
↓
内容生成
共同构成了现代多模态 AI 系统的基础。
图文检索
图文检索(Image-Text Retrieval)是最早落地的多模态应用之一。
目标:
文本找图片
图片找文本
例如:
用户输入:
一只趴在沙发上的橘猫
系统返回:
对应图片
实现流程:
scss
Text
↓
Text Encoder
↓
Text Embedding
Image
↓
Image Encoder
↓
Image Embedding
对齐后:
arduino
猫(text)
≈
猫(image)
检索时:
计算余弦相似度
↓
返回最相近图片
典型应用:
- 搜索引擎
- 电商搜索
- 素材库检索
- 医学影像检索
多模态 RAG
传统 RAG(Retrieval-Augmented Generation)主要处理:
文本
但现实知识并不只有文本。
还包括:
图片
表格
视频
PDF
音频
多模态 RAG 目标:
多模态知识库
↓
统一向量空间
↓
检索
↓
生成答案
例如:
用户上传:
电路图
并提问:
这个模块的作用是什么?
系统流程:
Image
↓
Vision Encoder
↓
Image Embedding
↓
Vector Database
↓
Retrieve
↓
LLM
最终实现:
看图问答
图文分析
企业知识库
视觉语言模型(VLM)
VLM(Vision Language Model)是当前最主流的多模态模型。
目标:
diff
理解图片
+
理解语言
典型结构:
scss
Image
↓
Vision Encoder
↓
Visual Tokens
Text
↓
Tokenizer
↓
Text Tokens
Cross Attention
↓
LLM
↓
Answer
例如:
用户上传:
一张交通事故照片
并提问:
发生了什么?
模型流程:
图片理解
↓
视觉语义
↓
语言推理
↓
回答
代表模型:
- GPT-4o
- Gemini
- Qwen-VL
- LLaVA
文生图与文生视频
生成式 AI 是多模态技术最具影响力的应用。
文生图:
scss
Prompt
↓
Text Encoder
↓
Cross Attention
↓
Diffusion
↓
Image
例如:
一只宇航员猫
生成:
对应图片
文生视频:
css
Prompt
↓
Text Embedding
↓
Video Diffusion
↓
Video
例如:
宇航员猫在月球散步
生成:
连续视频
关键技术:
diff
Alignment
+
Cross Attention
+
Diffusion
代表模型:
- Sora
- Veo 3
- Runway Gen-3
多模态 Agent
多模态 Agent 是当前最活跃的发展方向之一。
目标:
看
听
说
做
传统 LLM:
输入文字
输出文字
多模态 Agent:
图片
音频
视频
文本
↓
理解
↓
规划
↓
执行
例如:
机器人看到:
桌上的杯子
用户说:
帮我拿过来
系统需要:
视觉识别
↓
目标定位
↓
动作规划
↓
执行
能力来源:
diff
Perception
+
Reasoning
+
Action
未来 Agent 更可能成为:
diff
多模态模型
+
工具调用
+
长期记忆
的结合体。
未来方向与挑战
虽然多模态模型已经取得巨大进展,但距离真正理解现实世界仍有较大差距。
视频与时序模态对齐
当前主流对齐:
图片
↔
文本
未来重点:
视频
音频
传感器数据
挑战:
时间关系
动作变化
因果关系
例如:
拿起杯子
↓
喝水
与:
喝水
↓
放下杯子
语义不同。
模型需要理解:
事件演化
而不仅仅是静态对象。
通用多模态世界模型
未来目标:
不只是理解数据,而是理解世界。
例如:
模型知道:
球会掉落
水会流动
玻璃会碎
不仅因为见过数据。
而是学会:
物理规律
因果关系
这类模型通常被称为:
World Model
代表方向包括:
- 世界模拟
- 环境预测
- 智能体训练
动态对齐与推理时优化
当前对齐:
训练完成
↓
固定
未来:
输入变化
↓
动态调整对齐方式
例如:
视觉任务
优先视觉信息。
语音任务
优先语音信息。
实现:
Adaptive Alignment
提高:
效率
泛化能力
推理质量
从特征对齐走向行为对齐
传统对齐:
scss
Image Vector
≈
Text Vector
未来重点:
Action Alignment
即:
按照人类意图行动
例如:
用户说:
帮我订机票
模型不仅理解:
机票
还需要:
搜索
比较
选择
执行
因此研究重点正在从:
Feature Alignment
转向:
Behavior Alignment
总结
从 Embedding 到 Alignment
整篇文章最核心的主线是:
rust
Raw Data
↓
Encoder
↓
Embedding
↓
Self Attention
↓
Contextual Embedding
↓
Cross Attention
↓
Multimodal Alignment
Embedding 解决:
如何表示
问题。
Alignment 解决:
如何理解
问题。
从 Alignment 到 Generation
统一语义空间建立后:
css
Text
Image
Audio
Video
可以互相映射。
进一步实现:
scss
Text → Image
Text → Video
Image → Text
Speech → Text
等生成任务。
因此:
Alignment
=
Generation 的基础
多模态模型的统一认知框架
如果用一句话概括现代多模态 AI:
不同模态
↓
统一表示
↓
统一语义
↓
统一推理
↓
统一生成
从技术角度看:
rust
Embedding
负责表示
Encoder
负责特征提取
Self-Attention
负责上下文理解
Cross-Attention
负责跨模态交互
Alignment
负责统一语义空间
Diffusion/LLM
负责生成与推理
这也是当前绝大多数多模态模型(VLM、文生图、文生视频、多模态 Agent)的共同底层框架。