m-RoPE是传统RoPE(旋转位置编码)在多模态场景下的扩展。传统RoPE处理的是一维序列,而m-RoPE专门设计用来处理包含图像和视频等视觉内容的多模态输入。
如代码中注释所述:
多模态3D旋转位置编码是1D旋转位置编码的扩展。输入嵌入序列包含视觉(图像/视频)嵌入和文本嵌入,或者仅包含文本嵌入。对于视觉嵌入部分,我们分别在时间、高度和宽度维度上应用旋转位置编码。这里我们将通道维度分为3个块,用于时间、高度和宽度旋转位置编码。对于文本嵌入部分,我们只应用1D旋转位置编码。
标准RoPE通过对每个token的嵌入进行旋转变换,将位置信息植入到token嵌入中。其核心公式:
其中,是查询向量的第i个特征维度,是token的绝对位置,是频率系数,通常。
在代码中,这种旋转通过rotate_half
函数实现:
pythondef rotate_half(x):
"""Rotates half the hidden dims of the input."""
x1 = x[..., : x.shape[-1] // 2]
x2 = x[..., x.shape[-1] // 2 :]
return torch.cat((-x2, x1), dim=-1)
以及旋转变换公式:
pythonq_embed = (q * cos) + (rotate_half(q) * sin) k_embed = (k * cos) + (rotate_half(k) * sin)
对于视觉输入(图像/视频),Qwen2.5-VL使用三维位置ID:
这在Qwen2_5_VLRotaryEmbedding.forward
中有体现:
python# Core RoPE block. In contrast to other models, Qwen2_5_VL has different position ids for thw grids
# So we expand the inv_freq to shape (3, ...)
inv_freq_expanded = self.inv_freq[None, None, :, None].float().expand(3, position_ids.shape[1], -1, 1)
position_ids_expanded = position_ids[:, :, None, :].float() # shape (3, bs, 1, positions)
关键创新是将查询和键向量的特征维度分成三个部分,分别应用时间、高度和宽度的位置编码。这在apply_multimodal_rotary_pos_emb
函数中实现:
pythonmrope_section = mrope_section * 2 # mrope_section是每个维度分配的特征数
cos = torch.cat([m[i % 3] for i, m in enumerate(cos.split(mrope_section, dim=-1))], dim=-1)
sin = torch.cat([m[i % 3] for i, m in enumerate(sin.split(mrope_section, dim=-1))], dim=-1)
这段代码的核心操作是:
mrope_section
大小分块m-RoPE可以表示为:
其中,是标准RoPE的旋转矩阵,、、分别是时间、高度和宽度维度的位置ID。
完整的m-RoPE实现涉及以下几个关键组件:
get_rope_index
方法负责为输入序列生成三维位置ID:
Qwen2_5_VLRotaryEmbedding
类负责生成位置编码的sin和cos成分:
pythonfreqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(2, 3)
emb = torch.cat((freqs, freqs), dim=-1)
cos = emb.cos()
sin = emb.sin()
apply_multimodal_rotary_pos_emb
函数将cos和sin分块,并根据特征维度应用相应的位置编码:
pythonmrope_section = mrope_section * 2
cos = torch.cat([m[i % 3] for i, m in enumerate(cos.split(mrope_section, dim=-1))], dim=-1)
sin = torch.cat([m[i % 3] for i, m in enumerate(sin.split(mrope_section, dim=-1))], dim=-1)
q_embed = (q * cos) + (rotate_half(q) * sin)
k_embed = (k * cos) + (rotate_half(k) * sin)
m-RoPE的设计使得模型能够:
这种设计让Qwen2.5-VL能够更好地理解和处理多模态输入,特别是在处理需要空间和时间理解的视觉内容时,如视频动作识别、空间关系描述等任务。
总结来说,m-RoPE通过将标准RoPE扩展到三维空间(时间、高度、宽度),并通过特征分块技术将这三种位置信息分别编码到不同的特征维度中,从而实现了对多模态内容的更有效建模。
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!