☰
3D正弦位置编码解析:InternVideo2-Stage2_6B如何同时看懂图像与视频的完整指南
2026/10/22 1:43:26 网站建设 项目流程

【免费下载链接】InternVideo2-Stage2_6B

项目地址:https://ai.gitcode.com/OpenGVLab/InternVideo2-Stage2_6B
点击查看免费下载

本文带你快速读懂 InternVideo2-Stage2_6B 的 3D 正弦位置编码(3D Sincos Positional Encoding)。这是一个约 6B 参数的多模态理解模型,能同时处理视频、图像和文本。它只用一套位置编码方案,就让同一个视觉编码器既"看"得懂单张图片,也"看"得懂一段视频的时序变化——这正是本文要拆解的核心设计。

一、为什么视频模型需要"3D 位置"?

在 ViT(Vision Transformer)风格架构中,图像会被切成小块(patch),每个 patch 变成一个 token 送入 Transformer。但 Transformer 本身不感知顺序——如果不告诉模型"某个 token 在画面的第几行第几列",它就无法理解空间关系。🧩

视频比图像多了一个维度:时间。InternVideo2-Stage2_6B 的视觉编码器配置如下(见 config.json):

配置项值含义
img_size224输入分辨率 224×224
patch_size14每块 14×14 像素
num_frames4取 4 帧
tubelet_size1时间方向不压缩
d_model1408每个 patch 的向量维度

因此,4 帧视频会被切成一个4×16×16 的 3D 网格(时间 4 层,每层 16×16 个 patch),网格划分逻辑见 modeling_internvideo2.py 中的PatchEmbed。位置编码要回答的问题也随之变成三维的:"这个 token 来自第几帧?哪一行?哪一列?"

二、正弦编码原理:用波的频率"编号"位置

InternVideo2 采用的是经典的正弦-余弦位置编码(源自 Transformer 原论文,MoCo v3 也沿用了该方案)。核心函数是 get_1d_sincos_pos_embed_from_grid:

  1. 先构造一组"频率":ω = 1 / 10000^(0, 2/D, 4/D, ...),波长从 2π 到 10000·2π 对数级展开;
  2. 用位置编号pos分别乘以这些频率,得到角度;
  3. 对角度同时取sin与cos,把两部分拼起来作为该位置的位置向量。
omega = 1.0 / 10000 ** omega # 一组从高频到低频的"波长" out = np.einsum("m,d->md", pos, omega) # 位置 × 频率 emb = np.concatenate([np.sin(out), np.cos(out)], axis=1)

这种设计有两个天然优势:

  • 免训练:位置编码是"算"出来的,不是"学"出来的,初始化即可用;
  • 相对位置友好:sin/cos 满足三角恒等式,模型很容易从位置向量里"读出"两个位置的相对距离。

在 2D 图像上(get_2d_sincos_pos_embed_from_grid),维度被对半分:一半编码行号,一半编码列号。

三、3D 版的精髓:一份维度,三种角色

get_3d_sincos_pos_embed 是本文的主角。它把embed_dim(1408 维)按1/4 : 3/4切成时间与空间两大部分:

位置分量占用维度说明
时间 T(第几帧)352 = 1408 × 1/41D 正弦编码 4 个帧位置
高度 H(第几行)528 = 1408 × 3/4 ÷ 22D 编码的一半
宽度 W(第几列)5282D 编码的另一半

组装方式很巧妙:把时间向量沿 16×16 个空间位置重复,把空间向量沿 4 个时间帧重复,然后按最后一维拼接,就得到形状为[T×H×W, 1408]=[1024, 1408]的完整位置表;若启用cls_token,最前面再补一行全零向量给分类 token。

💡 空间占了 3/4 的维度、时间只占 1/4——这反映了一个工程直觉:视觉细节主要在空间里,时间轴上只需足够区分 4 帧即可。

四、图像与视频如何"共用"一套编码器?

这是 InternVideo2-Stage2_6B 最实用的设计之一。它并不为图像另造一个编码器,而是维护两套预填充的位置编码参数(初始化见 init_pos_embed):

  • pos_embed:视频用,时间维 T=4,形状[1, 1+1024, 1408];
  • img_pos_embed:图像用,等价于 T=1 的 3D 编码(时间分量恒定),形状[1, 1+256, 1408]。

两者是否分开由配置项sep_image_video_pos_embed控制(config.json 中设为true)。在前向传播 forward 中,只要use_image=True,模型就选img_pos_embed去加到 patch token 上,其余流程完全一致:

if use_image: pos_embed = self.img_pos_embed # 图像:单帧位置编码 else: pos_embed = self.pos_embed # 视频:4 帧 3D 位置编码 x = x + pos_embed

若关掉分离开关,模型还有一招回退方案:把视频位置编码的 4 帧按时间取平均,得到单帧位置编码(modeling_internvideo2.py)——相当于"把 4 帧的位置信息摊平成 1 帧",让同一份参数也能为图像服务。

此外,主编码器还配有clip_pos_embed/clip_img_pos_embed两份孪生参数,专门服务于 CLIP 对齐分支(modeling_internvideo2.py),保证对齐目标与主任务各自拥有干净的位置信息。

五、位置编码的"特权身份":不衰减、可插值

位置编码在这个模型里享受两个特殊待遇:

  1. 不参与权重衰减。no_weight_decay 明确把pos_embed、img_pos_embed、clip_pos_embed等全部排除在 weight decay 之外——它们更像"先验地图",只需微调,不该被正则项拉向零。

  2. 帧数变了也能插值。预训练固定用 4 帧,如果加载检查点时目标帧数不同,interpolate_pos_embed 会先把位置表还原成[帧, 空间, 维度]的形状,沿时间维做线性插值,再把 cls token 原样接回——空间变化时同理做双线性插值。这让 4 帧预训练的模型能平滑迁移到其他帧数的场景。

六、上手体验:三行代码感受它的工作效果

模型自带演示脚本 demo.py,核心调用只有几行:

model = AutoModel.from_pretrained( "OpenGVLab/InternVideo2-Stage2_6B", trust_remote_code=True).eval() texts, probs = retrieve_text(frames, text_candidates, model=model, topk=5) feat = model.get_vid_feat(vid2tensor('example1.mp4', fnum=4))

其中 retrieve_text 负责视频帧采样与文本特征检索,get_vid_feat 则走完整的"切 patch → 加 3D 位置编码 → 过 Transformer 块 → 池化"流程。仓库内还附有示例视频 example1.mp4,可直接验证视频-文本检索效果。

七、关键文件速查表

文件内容
modeling_internvideo2.py#L149-L1671D 正弦位置编码核心实现
modeling_internvideo2.py#L335-L3803D 位置编码组装(时间 1/4 + 空间 3/4)
modeling_internvideo2.py#L858-L881视频/图像两套位置编码的初始化
modeling_internvideo2.py#L924-L960前向传播中位置编码的选择与叠加
config.json#L457-L486视觉编码器关键超参数
demo.py / README.md使用示例与说明

总结

InternVideo2-Stage2_6B 的 3D 正弦位置编码,本质上是一次优雅的"维度分配":用 1/4 的维度编码第几帧、3/4 的维度编码第几行第几列,再靠"图像=单帧视频"的视角,让一套视觉编码器无缝覆盖图像与视频两大模态。位置编码免训练、可插值、不衰减的特性,则保证了它在不同分辨率和帧数下的稳健性。理解了这套机制,你就掌握了多模态大模型中"时空统一建模"的一块基石。🎬

【免费下载链接】InternVideo2-Stage2_6B

项目地址:https://ai.gitcode.com/OpenGVLab/InternVideo2-Stage2_6B
点击查看免费下载
上一篇:实战指南:3步实现LLM评估结果可视化与深度分析
下一篇:高效开源浏览器资源嗅探工具:猫抓扩展深度技术解析与实战指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询