用 OpenVINO™ 部署 MiniCPM-V 4.6:端侧多模态大模型一站式实践
openlab_96bf3613
更新于 1天前
一、导语:把多模态大模型装进端侧
OpenBMB 最新开源的 MiniCPM-V 4.6 是 MiniCPM-V 系列里最适合端侧部署的一档:基于 SigLIP2-400M 视觉塔 + Qwen3.5-0.8B 语言模型,能力延续了系列一贯的单图、多图、视频理解,并通过 LLaVA-UHD v4 把视觉编码 FLOPs 砍掉一半以上,是当前少数能在 AI PC 上做到流畅多模态对话的 sub-1B 主干模型。
本文给出一条与OpenVINO Notebooks 中minicpm-v-4.6 教程严格对齐的部署路径:环境安装→ optimum-cli 导出 INT4 量化 IR → OVModelForVisualCausalLM 推理 → 单图/视频示例 → Gradio 演示界面,所有命令与代码均可直接**运行。
二、MiniCPM-V 4.6 模型亮点
2.1 主干能力:13 分超越 Qwen3.5-0.8B 的 10 分
MiniCPM-V 4.6 在 Artificial Analysis Intelligence Index 上拿到 13 分,明显高于 Qwen3.5-0.8B 的 10 分,更关键的是平均 token 用量约为后者的 1/19,对端侧部署友好——意味着同样一个回答,所需算力与显存吞吐显著降低。
2.2 多模态能力:在多个榜单逼近 2B 级
OpenCompass:综合视觉-语言能力达到 Qwen3.5 2B 水平;
RefCOCO:指代理解;
HallusionBench:抗幻觉;
OCRBench:图文 OCR——这是端侧最常见的多模态需求之一。
2.3 极致高效的视觉前端
视觉部分基于 LLaVA-UHD v4,相比上一代视觉编码 FLOPs 减少 50% 以上,并支持4× / 16× 两档视觉 token 压缩:4× 模式保留更多细节、token 略多;16× 模式更省算力,是默认推荐。在 OpenVINO™ 推理时,这两档分别对应downsample_mode="4x" 与downsample_mode="16x" 参数。
2.4 端侧覆盖
官方明确支持 iOS / Android / HarmonyOS。本文将这套能力延伸到 PC 侧——通过 OpenVINO™,让 Intel CPU、酷睿 Ultra iGPU、Arc 独立显卡都能成为它的可选后端。
三、为什么用 OpenVINO™ + Optimum Intel
- Optimum Intel:一行optimum-cli export openvino 即可把多模态 VLM 拆成视觉塔、文本嵌入、语言模型等多个子图,并打包为 OpenVINO™ IR;同时内置 NNCF 权重压缩,免写转换脚本。
OVModelForVisualCausalLM:与 Hugging Face AutoModelForCausalLM 同构的接口——from_pretrained / generate 均沿用 Transformers 习惯,几乎零迁移成本。
全后端覆盖:相同 IR 模型可在 CPU / iGPU / Arc 独显 / AUTO 上无差别运行;多模态多子图配合动态形状目前不建议跑 NPU。
四、端到端部署实操
下文所有命令源自 OpenVINO™ Notebooks 仓库的 minicpm-v-4.6 教程;该 notebook 当前标记为 EXPERIMENTAL,使用了 optimum-intel 的自定义分支。
4.1 环境准备
建议 Python 3.10 及以上,先在干净虚拟环境里把已有的 transformers / optimum 系列卸载,再装本教程指定的版本:
python -m venv minicpmv-env# Windows: minicpmv-env\Scripts\activate# Linux / macOS: source minicpmv-env/bin/activatepip uninstall -y transformers optimum optimum-intel optimum-onnxpip install "git+https://github.com/openvino-dev-samples/optimum-intel.git@minicpm-v4.6" \--extra-index-url https://download.pytorch.org/whl/cpupip install "transformers[torch]==5.7.0" "torchvision" "torchcodec" "av" "Pillow" \"gradio>=4.19,<6" \--extra-index-url https://download.pytorch.org/whl/cpupip install nncfpip install --pre -U openvino openvino-tokenizers \--extra-index-url https://storage.openvinotoolkit.org/simple/wheels/nightly# macOS 用户额外执行:# pip install "numpy<2.0"
其中optimum-intel 必须使用@minicpm-v4.6 这个自定义分支,主仓尚未合并,等正式 PR 合入后即可切回 PyPI 主线版本。
4.2 一键导出 OpenVINO™ IR + INT4 量化
推荐 INT4 权重压缩——体积约为 FP16 的 1/4,端侧 8GB 显存即可流畅加载:
optimum-cli export openvino \--model openbmb/MiniCPM-V-4.6 \--task image-text-to-text \--trust-remote-code \--weight-format int4 \--group-size 128 \--ratio 0.8 \MiniCPM-V-4.6-ov/INT4
--task image-text-to-text 告诉 optimum-intel 这是「图文输入、文本输出」的多模态任务,会自动生成视觉塔 / 文本嵌入 / 语言模型多个子图;--trust-remote-code 是因为 MiniCPM-V 4.6 的建模代码托管在 HF 仓库自身(含视觉前端的 LLaVA-UHD v4 实现),需要执行远端 Python 代码完成转换;--ratio 0.8 表示 80% 的权重走 INT4,余下 20% 走更高精度——是社区在 LLM/VLM 上验证较稳的默认折中。
如果你需要最高精度(也最大体积)的 FP16 版本:
optimum-cli export openvino \--model openbmb/MiniCPM-V-4.6 \--task image-text-to-text \--trust-remote-code \--weight-format fp16 \MiniCPM-V-4.6-ov/FP16
4.3 选择推理设备
from notebook_utils import device_widgetdevice = device_widget(default="AUTO", exclude=["NPU"])device # 在 Jupyter 中渲染下拉框:CPU / GPU / AUTO
MiniCPM-V 4.6 的多模态 pipeline 由多个子图组成,且视觉部分存在动态形状,目前不建议跑 NPU——所以这里用 exclude=["NPU"] 直接屏蔽。日常开发推荐AUTO 让 OpenVINO™ 自动决策;想固定用独显或 iGPU,则选 GPU。
4.4 加载模型与处理器
from pathlib import Pathfrom optimum.intel import OVModelForVisualCausalLMfrom transformers import AutoProcessormodel_dir = Path("MiniCPM-V-4.6-ov/INT4")processor = AutoProcessor.from_pretrained(model_dir, trust_remote_code=True)ov_model = OVModelForVisualCausalLM.from_pretrained(model_dir,trust_remote_code=True,device=device.value,)print(f"Model loaded on {device.value}")
4.5 单图推理:解释一张「光的折射」图
下载 MiniCPM-V 模型卡里的示例图,问它「这是什么物理现象」:
from pathlib import Pathimport requestsfrom PIL import Imageexample_image_url = "https://huggingface.co/datasets/openbmb/DemoCase/resolve/main/refract.png"example_image_path = Path("refract.png")if not example_image_path.exists():Image.open(requests.get(example_image_url, stream=True).raw).save(example_image_path)image = Image.open(example_image_path).convert("RGB")question = "What causes this phenomenon?"messages = [{"role": "user","content": [{"type": "image", "image": image},{"type": "text", "text": question},],}]# 视觉 token 压缩:默认 16x(更省算力),需要更细的细节可改成 "4x"downsample_mode = "16x"inputs = processor.apply_chat_template(messages,tokenize=True,add_generation_prompt=True,return_dict=True,return_tensors="pt",downsample_mode=downsample_mode,max_slice_nums=36,)output = ov_model.generate(**inputs,downsample_mode=downsample_mode,max_new_tokens=512,do_sample=False,)generated_ids = output[0, inputs["input_ids"].shape[1]:]answer = processor.decode(generated_ids, skip_special_tokens=True)print(answer)
三个关键参数对齐: apply_chat_template 与generate 中的downsample_mode 必须保持一致;max_slice_nums=36 控制单图最多切片数(高分辨率长图建议保留默认);do_sample=False 选择确定性输出便于复现,在酷睿Ultra2处理器平台的运行效果如下:
4.6 4× vs 16× downsample_mode 该怎么选
16x(默认):适合大多数自然图像理解、对话场景,token 更少、首 token 延迟更低;
4x:适合 OCR、表格、密集文字等需要细节的任务,但视觉 token 更多、显存与算力开销更高。
五、视频推理:让模型看一段足球集锦
MiniCPM-V 4.6 原生支持视频输入。教程中给了一段 football.mp4 作为示例,下面这段代码即可让模型「描述这段视频」——和单图相比只需在 chat template 里多带几个视频专用参数:
video_messages = [{"role": "user","content": [{"type": "video","url": "https://huggingface.co/datasets/openbmb/DemoCase/resolve/main/football.mp4"},{"type": "text", "text": "Describe this video in detail."},],}]downsample_mode = "16x"video_inputs = processor.apply_chat_template(video_messages,tokenize=True,add_generation_prompt=True,return_dict=True,return_tensors="pt",downsample_mode=downsample_mode,max_num_frames=128, # 超过 128 帧自动均匀采样stack_frames=1, # 短视频建议保持 1max_slice_nums=1, # 视频每帧不再做切片use_image_id=False, # 关闭逐帧 <image_id> 标签)video_output = ov_model.generate(**video_inputs,downsample_mode=downsample_mode,max_new_tokens=2048,do_sample=False,)generated_ids = video_output[0, video_inputs["input_ids"].shape[1]:]print(processor.decode(generated_ids, skip_special_tokens=True))
max_num_frames=128:视频帧数上限,超过会均匀采样,覆盖较长视频;
stack_frames=1:短视频按主帧顺序送入;
max_slice_nums=1 / use_image_id=False:避免每帧再做切片或加 ID 标签,减少视觉 token 数量。
由于视频要做更长的描述,max_new_tokens 通常给到 2048。
六、可选:Gradio 多模态 Chat Demo
教程提供了一个开箱即用的 Gradio 演示,支持上传图片 + 文字提问,配合 TextIteratorStreamer 实现流式输出:
from gradio_helper import make_demodemo = make_demo(ov_model, processor)try:demo.launch(debug=True)except Exception:demo.launch(debug=True, share=True)# 远程部署:# demo.launch(server_name="0.0.0.0", server_port=7860)
make_demo 内部用 ChatInterface + MultimodalTextbox 组合:用户上传一张图、输入问题,模型在另一个线程里 generate,主线程从 streamer 里 yield 增量文本回前端。
七、性能与精度建议
在酷睿 Ultra iGPU 上,1.8B 主干 + INT4 即可获得交互级流畅度;Arc A 系或 B 系独显更适合长视频与多图场景;
若 OCR、表格识别等场景质量不达标,先把 downsample_mode 切成 4×,再考虑切 FP16;
INT4 ratio=0.8 / group-size=128 是默认折中,若想更激进的压缩可下调 ratio,但建议先做精度回归。
八、总结与资源链接
凭借 OpenVINO™ + Optimum Intel,把 MiniCPM-V 4.6 这种端侧友好型多模态大模型搬上 Intel 平台已经是一条几乎零摩擦的路径——一条 optimum-cli 命令完成量化导出,几行 Python 代码即可拥有图文/视频对话能力,再叠一个 Gradio demo 就是一个可以演示给业务方的 PoC。
MiniCPM-V 4.6 模型卡:
https://huggingface.co/openbmb/MiniCPM-V-4.6LLaVA-UHD v4:
https://github.com/THUMAI-Lab/LLaVA-UHD-v4Optimum Intel(自定义分支):
https://github.com/openvino-dev-samples/optimum-intel/tree/minicpm-v4.6OpenVINO™ Notebooks:https://github.com/openvinotoolkit/openvino_notebooks
提示:本文步骤源自 OpenVINO Notebooks 中的 EXPERIMENTAL Notebook,optimum-intel 当前需使用自定义分支;待主仓合入后可直接使用 PyPI 版本。