llama.cpp 中运行 MiniCPM-V 4.0 视觉模型的完整实战指南:从模型手术到 mtmd 推理
本文以 llama.cpp 仓库中的 MiniCPM-V 4.0 多模态指南为核心,完整讲解如何在 llama.cpp 中部署 openbmb 的 MiniCPM-V 4 视觉模型:包括 PyTorch 权重"手术"拆分、视觉编码器转 GGUF(mmproj)的转换流程、语言模型量化,以及使用 llama-mtmd-cli 进行单轮提问与多轮会话推理。读完本文,你将能够独立完成 MiniCPM-V 4.0 从 PyTorch 仓库到本地 GGUF 推理的全链路操作,并理解每个脚本在源码层面的实际作用。
一、背景:MiniCPM-V 4.0 在 llama.cpp 多模态体系中的定位
llama.cpp 的多模态支持(mtmd,multimodal)是一个持续高速迭代的子项目。早期它为 LLaVA 提供 llava.cpp 支持,随后模型专属 CLI(如 minicpmv-cli)不断涌现,最终统一收敛为 libmtmd 库和单一入口 llama-mtmd-cli(见 mtmd 开发说明)。运行一个多模态模型通常需要两个 GGUF 文件:
- 标准语言模型文件(由
convert_hf_to_gguf.py转换); - 对应的多模态投影器(
mmproj) 文件,负责图像编码与投影。
MiniCPM-V 4.0 属于"旧式"视觉模型,不能直接用 convert_hf_to_gguf.py --mmproj 一键生成投影器,必须走 tools/mtmd/legacy-models 下的专用手术脚本——这正是 官方 MiniCPM-V 4.0 指南 所描述的流程。
二、准备工作:获取 PyTorch 模型与构建 llama.cpp
2.1 下载 PyTorch 权重
将 openbmb 的 MiniCPM-V-4 PyTorch 模型从 Hugging Face 下载到一个名为 MiniCPM-V-4 的目录中。官方指南同时提供了由 openbmb 预先转换好的 GGUF 版本(MiniCPM-V-4-gguf),如果不需要亲手练习转换流程,可直接下载现成 GGUF 跳到第五节。
2.2 构建 llama.cpp
克隆仓库并用 CMake 构建:
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
cmake -B build
cmake --build build --config Release
构建成功后会生成 build/bin/ 下的 llama-mtmd-cli、llama-quantize 等可执行文件。完整构建选项请参考仓库构建文档(docs/install.md 及相关后端文档)。
三、模型"手术":拆分投影器、视觉编码器与纯文本 LLM
MiniCPM-V 的 PyTorch 检查点把视觉编码器、多模态投影器和语言模型混在同一个模型对象里,而 convert_hf_to_gguf.py 只认识标准因果语言模型。因此第一步是运行手术脚本:
python ./tools/mtmd/legacy-models/minicpmv-surgery.py -m ../MiniCPM-V-4
从 minicpmv-surgery.py 的源码可以看清它实际完成了四件事:
- 抽取投影器权重:遍历
state_dict,把所有以resampler开头的张量挑出来,float 化后保存为minicpmv.projector。如果模型配置带scale_emb且存在resampler.proj,会把resampler.proj除以scale_emb(源码第 19-20 行),这一步是权重归一化的关键细节; - 抽取视觉编码器权重:把以
vpm开头的张量去掉vpm.前缀后保存为minicpmv.clip(源码第 23-26 行),它就是后续生成mmproj的原始 ViT 权重; - 清理附加词表:若存在
added_tokens.json则清空为{}(源码第 29-31 行)。注释写明原因——这些多模态新增 token 必须移除,否则后续按普通 LLaMA/Mistral 系模型转换会出错; - 导出纯文本 LLM:改写
auto_map指向 MiniCPM 的配置与模型类,把model.llm及分词器单独保存到../MiniCPM-V-4/model子目录(源码第 33-43 行),使之成为标准 HF 因果语言模型结构,供第 3.2 节的通用转换脚本处理。
脚本结束时会打印提示:现在可以把 model/ 当作常规 LLaMA GGUF 转换,并用 minicpmv.projector 准备投影器文件了。
四、转换:生成 mmproj 与语言模型 GGUF
4.1 生成视觉投影器 mmproj-model-f16.gguf
python ./tools/mtmd/legacy-models/minicpmv-convert-image-encoder-to-gguf.py \
-m ../MiniCPM-V-4 \
--minicpmv-projector ../MiniCPM-V-4/minicpmv.projector \
--output-dir ../MiniCPM-V-4/ \
--minicpmv_version 5
关键参数在 minicpmv-convert-image-encoder-to-gguf.py 中均有定义:
| 参数 | 作用 | 依据 |
|---|---|---|
-m, --model-dir |
HF Hub 克隆下来的模型目录(必填) | 源码第 485 行 |
--minicpmv-projector |
指向手术脚本产出的 minicpmv.projector;指定后输出文件名前缀为 mmproj-,并只包含视觉编码器与投影器 |
源码第 495 行、第 663-666 行 |
--minicpmv_version |
MiniCPM 系列版本号:2=MiniCPM-V 2.5,3=MiniCPM-V 2.6,4=MiniCPM-o 2.6,5=MiniCPM-V 4.0,6=MiniCPM-o 4.0 |
源码第 504 行 |
-o, --output-dir |
GGUF 输出目录,默认为原模型目录 | 源码第 497 行 |
--projector-type |
投影器类型 mlp / ldp / ldpv2,默认 mlp |
源码第 496 行 |
--use-f32 |
用 f32 而非默认的 f16 保存权重 | 源码第 486 行 |
--minicpmv_version 5 的语义可以从源码中验证:版本号 5 时脚本按 SigLIP 视觉编码器建模(model_type = "siglip_vision_model",源码第 635-638 行),并且当找不到 config.json 时回退到 emb_dim = 2560、block_count = 27 的硬编码默认值(源码第 607-609 行);若能读到模型配置,则直接采用 hidden_size 与 vision_config 的真实值(源码第 570-590 行)。加载的视觉权重来自手术脚本生成的 minicpmv.clip(源码第 653 行)。
输出文件的元数据同样可追溯:脚本会向 GGUF 写入 clip.has_minicpmv_projector = true、clip.projector_type = "resampler" 和 clip.minicpmv_version = 5 等字段(源码第 679-691 行),推理端的 libmtmd 正是依据这些元数据选择对应的 MiniCPM-V 模型实现。
4.2 转换语言模型并量化
python ./convert_hf_to_gguf.py ../MiniCPM-V-4/model
# 量化 int4 版本
./build/bin/llama-quantize ../MiniCPM-V-4/model/ggml-model-f16.gguf \
../MiniCPM-V-4/model/ggml-model-Q4_K_M.gguf Q4_K_M
convert_hf_to_gguf.py处理的是手术脚本导出的纯文本 LLM 目录model/,产出ggml-model-f16.gguf;llama-quantize将其量化为Q4_K_M,显著降低显存/内存占用,适合资源受限的机器。
至此获得推理所需的两个文件:
../MiniCPM-V-4/model/ggml-model-f16.gguf(或 Q4_K_M 版本)——语言模型;../MiniCPM-V-4/mmproj-model-f16.gguf——视觉编码器 + resampler 投影器。
五、推理:llama-mtmd-cli 单轮与对话两种模式
5.1 单轮模式(single-turn)
./build/bin/llama-mtmd-cli \
-m ../MiniCPM-V-4/model/ggml-model-f16.gguf \
--mmproj ../MiniCPM-V-4/mmproj-model-f16.gguf \
-c 4096 --temp 0.7 --top-p 0.8 --top-k 100 --repeat-penalty 1.05 \
--image xx.jpg -p "What is in the image?"
命令行参数的官方定义见 mtmd-cli.cpp 的使用说明(源码第 43-46 行):-m 与 --mmproj 为必填;--image、--audio 和 -p 均为可选——一旦提供了 --image 和 -p,即进入单次问答模式,模型回答图像问题后直接结束。采样参数沿用小模型常用配置:上下文 4096、温度 0.7、top-p 0.8、top-k 100、重复惩罚 1.05。
5.2 多轮会话模式(conversation)
./build/bin/llama-mtmd-cli \
-m ../MiniCPM-V-4/model/ggml-model-Q4_K_M.gguf \
--mmproj ../MiniCPM-V-4/mmproj-model-f16.gguf
不提供 --image/-p 时,CLI 进入交互式聊天模式,可在会话中随时输入图片路径或文本(源码注释明确:"if NOT provided, the CLI will run in chat mode",见 mtmd-cli.cpp)。此处示例特意搭配 Q4_K_M 量化的语言模型与 f16 的 mmproj——投影器体积相对较小,保留 f16 有助于保持视觉特征精度,而把大头的语言模型量化以压缩内存。
六、注意事项与延伸
- 文档时效:该指南自述"Readme modification time: 20250731",且 llama.cpp 多模态子项目处于快速迭代期、存在破坏性变更的预期(见 mtmd README 的 IMPORTANT 提示)。若实际运行命令与文档不符,以仓库当前构建文档和 mtmd 目录 为准。
- 同族模型对照:仓库内还有 MiniCPM-V 4.5、MiniCPM-V 4.6、MiniCPM-o 4.0 等指南,流程高度一致,仅
--minicpmv_version取值与投影器生成方式不同(4.6 已支持convert_hf_to_gguf.py --mmproj直接生成)。 - 架构参考:MiniCPM-V 系列在推理端由 minicpmv.cpp 实现图像编码与 resampler 投影的 C++ 侧逻辑,语言模型侧则走 src/models/minicpm.cpp;调试图像预处理链路时可配合 mtmd-debug 工具说明 使用。
- 多模态原理:图像先被
mmproj中的 ViT 编码器转为视觉嵌入,再经 resampler 投影到语言模型词嵌入空间,最后与文本 token 一并送入 LLM——这套"两文件"设计使多模态组件独立于核心libllama快速演进(详见 mtmd README 的 How it works 一节)。
参考文件清单
| 文件 | 说明 |
|---|---|
| docs/multimodal/minicpmv4.0.md | 本文核心指南原文 |
| tools/mtmd/legacy-models/minicpmv-surgery.py | 权重拆分(projector / clip / 纯文本 LLM) |
| tools/mtmd/legacy-models/minicpmv-convert-image-encoder-to-gguf.py | 生成 mmproj-*.gguf 的视觉编码器转换脚本 |
| convert_hf_to_gguf.py | 语言模型 PyTorch → GGUF 转换 |
| tools/mtmd/mtmd-cli.cpp | 统一多模态 CLI 入口(llama-mtmd-cli) |
| tools/mtmd/README.md | 多模态支持原理、mmproj 概念与演进史 |
| tools/mtmd/models/minicpmv.cpp | MiniCPM-V 图像编码与投影的 C++ 实现 |
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00