news 2026/9/24 18:56:56

PowerInfer 多模态推理指南:MiniCPM-o 2.6 图像能力转换与 llama-mtmd-cli 本地部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PowerInfer 多模态推理指南:MiniCPM-o 2.6 图像能力转换与 llama-mtmd-cli 本地部署

PowerInfer 多模态推理指南:MiniCPM-o 2.6 图像能力转换与 llama-mtmd-cli 本地部署

【免费下载链接】PowerInferHigh-speed Large Language Model Serving for Local Deployment项目地址: https://gitcode.com/gh_mirrors/po/PowerInfer

MiniCPM-o 2.6 是 OpenBMB 推出的支持图像输入的端侧多模态大模型,本指南以仓库中 smallthinker/docs/multimodal/minicpmo2.6.md 为骨架,完整讲解从 Hugging Face 下载 PyTorch 权重、执行模型拆分手术、转换为 GGUF 与 mmproj 视觉投影文件、量化压缩,到使用llama-mtmd-cli进行单轮问答与多轮对话的完整本地部署流程。读完本文,你将掌握一套可复现的 MiniCPM-o 2.6 端侧多模态推理方案,并理解libmtmd视觉编码器与语言模型协同工作的底层原理。

一、背景:MiniCPM-o 2.6 与当前支持范围

MiniCPM-o 2.6 属于 MiniCPM 系列的多模态模型。需要首先明确的是:当前仓库中的该篇指南只支持 minicpm-omni 的图像能力(image capabilities),全模态(音频、视频等)支持仍在规划中,后续会尽快更新完整模式。因此本文所有操作均围绕"图像理解"这一能力展开。

在仓库的smallthinker子项目中,多模态能力由libmtmd库统一提供(替代早期的llava.cpp),其历史演进可参考 smallthinker/tools/mtmd/README.md:从 LLaVA 1.5 起步,经历 MobileVLM、多个模型专属 CLI(如minicpmv-cli)的碎片化阶段,最终由mtmd-cli统一为单一入口。目前支持多模态输入的工具主要有两个(见 smallthinker/docs/multimodal.md):

  • llama-mtmd-cli:命令行交互工具;
  • llama-server:通过 OpenAI 兼容的/chat/completionsAPI 提供服务。

本文聚焦llama-mtmd-cli在 MiniCPM-o 2.6 上的实战。

二、准备工作:模型下载与环境要求

2.1 下载 PyTorch 模型

将 MiniCPM-o-2_6 的 PyTorch 权重下载到本地MiniCPM-o-2_6文件夹:

# 使用 huggingface_hub 或 git lfs 将模型克隆到 MiniCPM-o-2_6 目录 git lfs install git clone https://huggingface.co/openbmb/MiniCPM-o-2_6

下载完成后目录中应包含完整的 transformers 权重文件(*.safetensorsconfig.jsonadded_tokens.json、分词器文件等),后续的"手术"脚本将直接读取该目录。

2.2 获取构建产物:编译 llama.cpp(PowerInfer 的 smallthinker 子项目)

本仓库根目录即为 PowerInfer 项目,其中smallthinker/子目录维护着独立的 llama.cpp 分支代码(多模态工具位于 smallthinker/tools/mtmd)。编译方式与官方 llama.cpp 一致,使用 CMake:

git clone https://github.com/ggerganov/llama.cpp cd llama.cpp cmake -B build cmake --build build --config Release

说明:原文档撰写于 20250206,若使用过程中命令或参数存在差异,请以本仓库 smallthinker/tools/mtmd/CMakeLists.txt 中实际构建的目标为准。构建完成后,build/bin/目录下会生成llama-mtmd-cli可执行文件(以及llama-llava-clillama-gemma3-clillama-minicpmv-clillama-qwen2vl-cli等仅输出废弃提示的兼容二进制,见 CMakeLists.txt)。

从构建脚本可见,llama-mtmd-climtmd-cli.cpp编译而来,并链接了commonmtmd两个库;mtmd库则由mtmd.cppmtmd-audio.cppclip.cppmtmd-helper.cpp等源文件构成,依赖ggmlllama核心库——这正是"视觉编码器与语言模型解耦"的架构体现。

三、核心概念:为什么需要两个 GGUF 文件(mmproj)

在动手转换前,先理解llama.cpp多模态方案的设计思想(详见 smallthinker/tools/mtmd/README.md 的 "What is mmproj" 一节):

  • 多模态推理时,图像先由一个独立的视觉编码器编码为 embedding,再喂给语言模型;
  • 这种设计使多模态组件与核心libllama解耦,可以独立、快速地迭代;
  • 现代视觉模型虽然大多基于 ViT(Vision Transformer),但各自的前处理和投影步骤差异很大,直接整合进libllama难度较高。

因此运行一个多模态模型通常需要两个文件:

  1. 语言模型 GGUF:标准文本模型文件;
  2. mmproj(multimodal projector)GGUF:负责图像编码与投影的视觉投影器文件。

llama-mtmd-cli的源码 smallthinker/tools/mtmd/mtmd-cli.cpp 中,init_vision_context通过mtmd_init_from_file--mmproj指定的路径加载视觉模型,并默认将其放行到 GPU(可通过--no-mmproj-offload关闭)。加载失败时程序会直接报错退出。

四、模型转换:从 PyTorch 到 GGUF 三步走

MiniCPM-o 2.6 不能直接用原始 transformers 权重运行,需要依次执行三个脚本完成转换(官方也提供了转换好的 GGUF 版本 可直接下载,省去本步骤)。

步骤 1:模型手术(surgery)——拆出视觉组件与 LLM

python ./tools/mtmd/minicpmv-surgery.py -m ../MiniCPM-o-2_6

注:原文档中的脚本路径为tools/mtmd/minicpmv-surgery.py,在本仓库中对应位置为 smallthinker/tools/mtmd/legacy-models/minicpmv-surgery.py。

阅读该脚本源码可以清晰看到"手术"做了什么(minicpmv-surgery.py):

  • 加载完整模型后,把张量名以resampler开头的部分(即多模态投影器权重)抽取出来,转成 float32 保存为minicpmv.projector
  • 把张量名以vpm开头的部分(视觉编码器权重)抽取出来,去掉vpm.前缀后保存为minicpmv.clip
  • 将 LLM 部分通过model.llm.save_pretrained保存到model/子目录,同时保存分词器;
  • 特别地,脚本会清空added_tokens.json(注释说明这是为了移除额外 token 以便转换 Mistral 系模型)。

执行完毕后,MiniCPM-o-2_6/下会出现minicpmv.projectorminicpmv.clipmodel/三个关键产物。

步骤 2:转换视觉编码器 + 投影器为 mmproj GGUF

python ./tools/mtmd/minicpmv-convert-image-encoder-to-gguf.py -m ../MiniCPM-o-2_6 --minicpmv-projector ../MiniCPM-o-2_6/minicpmv.projector --output-dir ../MiniCPM-o-2_6/ --image-mean 0.5 0.5 0.5 --image-std 0.5 0.5 0.5 --minicpmv_version 4

对应仓库脚本为 smallthinker/tools/mtmd/legacy-models/minicpmv-convert-image-encoder-to-gguf.py。几个关键参数说明如下:

  • -m/--model-dir:模型目录(必填),脚本会从中读取minicpmv.clip
  • --minicpmv-projector:上一步生成的minicpmv.projector路径;一旦指定,输出即为"图像编码器"文件(文件名前缀mmproj-);
  • --output-dir:输出目录,默认与模型目录相同;
  • --image-mean / --image-std:图像归一化参数。MiniCPM-o 2.6 使用0.5 0.5 0.5(而非 CLIP 默认的0.48145466 0.4578275 0.40821073,脚本中通过 default_image_mean/default_image_std 定义),这两组值会被写入 GGUF 元数据clip.vision.image_mean/clip.vision.image_std,供推理时图像预处理使用;
  • --minicpmv_version:版本标记,MiniCPM-o 2.6 必须使用 4。脚本中版本与视觉架构的对应关系(源码 L546-L579)为:
    • 1 = MiniCPM-V-2:emb_dim 2304,block_count 26;
    • 2 = MiniCPM-V-2.5:emb_dim 4096,block_count 27;
    • 3 = MiniCPM-V-2.6:emb_dim 3584,block_count 27,使用 SiglipVisionTransformer;
    • 4 = MiniCPM-o-2.6:emb_dim 3584,block_count 27,同样使用 SiglipVisionTransformer(即 SigLIP 视觉塔,hidden_size 1152、patch_size 14、图像尺寸 980)。

转换脚本还会做投影器张量重命名(resampler.attn.in_proj_*拆分为 q/k/v、resampler.proj转置等,见_replace_name_resampler),并在 GGUF 头中写入clip.has_minicpmv_projector = trueclip.projector_type = "resampler"clip.minicpmv_version = 4等元数据,最终输出mmproj-model-f16.gguf

步骤 3:转换语言模型为 GGUF

python ./convert_hf_to_gguf.py ../MiniCPM-o-2_6/model

对应仓库脚本为 smallthinker/convert_hf_to_gguf.py。这里转换的是步骤 1 产生的model/子目录(纯 LLM 部分),默认输出ggml-model-f16.gguf。需要说明的是,该转换脚本还支持--mmproj参数(见 源码 L6526-L6536),可直接为部分视觉模型导出mmproj-前缀的文件,但 MiniCPM-o 2.6 需要按照上述"手术 + 独立转换脚本"的流程处理视觉部分。

可选:量化 int4 版本

./build/bin/llama-quantize ../MiniCPM-o-2_6/model/ggml-model-f16.gguf ../MiniCPM-o-2_6/model/ggml-model-Q4_K_M.gguf Q4_K_M

使用llama-quantize将 f16 语言模型量化为Q4_K_M格式,可显著减小体积、降低内存占用。注意量化仅针对语言模型 GGUF;mmproj 视觉投影文件通常保持 f16 即可(其张量较小,量化收益有限)。

五、推理实战:llama-mtmd-cli 的两种运行模式

转换完成后,MiniCPM-o-2_6/目录下应有:

  • model/ggml-model-f16.gguf(及可选model/ggml-model-Q4_K_M.gguf
  • mmproj-model-f16.gguf

下面在 Linux 或 macOS 上运行推理。从 mtmd-cli.cpp 源码可以看到两条硬性约束:-m--mmproj为必填参数(缺--mmproj会直接打印用法并退出);若同时提供-p提示词与--image图片,则进入单轮模式,否则进入对话模式

5.1 单轮模式:一次问答识别一张图

./build/bin/llama-mtmd-cli -m ../MiniCPM-o-2_6/model/ggml-model-f16.gguf --mmproj ../MiniCPM-o-2_6/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?"

参数含义:

  • -m:语言模型 GGUF 路径;
  • --mmproj:视觉投影器 GGUF 路径;
  • -c 4096:上下文长度,多模态场景建议 4096 起步;
  • --temp 0.7--top-p 0.8--top-k 100:采样参数,控制生成多样性与质量(注意mtmd-cli的默认 temp 是 0.2,见 源码 L252,此处显式覆盖);
  • --repeat-penalty 1.05:重复惩罚;
  • --image xx.jpg:输入图片路径(可多次指定多张图);
  • -p "...":用户提示词。

源码中单轮模式的处理逻辑(mtmd-cli.cpp L291-L311)值得留意:若提示词中未包含图像占位标记,程序会为每张图片自动追加默认标记<__image__>mtmd_default_marker(),其宏定义为MTMD_DEFAULT_IMAGE_MARKER,见 mtmd.h L42)。也就是说你甚至可以不写标记,直接让图片与文本一起送入模型。

5.2 对话模式:多轮图文聊天

./build/bin/llama-mtmd-cli -m ../MiniCPM-o-2_6/model/ggml-model-Q4_K_M.gguf --mmproj ../MiniCPM-o-2_6/mmproj-model-f16.gguf

不传-p--image即进入交互式聊天。启动后支持以下内置命令(源码 L313-L323):

  • /image <path>:加载一张图片(mtmd_support_vision返回支持时才会显示该命令);
  • /audio <path>:加载一段音频(仅当视觉模型支持音频时显示;MiniCPM-o 2.6 当前只启用图像能力,因此该命令通常不会出现);
  • /clear:清空对话历史(内部调用llama_kv_self_seq_rm保留 BOS 后删除历史 KV);
  • /quit/exit:退出程序。

多轮对话中图片会通过<__image__>标记嵌入到消息内容中参与编码,模型即可基于图片继续多轮问答。/clear之后n_past归零、KV 缓存清空,可重新开启一轮全新会话。

六、底层原理速览:图像如何进入语言模型

结合源码,可以把 MiniCPM-o 2.6 图像推理的完整链路概括为四步:

  1. 加载llama-mtmd-cli通过common_init_from_params初始化语言模型,再经mtmd_init_from_file加载 mmproj 视觉模型(mtmd-cli.cpp L89-L140);
  2. 编码mtmd_tokenize接收文本、位图(bitmap)等输入块,由视觉编码器将图像编码为图像 embedding;
  3. 拼接与评估mtmd_helper_eval_chunks将文本 token 与图像 embedding 按占位标记顺序拼接成输入块,一并喂给llama_decode做前向计算(mtmd-cli.cpp L199-L246);
  4. 生成common_sampler_sample+common_sampler_accept逐 token 采样输出,遇到 EOG(end-of-generation)token 或反提示词(antiprompt,如旧版 vicuna 模板的ASSISTANT:)时停止(mtmd-cli.cpp L163-L197)。

其中视觉部分读取 GGUF 中写入的image_meanimage_stdminicpmv_version等元数据完成图像归一化与架构选择,保证"转换期参数"与"推理期预处理"严格一致——这也是为什么第 4 步必须正确传入--image-mean 0.5 0.5 0.5 --image-std 0.5 0.5 0.5 --minicpmv_version 4

另外,仓库中还提供了 smallthinker/tools/mtmd/tests.sh 与测试图片 smallthinker/tools/mtmd/test-1.jpeg,可用于快速验证构建出的llama-mtmd-cli功能是否正常。

七、常见问题与注意事项

  • --mmproj缺失报错llama-mtmd-cli强制要求--mmproj,多模态推理必须同时提供语言模型与视觉投影器两个文件;若用-hf user/repo方式加载则多数情况可同时推导两者(见 mtmd-cli.cpp L41-L47)。
  • 版本号写错导致加载失败--minicpmv_version决定视觉塔架构(3 与 4 均用 SigLIP,但张量结构与投影器不同),MiniCPM-o 2.6 必须为 4;写错会出现张量名不匹配或加载报错。
  • 上下文长度:图像会占用较多 token,-c 4096是稳妥起点,长对话可适当增大。
  • 全模态支持:当前 MiniCPM-o 2.6 仅启用了图像能力,音频等全模态能力待上游更新,请勿期望当前版本支持音频输入。
  • 本项目为镜像仓库、只读:本文所有转换、构建、运行操作均在本地进行,不涉及修改仓库内容。

八、总结

本指南完整覆盖了 MiniCPM-o 2.6 在 PowerInfer(smallthinker 子项目)上从模型下载、三步转换(手术拆分 → 视觉编码器转 GGUF → 语言模型转 GGUF)、可选 int4 量化,到llama-mtmd-cli单轮/对话双模式推理的全流程,并深入到 minicpmv-surgery.py、minicpmv-convert-image-encoder-to-gguf.py 与 mtmd-cli.cpp 的源码实现,解释了 mmproj 双文件机制、resampler 投影器张量处理、SigLIP 视觉塔版本映射与图像占位标记的工作原理。按照本文步骤操作,即可在本地用 GGUF 格式高效运行 MiniCPM-o 2.6 的图像理解能力;更多多模态模型支持情况可查阅 smallthinker/docs/multimodal.md 与 smallthinker/tools/mtmd/README.md。

【免费下载链接】PowerInferHigh-speed Large Language Model Serving for Local Deployment项目地址: https://gitcode.com/gh_mirrors/po/PowerInfer

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 18:55:48

从@Scheduled到XXL-JOB:Spring Boot定时任务分布式迁移实战

告别Scheduled&#xff01;手把手把Spring Boot定时任务迁移到XXL-JOB先说说背景。我接手过一个电商项目&#xff0c;初期定时任务不多&#xff0c;用Spring Boot自带的Scheduled注解写得很爽——库存超时关单、优惠券过期提醒、每日报表统计&#xff0c;一个注解搞定。但到了后…

作者头像 李华
网站建设 2026/9/24 18:55:43

长春广受信赖的出国留学培训专业学校客户口碑力荐

留学申请服务的基础认知&#xff1a;从概念到价值 留学申请服务&#xff0c;也就是我们常说的留学规划与申请咨询服务&#xff0c;属于面向计划出国留学的学生及家庭提供的贯穿申请全程的专业咨询服务。不同于单一的语言培训或者文书代写&#xff0c;正规的全流程留学申请服务覆…

作者头像 李华
网站建设 2026/9/24 18:53:56

215类蘑菇图像分类实战:小样本细粒度分类的数据集处理与模型微调

简介&#xff1a;本资源为面向图像分类任务的蘑菇类别识别数据集&#xff0c;适合深度学习入门者、CNN分类网络实践者以及YOLOv5分类模型使用者。数据集共涵盖215种蘑菇类别&#xff0c;包括bay_bolete、brown_birch_bolete、deathcap等&#xff0c;类别字典以json文件形式提供…

作者头像 李华
网站建设 2026/9/24 18:53:36

GAN代码实战:从损失函数到训练调参的完整指南

第一次动手写GAN代码的时候&#xff0c;我卡在了一个现在回头看特别基础的地方&#xff1a;判别器和生成器的损失函数到底该怎么写。原论文那个 max_D min_G 的公式明明没有负号&#xff0c;为什么代码里全是一大串 BCEWithLogitsLoss&#xff1f;后来我花了一个周末把最小可跑…

作者头像 李华
网站建设 2026/9/24 18:52:56

WorkBuddy 十大技能实战:从代码脚手架到跨工具协同的效率提升指南

1. 为什么 WorkBuddy 的技能体系值得认真拆解WorkBuddy 这类工具型产品&#xff0c;最怕的就是“装完即吃灰”。我见过太多人兴冲冲下载、安装、登录&#xff0c;然后对着工作台发呆——不知道从哪下手&#xff0c;也不知道哪些功能真正能省时间。问题不在工具本身&#xff0c;…

作者头像 李华
网站建设 2026/9/24 18:52:47

Spring Boot Maven插件not found报错:原因排查与解决方案

1. 问题现象与初步定位1.1 报错出现的典型场景先说说最常见的踩坑现场。你在IDEA里新建了一个Spring Boot项目&#xff0c;可能是从Spring Initializr生成的&#xff0c;也可能是直接在Maven项目里手动加的依赖。一切看起来都很正常&#xff1a;pom.xml里依赖声明也写了&#x…

作者头像 李华