☰
InternVL3_5-30B-A3B-MPO 多模态对话实战:单图问答、多图对比到视频理解,5大核心场景一次讲透
2026/10/17 11:06:33 网站建设 项目流程

【免费下载链接】InternVL3_5-30B-A3B-MPO

项目地址:https://ai.gitcode.com/OpenGVLab/InternVL3_5-30B-A3B-MPO
点击查看免费下载

InternVL3_5-30B-A3B-MPO是 OpenGVLab 开源的多模态大模型(MLLM)权重库,属于 InternVL3.5 家族。它基于 "ViT–MLP–LLM" 架构,语言部分采用 Qwen3-30B-A3B 混合专家(MoE)模型,视觉部分采用 InternViT-300M 编码器。只需3B 激活参数即可驱动 30B 总参数,单卡 A100 即可部署,支持单图问答、多图对比、视频理解、纯文本对话与批量推理五大场景,并完成 CPT + SFT + MPO 三阶段训练。

一、先认识它:模型规格与文件构成

项目说明
模型类型internvl_chat(图像/视频 → 文本)
视觉编码器InternViT-300M(24 层,image_size=448)
语言模型Qwen3-30B-A3B(128 专家,每 token 激活 8 个)
训练阶段CPT + SFT +MPO(离线强化学习阶段)
部署门槛1 张 A100(≤30B 系列)
依赖transformers>=4.52.1

仓库内核心文件速览:

  • 模型结构定义:modeling_internvl_chat.py
  • 视觉编码器(InternViT):modeling_intern_vit.py
  • 对话模板系统:conversation.py
  • 模型配置(分辨率/动态切片等):config.json
  • 视觉权重:vision.safetensors
  • 语言权重按层拆分:layer-0-ep-0-of-1.safetensors 至 layer-47-ep-0-of-1.safetensors,另见权重索引 model.safetensors.index.json
  • 分词器资源:tokenizer_config.json、vocab.json、merges.txt、added_tokens.json

💡MPO 是什么?MPO(Mixed Preference Optimization,混合偏好优化)是 Cascade RL 中的离线 RL 算法,目标是偏好损失 + 质量损失 + 生成损失的加权和。带 MPO 后缀的版本已完成 SFT 后的偏好对齐,回答风格更贴近人类偏好,但未叠加最终的在线 GSPO 阶段。若追求最强推理,可关注无后缀的完整版InternVL3_5-30B-A3B。

二、3 步加载模型:从权重到可对话

以本地路径为例,16-bit 加载只需几行(完整示例见 README.md Quick Start 一节):

import torch from transformers import AutoTokenizer, AutoModel path = "./" # 本仓库目录 model = AutoModel.from_pretrained( path, torch_dtype=torch.bfloat16, low_cpu_mem_usage=True, use_flash_attn=True, trust_remote_code=True).eval().cuda() tokenizer = AutoTokenizer.from_pretrained(path, trust_remote_code=True, use_fast=False)

三个关键参数记住即可:

  1. trust_remote_code=True:模型自带custom_code,必须允许加载仓库内的 modeling 文件;
  2. torch_dtype=torch.bfloat16:显存紧张可改为load_in_8bit=True走 BNB 8-bit 量化;
  3. 多卡部署加device_map="auto"自动分片。

加载后的model就是InternVLChatModel(见 modeling_internvl_chat.py),所有场景都围绕它的chat()方法(定义处)和batch_chat()方法(定义处)展开。

统一生成配置:

generation_config = dict(max_new_tokens=1024, do_sample=True)

三、场景 1:单图问答 —— 最基础也最常用的姿势

单图对话的核心思路:先把图片切成若干 448×448 的"瓦片"(max_num=12控制最多切片数),再用<image>占位符告诉模型"这里有一张图"。

pixel_values = load_image('./examples/image1.jpg', max_num=12).to(torch.bfloat16).cuda() question = '<image>\n请简短描述这张图片。' response = model.chat(tokenizer, pixel_values, question, generation_config) print(response)

单图多轮对话:通过return_history=True拿到历史,第二轮起传入history即可,追问无需重复传图:

question = '<image>\n请详细描述这张图片。' response, history = model.chat(tokenizer, pixel_values, question, generation_config, history=None, return_history=True) question = '根据这张图片写一首诗。' response, history = model.chat(tokenizer, pixel_values, question, generation_config, history=history, return_history=True)

🖼️ 小技巧:图片细节多、文字密(如文档、图表),把max_num调大;普通照片max_num=4就够,能显著降低 token 消耗。

四、场景 2:多图对比 —— 两种方式一次学会

多图对话有两种喂法,官方示例都给了,区别在于模型"怎么数图":

方式 A:拼接图像(不传 num_patches_list)

pixel_values = torch.cat((load_image('./examples/image1.jpg'), load_image('./examples/image2.jpg')), dim=0).to(torch.bfloat16).cuda() question = '<image>\n详细描述这两张图片。' response, history = model.chat(tokenizer, pixel_values, question, generation_config, history=None, return_history=True) question = '这两张图的异同点是什么?' response, history = model.chat(tokenizer, pixel_values, question, generation_config, history=history, return_history=True)

方式 B:独立图像(传 num_patches_list,推荐)

用Image-1: <image>/Image-2: <image>显式编号,模型对每张图的对应关系更准确:

pv1 = load_image('./examples/image1.jpg', max_num=12).to(torch.bfloat16).cuda() pv2 = load_image('./examples/image2.jpg', max_num=12).to(torch.bfloat16).cuda() pixel_values = torch.cat((pv1, pv2), dim=0) num_patches_list = [pv1.size(0), pv2.size(0)] question = 'Image-1: <image>\nImage-2: <image>\n详细描述这两张图片。' response = model.chat(tokenizer, pixel_values, question, generation_config, num_patches_list=num_patches_list)

其原理在源码中很清晰:chat()会按num_patches_list中每张图的切片数,把每个<image>占位符替换成对应数量的图像 token(替换逻辑),编号越清晰,模型越不容易"张冠李戴"。

五、场景 3:视频理解 —— 把视频抽帧当"多帧图片"

InternVL3_5 没有独立的视频分支,而是按帧采样 → 逐帧切片 → 多帧拼接,天然复用多图机制。官方示例从视频中均匀抽取 8 帧(num_segments=8):

pixel_values, num_patches_list = load_video('./examples/red-panda.mp4', num_segments=8, max_num=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 + '小熊猫在做什么?' response, history = model.chat(tokenizer, pixel_values, question, generation_config, num_patches_list=num_patches_list, history=None, return_history=True) question = '请详细描述这段视频。' response, history = model.chat(tokenizer, pixel_values, question, generation_config, num_patches_list=num_patches_list, history=history, return_history=True)

调参经验:

  • 短视频/动作快→ 加大num_segments(32 起步),帧率覆盖更密;
  • 长视频→ 配合bound参数只截取关键时间段;
  • 帧数 × 每帧切片数就是总 token 量,注意控制上下文长度(SFT 阶段为 32K tokens)。

六、场景 4:纯文本对话与批量推理 —— 别忘了它也会"纯聊天"

纯文本:pixel_values传None即可,chat()会退化为普通 LLM 对话(自动补占位符逻辑):

question = '你好,你是谁?' response, history = model.chat(tokenizer, None, question, generation_config, history=None, return_history=True)

批量推理:batch_chat()一次处理 N 张图 + N 个问题,适合文档批量摘要、图片批量打标等流水线任务(注意:不支持多轮):

questions = ['<image>\n详细描述图片。'] * len(num_patches_list) responses = model.batch_chat(tokenizer, pixel_values, num_patches_list=num_patches_list, questions=questions, generation_config=generation_config)

流式输出:用TextIteratorStreamer+ 线程跑model.chat,边生成边打印,体验更接近聊天产品(完整代码见 README.md Streaming Output 一节)。

七、场景 5:生产部署 —— LMDeploy 一行起服务

单机transformers适合开发调试,线上服务推荐 LMDeploy,安装后一条命令即可起 OpenAI 兼容 API:

pip install lmdeploy>=0.9.1 lmdeploy serve api_server OpenGVLab/InternVL3_5-30B-A3B-MPO \ --server-port 23333 --tp 1 --backend pytorch

之后任何支持 OpenAI 接口的客户端都能直接调用,image_url里传图片即可。部署要点:

版本张量并行--tp
≤30B(含本模型)1(单卡 A100)
38B2
241B-A28B8

vLLM 同样支持本系列;多图推理时记得调大session_len,因为多张图会显著增加输入 token 数。

八、进阶:开启 Thinking 深度思考模式

对数学、图表推理等复杂任务,可设置 R1 风格的 system prompt 让模型先"想"再答:

model.system_message = R1_SYSTEM_PROMPT # 提示词全文见 README generation_config = dict(max_new_tokens=1024, do_sample=True, temperature=0.6)

官方建议开启 Thinking 模式时使用do_sample=True且temperature=0.6,避免重复输出。对话模板系统(conversation.py)也内置了多种模板,本模型使用internvl2_5模板(见 config.json 的template字段)。

九、常见问题速查(FAQ)

问题解决办法
加载时报trust_remote_code相关错误加trust_remote_code=True,并确认transformers>=4.52.1
显存不足 OOM用load_in_8bit=True量化,或减小图片max_num
多图回答串图改用方式 B(Image-N:编号 +num_patches_list)
视频回答泛泛而谈增大num_segments抽更多帧,或截取关键时间段
想微调本模型官方支持 InternVL、SWIFT、XTuner 等仓库微调,见 README.md Finetune 一节

十、写在最后

InternVL3_5-30B-A3B-MPO 把"大模型能力"和"MoE 推理效率"结合得很好:30B 的总参数量保证了单图问答、多图对比、视频理解、OCR 与推理任务的通用能力,3B 激活参数 + 单卡 A100 的部署门槛让普通团队也能跑起来。建议上手顺序:先单图 → 再多图 → 再视频 → 最后接入 LMDeploy 服务化,配合本文五个场景的示例代码,基本可以覆盖绝大多数多模态应用需求。

本模型基于 Apache-2.0 协议开源,商业可用;若用于研究引用,参考 README.md 中的 Citation 部分。

【免费下载链接】InternVL3_5-30B-A3B-MPO

项目地址:https://ai.gitcode.com/OpenGVLab/InternVL3_5-30B-A3B-MPO
点击查看免费下载

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

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

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

立即咨询