【免费下载链接】InternVL2-40B
InternVL2-40B 是 OpenGVLab 开源的 400 亿参数多模态大模型,支持视频理解、文档图表问答、OCR 等多模态任务。本文带你用仓库自带的示例视频,掌握 InternVL2-40B 的 32 帧抽帧技巧与多轮视频问答实战方法,几分钟跑通完整流程。
为什么选 InternVL2-40B 做视频理解
InternVL2-40B 由 InternViT-6B-448px-V1.5 视觉编码器 + MLP 投影层 + Nous-Hermes-2-Yi-34B 语言模型组成,采用 8k 上下文窗口训练,训练数据中就包含长文本、多图和视频,因此在视频任务上表现突出:
| 基准测试 | GPT-4V | LLaVA-NeXT-Video | InternVL2-40B |
|---|---|---|---|
| MVBench | - | - | 72.5 |
| Video-MME(无字幕) | 59.9 | 52.0 | 61.2 |
| Video-MME(有字幕) | 63.3 | 54.9 | 62.4 |
更多基准成绩可查阅 README.md 中的 Video Benchmarks 表格。模型结构细节见 config.json 与 modeling_internvl_chat.py。
核心原理:抽帧,而不是喂整个视频
InternVL2-40B 本身是"图像 + 文本"模型,视频理解的关键思路是:从视频中均匀抽取若干帧,把每一帧当作一张图片送入模型。
整个流程分三步:
- 抽帧:用
decord的VideoReader读取视频,get_index函数把总时长等分成num_segments段,每段取中间一帧(默认参数就是 32 段,即抽 32 帧); - 预处理:每帧经过
dynamic_preprocess动态缩放为 448x448 的图块(tile),max_num控制每帧最多切成几块; - 组装提示词:用
num_patches_list记录每帧的图块数,并在问题前拼接Frame1: <image>、Frame2: <image>……前缀,让模型知道这是有序的视频帧。
仓库示例视频 examples/red-panda.mp4 是一只小熊猫的画面,下方就是同源的示例图,适合验证模型是否正确识别主体与动作:
32帧抽帧快速上手
加载模型(8bit 量化单卡 80GB 即可,量化参数说明见 README.md)后,核心代码只需几行:
from decord import VideoReader, cpu # load_video 内部会完成抽帧 + 动态分辨率切块 pixel_values, num_patches_list = load_video('./examples/red-panda.mp4', num_segments=32, # 抽 32 帧 max_num=1) # 每帧 1 块 pixel_values = pixel_values.to(torch.bfloat16).cuda() video_prefix = ''.join([f'Frame{i+1}: <image>\n' for i in range(len(num_patches_list))]) question = video_prefix + 'What is the red panda doing?' response, history = model.chat(tokenizer, pixel_values, question, generation_config, num_patches_list=num_patches_list, history=None, return_history=True)💡 抽帧函数的完整实现(
get_index/load_video)可直接参考 README.md 的 Inference with Transformers 一节,拷贝即用。
num_segments=32意味着模型看到 32 个时间切片;如果你的视频较短或显存紧张,改成num_segments=8即可(README 官方示例用的就是 8 帧)。
多轮视频问答:用 history 连续追问
多轮对话的精髓在于return_history=True——第一轮返回的history对象包含已构建好的上下文,下一轮直接传入即可,帧数据不用重新编码,省显存也省时间:
# 第一轮:问视频里发生了什么 question = 'What is the red panda doing?' response, history = model.chat(tokenizer, pixel_values, question, generation_config, num_patches_list=num_patches_list, history=None, return_history=True) # 第二轮:直接追问,复用 history question = 'Describe this video in detail.' response, history = model.chat(tokenizer, pixel_values, question, generation_config, num_patches_list=num_patches_list, history=history, return_history=True)注意第二轮的问题里不要再写<image>前缀,图像 token 已经在 history 里了,重复添加会导致理解错位。
参数调优实战技巧
| 参数 | 作用 | 调优建议 |
|---|---|---|
num_segments | 抽取帧数(默认 32) | 短视频 8~16 帧足够;长视频可降帧数防显存溢出 |
max_num | 每帧最多切块数(1~12) | 帧多时设 1 保上下文;关键帧场景可放大提细节 |
bound | 时间区间 (start, end) | 只关注视频某段时间时,可只抽该区间 |
input_size | 图块尺寸(默认 448) | 保持 448,这是官方评测的分辨率 |
do_sample | 是否采样生成 | 问答类任务建议True让回答更自然 |
几条容易踩的坑:
- ⚠️ 必须
transformers>=4.37.2且加载时加trust_remote_code=True,否则自定义模型文件无法识别; - ⚠️ 帧数 × 每帧块数 = 输入图块总数,直接决定显存占用。32 帧 × 12 块是理论上限,日常建议 32 帧 × 1 块起步;
- ⚠️ 长视频超过上下文时优先减
num_segments,而不是减max_num,时间覆盖比单帧细节更重要。
常见问题
Q:显存不够跑 40B 怎么办?使用load_in_8bit=True单卡 80GB 即可运行;bf16 全精度则至少需要两块 80GB 卡,多卡分配方案见 README.md。
Q:视频没有动作,模型回答像图片描述?抽帧数太少了,把num_segments调大,让模型看到更多时间变化。
Q:想部署成在线服务?可以用 LMDeploy 一键打包,兼容 OpenAI 接口,命令见 README.md 的 Deployment 一节。
掌握"抽帧 + 帧前缀 + history 续聊"这套组合拳,你就能用 InternVL2-40B 完成从短视频到长视频的理解与问答任务了。
【免费下载链接】InternVL2-40B
相关推荐
从16帧到视频问答:InternVL2-26B 视频理解完整实战指南
从16帧到视频问答:InternVL2 26B 视频理解完整实战指南 🎬 InternVL2 26B 是上海 AI Lab 开源的 25.5B 参数多模态大语
InternVL2_5-26B视频理解实战:抽帧策略设置与视频多轮对话技巧
InternVL2_5 26B视频理解实战:抽帧策略设置与视频多轮对话技巧 InternVL2_5 26B 是上海 AI Lab 开源 InternVL 2.5
让 InternVL2_5-8B-MPO 看懂视频:视频抽帧、多轮视频对话与动态分辨率实战教程
让 InternVL2_5 8B MPO 看懂视频:视频抽帧、多轮视频对话与动态分辨率实战教程 InternVL2_5 8B MPO 是 OpenGVLab 开
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考