Qwen2.5-VL 视觉编码器的 RMSNorm
Qwen2.5-VL 视觉编码器的RMSNorm
flyfish
视觉编码器在多模态大模型中扮演着至关重要的角色。我们从头开始训练了一个原生动态分辨率的 ViT,包括 CLIP、视觉-语言模型对齐和端到端训练等阶段。为了解决多模态大模型在训练和测试阶段 ViT 负载不均衡的问题,我们引入了窗口注意力机制,有效减少了 ViT 端的计算负担。在我们的 ViT 设置中,只有四层是全注意力层,其余层使用窗口注意力。最大窗口大小为 8x8,小于 8x8 的区域不需要填充,而是保持原始尺度,确保模型保持原生分辨率。此外,为了简化整体网络结构,我们使 ViT 架构与 LLMs 更加一致,采用了 RMSNorm 和 SwiGLU 结构。
这里就是介绍 RMSNorm
RMSNorm其实是LayerNorm的“简化版”,中文叫均方根归一化。它的核心思路就是去掉传统LayerNorm里的“减均值”操作,只保留“除以标准差”的缩放步骤,这样计算起来更省事儿。
每个样本4个特征
数据示例(N=4,D=4,每个样本4个特征):
[[x11, x12, x13, x14], # 样本1[x21, x22, x23, x24], # 样本2[x31, x32, x33, x34], # 样本3[x41, x42, x43, x44] # 样本4
]
每个样本的RMS计算元素集合
样本1:
[x11, x12, x13, x14] → 计算均方根:
1. 平方每个特征:x11², x12², x13², x14²
2. 求平均:(x11² + x12² + x13² + x14²) / 4
3. 开根号得到RMS值:√(平均)
4. 每个特征除以RMS值,再乘可学习参数g
样本2:
[x21, x22, x23, x24] → 同理,独立计算自身的RMS值
样本3-4:
[x31,x32,x33,x34] 和 [x41,x42,x43,x44] 各自独立计算RMS
文本模拟可视化
[[x11, x12, x13, x14], # 样本1 → 框选所有特征计算RMS[x21, x22, x23, x24], # 样本2 → 框选所有特征计算RMS[x31, x32, x33, x34], # 样本3 → 框选所有特征计算RMS[x41, x42, x43, x44] # 样本4 → 框选所有特征计算RMS
]→ 样本1计算范围: [x11, x12, x13, x14](算平方平均开根号)
→ 样本2计算范围: [x21, x22, x23, x24](同上,独立计算)
→ 样本3-4同理,每个样本单独处理所有特征
核心差异(对比LayerNorm)
- LayerNorm:计算均值后减去均值,再除以标准差(含中心化步骤)。
- RMSNorm:无中心化(不减均值),直接算均方根后缩放,计算更简单。
例如样本1的处理:- LayerNorm: ( x 11 − μ , x 12 − μ , x 13 − μ , x 14 − μ ) / σ (x11-μ, x12-μ, x13-μ, x14-μ) / σ (x11−μ,x12−μ,x13−μ,x14−μ)/σ
- RMSNorm: ( x 11 , x 12 , x 13 , x 14 ) / RMS ⋅ g (x11, x12, x13, x14) / \text{RMS} \cdot g (x11,x12,x13,x14)/RMS⋅g( RMS = ( x 11 2 + . . . + x 14 2 ) / 4 \text{RMS}=\sqrt{(x11²+...+x14²)/4} RMS=(x112+...+x142)/4)
2张2×2像素的RGB图像
数据示例(N=2,H=2,W=2,C=3,即2张2×2像素的RGB图像):
样本1(图1):
[[R11 G11 B11] [R12 G12 B12] # 第1行像素(H=1)[R21 G21 B21] [R22 G22 B22] # 第2行像素(H=2)
]样本2(图2):
[[R31 G31 B31] [R32 G32 B32] # 第1行像素(H=1)[R41 G41 B41] [R42 G42 B42] # 第2行像素(H=2)
]
每个样本的RMS计算元素集合
样本1的计算范围:
[[R11,G11,B11], [R12,G12,B12], # 第1行所有通道[R21,G21,B21], [R22,G22,B22] # 第2行所有通道
]
→ 计算均方根:
1. 平方所有元素:R11²,G11²,B11²,R12²,G12²,B12²,R21²,G21²,B21²,R22²,G22²,B22²
2. 求平均:总和 / (H×W×C) = 总和 / (2×2×3) = 总和 / 12
3. 开根号得到RMS值:√(平均)
4. 每个元素除以RMS值,再乘可学习参数g
样本2的计算范围:
[[R31,G31,B31], [R32,G32,B32],[R41,G41,B41], [R42,G42,B42]
] → 同理,独立计算自身的RMS值
文本模拟可视化
[# 样本1(整图计算RMS)[[R11 G11 B11] [R12 G12 B12], [R21 G21 B21] [R22 G22 B22]] → 框选所有像素和通道:[R11,G11,B11,R12,G12,B12,R21,G21,B21,R22,G22,B22],# 样本2(整图计算RMS)[[R31 G31 B31] [R32 G32 B32], [R41 G41 B41] [R42 G42 B42]] → 框选所有像素和通道:[R31,G31,B31,R32,G32,B32,R41,G41,B41,R42,G42,B42]
]
对比LayerNorm
- LayerNorm:计算均值后减去均值,再除以标准差(含中心化步骤)。
- RMSNorm:无中心化(不减均值),直接算均方根后缩放。
例如样本1的处理:- LayerNorm:先计算所有像素的均值μ,每个像素减去μ后再归一化。
- RMSNorm:直接对所有像素的平方值求平均,开根号得到RMS,每个像素除以RMS再缩放。
RMSNorm在二维场景中对每个样本的所有通道和空间维度(H×W×C) 整体计算均方根,跳过均值中心化步骤,计算效率更高。这使得它在视觉Transformer(如ViT)中广泛应用。
LayerNorm是先算一批数据的均值,再用每个数减去均值,最后除以标准差;但RMSNorm直接不算均值,只算每个特征的均方根(也就是先平方每个数,求平均,再开根号),然后用原始数据除以这个均方根,再乘一个可学习的参数g。举个例子,假设数据是[2,4,6],LayerNorm会先算均值4,每个数减4得到[-2,0,2],再算标准差,而RMSNorm直接算平方的平均(4+16+36)/3=18.67,开根号约4.32,然后每个数除以4.32,再乘g。
这种简化有啥好处呢?首先是计算更快,少了减均值的步骤,尤其在GPU上跑的时候,效率提升明显;其次是参数更少,没有LayerNorm里的偏移量β,只需要一个缩放参数g,模型更简洁。在像ViT这样的视觉Transformer里,RMSNorm常和SwiGLU激活函数搭配,让视觉模型的架构更接近语言模型(比如GPT),方便多模态对齐。比如训练QWen2.5 VL的时候,用RMSNorm能让ViT的计算负担更小,配合窗口注意力,减少全注意力层的计算量,同时保持动态分辨率的处理能力。
简单来说,RMSNorm就是“偷懒版”的LayerNorm,不要均值调整,只做尺度缩放,适合追求效率的大模型,尤其是视觉和语言模型结合的场景,既能省算力,又能和LLM的架构保持一致,一举两得。