Qwen2.5-VL - Vision Transformer(ViT)的patch 处理
Qwen2.5-VL - Vision Transformer(ViT)的patch 处理
flyfish
Patch 和卷积(Convolution)的不同处理
flyfish
Patch处理过程:8×8图像分块与线性投影
将输入图像(或特征图)划分为固定大小的不重叠区域,每个区域作为一个整体(token)输入到后续模型。
1. 输入图像(8×8像素矩阵)
假设图像像素值从1到64按行递增排列,矩阵如下:
[[1, 2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15, 16], [17, 18, 19, 20, 21, 22, 23, 24], [25, 26, 27, 28, 29, 30, 31, 32], [33, 34, 35, 36, 37, 38, 39, 40], [41, 42, 43, 44, 45, 46, 47, 48], [49, 50, 51, 52, 53, 54, 55, 56], [57, 58, 59, 60, 61, 62, 63, 64]]
2. 划分为2×2不重叠Patch(共16个Patch)
横向和纵向每2行/列分一块,分块结果如下(用「{}」标记每个Patch):
{ {1,2}, {3,4}, {5,6}, {7,8} },
{ {9,10}, {11,12}, {13,14}, {15,16} },
{ {17,18}, {19,20}, {21,22}, {23,24} },
{ {25,26}, {27,28}, {29,30}, {31,32} },
---------------------------------------
{ {33,34}, {35,36}, {37,38}, {39,40} },
{ {41,42}, {43,44}, {45,46}, {47,48} },
{ {49,50}, {51,52}, {53,54}, {55,56} },
{ {57,58}, {59,60}, {61,62}, {63,64} }
每个Patch展平为一维向量,例如第1个Patch(左上角)展平为 [1, 2, 9, 10]
(注意:实际分块是按行优先,即先取前两行前两列,再展平为向量)。
3. 线性投影:将4维Patch向量转为2维特征
假设投影矩阵为 W = [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6], [0.7, 0.8]]
(4×2矩阵),以第1个Patch [1, 2, 9, 10]
为例:
- 计算:
1×0.1 + 2×0.3 + 9×0.5 + 10×0.7 = 0.1 + 0.6 + 4.5 + 7 = 12.2 1×0.2 + 2×0.4 + 9×0.6 + 10×0.8 = 0.2 + 0.8 + 5.4 + 8 = 14.4
- 输出特征向量:
[12.2, 14.4]
- 所有16个Patch投影后,形成16个2维向量,构成序列
[v1, v2, ..., v16]
,后续可输入Transformer处理。
CNN处理对比:用2×2卷积核处理8×8图像
通过共享权重的卷积核在输入上滑动,逐点计算局部区域与卷积核的内积,提取局部特征。
1. 输入图像(同上,8×8矩阵)
[[1, 2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15, 16], [17, 18, 19, 20, 21, 22, 23, 24], [25, 26, 27, 28, 29, 30, 31, 32], [33, 34, 35, 36, 37, 38, 39, 40], [41, 42, 43, 44, 45, 46, 47, 48], [49, 50, 51, 52, 53, 54, 55, 56], [57, 58, 59, 60, 61, 62, 63, 64]]
2. 卷积核定义(以边缘检测为例,2×2核)
K = [[1, 0], [0, -1]]
偏置 b = 0
,步长 stride = 1
,无填充(padding = 0)。
3. 卷积计算过程(以左上角区域为例)
- 第1次滑动:覆盖输入矩阵前两行前两列:
计算内积:[[1, 2], [9, 10]]
1×1 + 2×0 + 9×0 + 10×(-1) = 1 - 10 = -9
- 第2次滑动(向右1格):
计算内积:[[2, 3], [10, 11]]
2×1 + 3×0 + 10×0 + 11×(-1) = 2 - 11 = -9
- 最终输出特征图(7×7,因输出尺寸 = (8-2)/1 + 1 = 7),部分值如下:
(注:实际边缘检测卷积核会产生更复杂的特征,此处简化为统一值以突出计算逻辑。)[[-9, -9, -9, -9, -9, -9, -9], [-9, ..., ..., ..., ..., ..., -9], [-9, ..., ..., ..., ..., ..., -9], [ ... , ..., ..., ..., ..., ..., ...], [-9, ..., ..., ..., ..., ..., -9], [-9, ..., ..., ..., ..., ..., -9], [-9, -9, -9, -9, -9, -9, -9]]
区别
维度 | Patch处理(Transformer) | 卷积处理(CNN) |
---|---|---|
输入分块 | 8×8图像→16个2×2不重叠Patch,无滑动 | 8×8图像→通过2×2核滑动覆盖,区域重叠 |
计算逻辑 | 每个Patch独立展平+线性投影,无参数共享 | 同一卷积核全局滑动,参数共享 |
输出形态 | 16个2维向量(序列,需位置编码) | 7×7特征图(保留空间结构) |
空间关联 | 初始不考虑Patch间关系,依赖后续注意力建模全局关联 | 通过滑动重叠隐式捕捉局部关联,需多层堆叠扩大感受野 |
计算量 | 16次4×2矩阵乘法(线性投影) | 7×7=49次2×2内积计算(卷积) |
Patch是“先分块再投影”的静态处理,而卷积是“滑动窗口+参数共享”的动态局部计算。
配置项 (Configuration) | Qwen2.5-VL-3B | Qwen2.5-VL-7B | Qwen2.5-VL-72B |
---|---|---|---|
视觉Transformer (ViT) | |||
隐藏层大小 (Hidden Size) | 1280 | 1280 | 1280 |
层数 (# Layers) | 32 | 32 | 32 |
头数 (# Num Heads) | 16 | 16 | 16 |
中间层大小 (Intermediate Size) | 3456 | 3456 | 3456 |
patch尺寸 (Patch Size) | 14 | 14 | 14 |
窗口尺寸 (Window Size) | 112 | 112 | 112 |
全注意力块索引 (Full Attention Block Indexes) | {7, 15, 23, 31} | {7, 15, 23, 31} | {7, 15, 23, 31} |
视觉-语言融合器 (Vision-Language Merger) | |||
输入通道 (In Channel) | 1280 | 1280 | 1280 |
输出通道 (Out Channel) | 2048 | 3584 | 8192 |
大语言模型 (LLM) | |||
隐藏层大小 (Hidden Size) | 2048 | 3584 | 8192 |
层数 (# Layers) | 36 | 28 | 80 |
KV头数 (# KV Heads) | 2 | 4 | 8 |
头大小 (Head Size) | 128 | 128 | 128 |
中间层大小 (Intermediate Size) | 4864 | 18944 | 29568 |
嵌入绑定 (Embedding Tying) | ✔️ | ✖️ | ✖️ |
词汇表大小 (Vocabulary Size) | 151646 | 151646 | 151646 |
训练 token 数 (# Trained Tokens) | 4.1T | 4.1T | 4.1T |
224×224 RGB图像的14×14 Patch分割流程
1. 图像预处理:Resize到28的倍数
- 输入要求:Qwen2.5-VL的视觉编码器要求图像尺寸为28的倍数,224=28×8,天然满足条件。
- RGB通道:图像格式为H×W×C=224×224×3(高×宽×3通道)。
2. 14×14 Patch分割可视化
# 224×224 RGB图像分割为14×14 Patch的网格示意
# 横向16个Patch(224÷14=16),纵向16个Patch,共256个Patch
# 每个Patch包含14×14×3=588个像素值(RGB三通道)+-----------------------------------------------------------------------------+
| patch(0,0) | patch(0,1) | ... | patch(0,15) |
| 14×14×3像素(RGB) | 14×14×3像素(RGB) | | 14×14×3像素(RGB) |
| +-----------+ +-----------+ | +-----------+ +-----------+ | | +-----------+ +-----------+ |
| | | | | | | | | | | | | | | | |
| | 14×14 | | 14×14 | | | 14×14 | | 14×14 | | | | 14×14 | | 14×14 | |
| | 像素 | | 像素 | | | 像素 | | 像素 | | | | 像素 | | 像素 | |
| | (RGB) | | (RGB) | | | (RGB) | | (RGB) | | | | (RGB) | | (RGB) | |
| | | | | | | | | | | | | | | | |
| +-----------+ +-----------+ | +-----------+ +-----------+ | | +-----------+ +-----------+ |
| | | | |
| patch(1,0) | patch(1,1) | ... | patch(1,15) |
| 14×14×3像素(RGB) | 14×14×3像素(RGB) | | 14×14×3像素(RGB) |
| +-----------+ +-----------+ | +-----------+ +-----------+ | | +-----------+ +-----------+ |
| | | | | | | | | | | | | | | | |
| | 14×14 | | 14×14 | | | 14×14 | | 14×14 | | | | 14×14 | | 14×14 | |
| | 像素 | | 像素 | | | 像素 | | 像素 | | | | 像素 | | 像素 | |
| | (RGB) | | (RGB) | | | (RGB) | | (RGB) | | | | (RGB) | | (RGB) | |
| | | | | | | | | | | | | | | | |
| +-----------+ +-----------+ | +-----------+ +-----------+ | | +-----------+ +-----------+ |
| | | | |
| ... | ... | | ... |
| | | | |
+-----------------------------------------------------------------------------+
| patch(15,0) | patch(15,1) | ... | patch(15,15) |
| 14×14×3像素(RGB) | 14×14×3像素(RGB) | | 14×14×3像素(RGB) |
| +-----------+ +-----------+ | +-----------+ +-----------+ | | +-----------+ +-----------+ |
| | | | | | | | | | | | | | | | |
| | 14×14 | | 14×14 | | | 14×14 | | 14×14 | | | | 14×14 | | 14×14 | |
| | 像素 | | 像素 | | | 像素 | | 像素 | | | | 像素 | | 像素 | |
| | (RGB) | | (RGB) | | | (RGB) | | (RGB) | | | | (RGB) | | (RGB) | |
| | | | | | | | | | | | | | | | |
| +-----------+ +-----------+ | +-----------+ +-----------+ | | +-----------+ +-----------+ |
+-----------------------------------------------------------------------------+
3. 数学计算与维度变换
-
分割参数:
图像尺寸:224×224×3 Patch尺寸:14×14×3 横向分割数:224 ÷ 14 = 16 纵向分割数:224 ÷ 14 = 16 总Patch数:16 × 16 = 256个 每个Patch像素数:14×14×3 = 588
-
展平与投影流程:
1. 展平每个Patch:[14×14×3] → [588] 一维向量 2. 线性投影(示例:映射到1280维):输入:256个×588维向量投影矩阵:W ∈ R^(1280×588)输出:256个×1280维视觉Token
-
28倍数的意义:
224 = 28×8 → 确保14×14 Patch的均匀分割(28是14的2倍) 隐含关系:28 = 2×14 → 每个28×28区域包含2×2个14×14 Patch (后续MLP融合时,4个相邻Patch会被分组为28×28区域处理)
4. RGB通道处理细节
- 每个Patch的维度:
Patch(i,j)的像素结构: [[R1 G1 B1, R2 G2 B2, ..., R14 G14 B14], # 第1行14个像素(RGB)[R15 G15 B15, ..., R28 G28 B28], # 第2行...[R197 G197 B197, ..., R204 G204 B204] # 第14行(14×14=196个像素,每个像素3通道) ] 展平后顺序:R1 G1 B1, R2 G2 B2, ..., R196 G196 B196 → 588维向量
5. 与窗口注意力的配合
- 窗口尺寸112×112:
112 = 8×14 → 每个窗口包含8×8=64个14×14 Patch 224×224图像的窗口划分: 横向窗口数:224÷112=2 纵向窗口数:224÷112=2 总窗口数:2×2=4个,每个窗口处理64个Patch
224×224的RGB图像通过14×14的Patch分割,生成256个视觉Token,每个Token包含588维像素信息(展平后)。Resize到28的倍数(224=28×8)确保了Patch的均匀划分,同时为后续MLP融合的4-Patch分组(2×2个Patch,对应28×28区域)提供了基础,最终实现视觉特征与语言模型的高效对齐。
视觉编码器(Vision Encoder)
Qwen2.5-VL的视觉编码器采用了重新设计的视觉Transformer(ViT)架构。在结构上,我们引入2D旋转位置编码(2D-RoPE)和窗口注意力机制,以支持原始输入分辨率并加速整个视觉编码器的计算。在训练和推理过程中,输入图像的高度和宽度会被调整为28的倍数,再输入到ViT中。视觉编码器通过以14为步长分割图像为patch,生成一组图像特征。
基于MLP的视觉-语言融合器(MLP-based Vision-Language Merger)
为解决图像特征长序列带来的效率挑战,我们采用一种简单有效的方法,在将特征序列输入大语言模型(LLM)之前对其进行压缩。具体来说,我们没有直接使用视觉Transformer(ViT)提取的原始patch特征,而是首先将空间相邻的四个patch特征分为一组。这些分组后的特征经过拼接,再通过一个两层的多层感知机(MLP)投影到与LLM中文本嵌入一致的维度。这种方法不仅降低了计算成本,还提供了一种灵活的方式来动态压缩不同长度的图像特征序列。
-
Patch分割逻辑:
输入图像被resize为28的倍数(如224=28×8),确保14×14的patch能均匀分割(224÷14=16),生成16×16=256个patch。 -
2D-RoPE与窗口注意力:
D-RoPE对应此前分析的二维旋转位置编码,用于捕获图像的空间关系;窗口注意力通过限制计算范围(如112×112像素,即8×8个patch),使计算复杂度与patch数量呈线性关系。 -
特征压缩机制:
将四个相邻patch特征分组(对应2×2个14×14 patch,即28×28像素区域),通过MLP投影到文本维度,“28×28”——即每个分组覆盖2×2个原始patch,与“token对应28×28像素区域”的分析一致,目的是减少输入LLM的token数量(256个patch压缩为64个分组)。