Skip to main content

MiniCPM-V 4.7

MiniCPM-V Multimodal Series

把模型接入自己的服务:vLLM 与 SGLang 面向高吞吐的 GPU 服务,llama.cpp 与 Ollama 面向本地与端侧运行。按硬件与场景选择其一,本页给出各自的安装、启动与调用步骤。

MiniCPM-V 4.7 提供两个尺寸,各框架均通过切换模型路径使用:

框架状态适用场景
vLLM上游已支持(PR #58674)高吞吐 GPU 服务
SGLang走 fork tc-mb/sglang,上游 PR 进行中高吞吐 GPU 服务
llama.cpp上游已支持(PR #29416)本地 CPU / Metal
Ollama模型代码已就绪,运行时待内置 llama.cpp 同步本地快速体验
共同前提

MiniCPM-V 4.7 注册为 MiniCPMV4_7ForConditionalGeneration,需 transformers >= 5.18.0,各框架均无需 trust_remote_code。MiniCPM-V 4.7 使用 Qwen3.5 词表,stop token 为 [248044, 248046](MiniCPM-V 4.5 是 [1, 151645])。

vLLM​

MiniCPM-V 4.7 已在 PR #58674 合入官方 vLLM main。无需 fork —— 从上游安装即可,确保 checkout 在该提交之后。

环境准备​

Bash
# 新建干净的 conda 环境
conda create -n vllm-v47 python=3.10 -y
conda activate vllm-v47

# 从上游 main 安装(需 CUDA toolkit;HEAD 需含 #58674)
git clone https://github.com/vllm-project/vllm.git
cd vllm
MAX_JOBS=6 VLLM_USE_PRECOMPILED=1 pip install --editable . -v

一旦含 #58674 的 vLLM 正式版发布,pip install -U vllm 即可,无需编译。

视频推理需安装视频模块:

Bash
pip install vllm[video]

验证安装:

Bash
python -c "import vllm, transformers; print('vllm', vllm.__version__, '| transformers', transformers.__version__)"

启动 API 服务​

Bash
vllm serve <model_path> \
--dtype auto \
--max-model-len 8192 \
--api-key token-abc123 \
--gpu_memory_utilization 0.9 \
--max-num-batched-tokens 8192
  • <model_path>:本地路径,或 openbmb/MiniCPM-V-4.7-1B / openbmb/MiniCPM-V-4.7-35B-A3B。
  • --api-key:API 访问密钥。
  • --max-model-len:最大上下文长度(MiniCPM-V 4.7 支持到 256K,按显存先设小)。
  • --gpu_memory_utilization:显存利用率。

图片推理​

Python
from openai import OpenAI
import base64

openai_api_key = "token-abc123" # 需与 vllm serve 传入的一致
openai_api_base = "http://localhost:8000/v1"
client = OpenAI(api_key=openai_api_key, base_url=openai_api_base)

with open('./assets/airplane.jpeg', 'rb') as file:
image = "data:image/jpeg;base64," + base64.b64encode(file.read()).decode('utf-8')

chat_response = client.chat.completions.create(
model="<model_path>",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "请描述这张图片"},
{"type": "image_url", "image_url": {"url": image}},
],
}],
extra_body={
# 4.7 使用 Qwen3.5 词表,stop token 与 4.6 相同
"stop_token_ids": [248044, 248046],
# 关闭 <think> 块以获得直答
"chat_template_kwargs": {"enable_thinking": False},
}
)
print(chat_response.choices[0].message.content)

视频推理​

Python
from openai import OpenAI
import base64

openai_api_key = "token-abc123"
openai_api_base = "http://localhost:8000/v1"
client = OpenAI(api_key=openai_api_key, base_url=openai_api_base)

with open('./videos/video.mp4', 'rb') as video_file:
video_base64 = base64.b64encode(video_file.read()).decode('utf-8')

chat_response = client.chat.completions.create(
model="<model_path>",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{
"role": "user",
"content": [
{"type": "text", "text": "请描述这段视频"},
{"type": "video_url", "video_url": {"url": f"data:video/mp4;base64,{video_base64}"}},
],
},
],
extra_body={"stop_token_ids": [248044, 248046]},
)
print(chat_response.choices[0].message.content)

调整单视频帧切片预算:

Python
extra_body = {
"stop_token_ids": [248044, 248046],
"mm_processor_kwargs": {"max_slice_nums": 2},
}

多图 / 多视频​

启动时提高 --limit-mm-per-prompt 预算:

Bash
# 单请求最多 5 图 + 2 视频
vllm serve <model_path> --dtype auto --max-model-len 16384 --api-key token-abc123 \
--gpu_memory_utilization 0.9 \
--limit-mm-per-prompt '{"image": 5, "video": 2}'

离线推理​

Python
from transformers import AutoProcessor
from PIL import Image
from vllm import LLM, SamplingParams

MODEL_NAME = "<model_path>" # 或 "openbmb/MiniCPM-V-4.7-1B"
image = Image.open("./assets/airplane.jpeg").convert("RGB")

processor = AutoProcessor.from_pretrained(MODEL_NAME)
llm = LLM(
model=MODEL_NAME,
max_model_len=8192,
disable_mm_preprocessor_cache=True,
limit_mm_per_prompt={"image": 5},
)

messages = [{
"role": "user",
"content": [
{"type": "image"},
{"type": "text", "text": "请描述这张图片的内容"},
],
}]
prompt = processor.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)

inputs = {"prompt": prompt, "multi_modal_data": {"image": image}}
sampling_params = SamplingParams(
stop_token_ids=[248044, 248046],
temperature=0.7,
top_p=0.8,
max_tokens=1024,
)

outputs = llm.generate(inputs, sampling_params=sampling_params)
print(outputs[0].outputs[0].text)

注意事项​

  1. 显存:1B 单张消费级卡即可;35B-A3B(bf16 约 70 GB)需多卡或 4-bit 权重(-AWQ / -GPTQ / -FP8 / -INT4)。按硬件调 --gpu_memory_utilization / --max-model-len / --max-num-batched-tokens。
  2. 多模态上限:多图 / 多视频会话用 --limit-mm-per-prompt。

SGLang​

MiniCPM-V 4.7 暂未合入上游 SGLang。请使用 fork tc-mb/sglang 的 Support-MiniCPM-V4.7 分支。上游 PR 进行中,合入后可直接安装 SGLang main。

安装​

Bash
git clone -b Support-MiniCPM-V4.7 https://github.com/tc-mb/sglang.git
cd sglang

pip install --upgrade pip
pip install -e "python[all]"

验证环境:

Bash
python -c "import torch, transformers; print('torch', torch.__version__, '| cuda', torch.version.cuda, '| transformers', transformers.__version__)"

安装 FlashInfer(可选,推荐)​

FlashInfer 的 wheel 与特定 (torch, cuda) 组合绑定。请选择与上面刚验证过的 torch + CUDA 匹配的索引 —— 不要盲目照抄 cu121/torch2.4 这类 URL。

通用索引见 flashinfer.ai/whl,例如:

你的 torch / CUDA索引 URL
torch 2.7 + CUDA 12.8https://flashinfer.ai/whl/cu128/torch2.7/
Bash
pip install flashinfer-python -i <上表对应索引 URL>

Docker 镜像与纯 CPU 回退见 SGLang 官方安装文档。

启动推理服务​

Bash
# 1B
python -m sglang.launch_server --model-path openbmb/MiniCPM-V-4.7-1B --port 30000 --dtype bfloat16

# 35B-A3B(需大显存节点;用 --tp-size 跨卡分片)
python -m sglang.launch_server --model-path openbmb/MiniCPM-V-4.7-35B-A3B --port 30000 --dtype bfloat16 --tp-size 2

或指定本地路径:

Bash
python -m sglang.launch_server --model-path /your/local/MiniCPM-V-4.7-1B --port 30000 --dtype bfloat16

调用服务​

curl:

Bash
curl -s http://localhost:30000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "MiniCPM-V-4.7-1B",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "What is in this image?"},
{
"type": "image_url",
"image_url": {
"url": "https://github.com/OpenSQZ/MiniCPM-V-CookBook/blob/main/inference/assets/airplane.jpeg?raw=true"
}
}
]
}
],
"max_tokens": 300,
"top_k": -1
}'

Python(OpenAI 客户端):

Python
from openai import OpenAI

client = OpenAI(base_url="http://localhost:30000/v1", api_key="None")

response = client.chat.completions.create(
model="MiniCPM-V-4.7-1B",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "What is in this image?"},
{
"type": "image_url",
"image_url": {
"url": "https://github.com/OpenSQZ/MiniCPM-V-CookBook/blob/main/inference/assets/airplane.jpeg?raw=true",
},
},
],
}
],
max_tokens=300,
extra_body={"top_k": -1, "stop_token_ids": [248044, 248046]},
)

print(response.choices[0].message.content)
  • 若 image_url 本机不可达,换成本地路径 / base64 data URL。
  • 若模型在答案后继续输出,传入 stop_token_ids = [248044, 248046]。
  • 如需关闭 <think> 块,传 chat_template_kwargs={"enable_thinking": false}(或服务端等价默认值)。

llama.cpp​

MiniCPM-V 4.7 已合入官方 llama.cpp(PR #29416)。请使用该 PR 之后(含)的 checkout 构建。

GGUF 格式变化

MiniCPM-V 4.7 使用 canvas M-RoPE,新增了 GGUF 元数据键(rope.section_order)与 mmproj 张量(v.tok_embd_sep)。用旧版 convert_hf_to_gguf.py 转出的 GGUF,在新构建里会加载成功但 M-RoPE 计算错误(或因缺 mmproj 张量直接失败)。请始终使用官方 MiniCPM-V 4.7 GGUF,或用当前脚本重新转换。

每个尺寸使用对应的一套 GGUF:

尺寸LLM 文件mmproj
1BMiniCPM-V-4_7-1B-Q4_K_M.ggufmmproj-model-f16.gguf
35B-A3BMiniCPM-V-4_7-35B-A3B-Q4_K_M.ggufmmproj-model-f16.gguf

构建 llama.cpp​

Bash
git clone https://github.com/ggml-org/llama.cpp.git
cd llama.cpp

用 CMake 构建(详见 build 文档):

Bash
# CPU / Metal
cmake -B build
cmake --build build --config Release

# CUDA
cmake -B build -DGGML_CUDA=ON
cmake --build build --config Release

获取 GGUF 文件​

下载官方 GGUF(语言模型 GGUF 与视觉投影 mmproj):

每个仓库提供完整的 K-quant 档位(F16、Q8_0、Q6_K、Q5_K_M、Q5_K_S、Q5_1、Q5_0、Q4_K_M、Q4_K_S、Q4_1、Q4_0)以及两个 mmproj(mmproj-model-f16.gguf、mmproj-model-f16-4x.gguf)。35B-A3B 仓库额外提供 mix_q3gud_im(14.4 GiB 的 imatrix 混合量化,推荐用于显存受限设备)。

也可以从 PyTorch 权重自行转换,步骤见量化。

模型推理​

近期 llama.cpp 默认 --reasoning 为 auto,会依据对话模板开启思考。MiniCPM-V 4.7 模板默认开启思考,因此普通问答请显式传 --reasoning off。

Bash
cd build/bin/

# F16 权重(1B)
./llama-mtmd-cli \
-m /path/to/MiniCPM-V-4.7-1B/MiniCPM-V-4_7-1B-F16.gguf \
--mmproj /path/to/MiniCPM-V-4.7-1B/mmproj-model-f16.gguf \
-c 8192 --temp 0.7 --top-p 0.8 --top-k 100 --repeat-penalty 1.05 \
--reasoning off \
--image xx.jpg -p "What is in the image?"

# 量化 INT4 权重(35B-A3B)
./llama-mtmd-cli \
-m /path/to/MiniCPM-V-4.7-35B-A3B/MiniCPM-V-4_7-35B-A3B-Q4_K_M.gguf \
--mmproj /path/to/MiniCPM-V-4.7-35B-A3B/mmproj-model-f16.gguf \
-c 8192 --temp 0.7 --top-p 0.8 --top-k 100 --repeat-penalty 1.05 \
--reasoning off \
--image xx.jpg -p "What is in the image?"

# 交互模式
./llama-mtmd-cli \
-m /path/to/MiniCPM-V-4.7-1B/MiniCPM-V-4_7-1B-Q4_K_M.gguf \
--mmproj /path/to/MiniCPM-V-4.7-1B/mmproj-model-f16.gguf \
-c 8192 --temp 0.7 --top-p 0.8 --top-k 100 --repeat-penalty 1.05 \
--reasoning off \
--image xx.jpg -i

开启思考(重 OCR / 推理任务)用 --reasoning on(--jinja 默认已开):

Bash
./llama-mtmd-cli \
-m /path/to/MiniCPM-V-4.7-1B/MiniCPM-V-4_7-1B-Q4_K_M.gguf \
--mmproj /path/to/MiniCPM-V-4.7-1B/mmproj-model-f16.gguf \
-c 8192 --image xx.jpg --jinja --reasoning on -p "What is in the image?"

参数参考:

参数说明
-m, --model语言模型 GGUF 路径
--mmproj视觉投影 GGUF 路径
--image输入图片路径
-p, --prompt提示词
-c, --ctx-size最大上下文长度
-rea, --reasoning [on|off|auto]是否开启思考。默认 auto(读模板)。普通问答用 off
--jinja使用模型 Jinja 对话模板(近期构建默认开启)

Ollama​

Ollama 的模型代码已识别 MiniCPM-V 4.7(convert_minicpmv.go),但其内置的 llama.cpp 必须先同步到 PR #29416 才能加载 MiniCPM-V 4.7 的 GGUF(canvas M-RoPE 新格式引入了 rope.section_order 与 mmproj 张量 v.tok_embd_sep)。在此之前,对 MiniCPM-V 4.7 GGUF 执行 ollama create / ollama run 会失败。可先用较新的 llama.cpp,或等待内置引擎更新后的 Ollama 正式版。

安装 Ollama​

  • macOS:Ollama.dmg
  • Windows:OllamaSetup.exe
  • Linux:curl -fsSL https://ollama.com/install.sh | sh
  • Docker:Docker Hub 上的 ollama/ollama

从注册表运行​

待内置引擎更新的正式版发布后,从 Ollama 注册表拉取官方模型:

Bash
ollama run openbmb/minicpm-v4.7

命令行中,提示词与图片路径用空格分隔:

Plain Text
What is in the picture? xx.jpg

API 调用:

Python
import base64, requests

with open("xx.jpg", "rb") as image_file:
encoded_string = base64.b64encode(image_file.read()).decode("utf-8")

data = {
"model": "openbmb/minicpm-v4.7",
"prompt": "What is in the picture?",
"stream": False,
"images": [encoded_string], # 可放多张 base64 图片
}
response = requests.post("http://localhost:11434/api/generate", json=data)

加载本地 GGUF​

要加载本地 GGUF(如自定义量化或指定尺寸),需创建一个 Modelfile。

Bash
vim minicpmv4.7.Modelfile

Modelfile 内容(1B 示例):

Plain Text
FROM ./MiniCPM-V-4.7-1B-gguf/MiniCPM-V-4_7-1B-Q4_K_M.gguf
FROM ./MiniCPM-V-4.7-1B-gguf/mmproj-model-f16.gguf

TEMPLATE """{{- if .Messages }}{{- range $i, $_ := .Messages }}{{- $last := eq (len (slice $.Messages $i)) 1 -}}<|im_start|>{{ .Role }}{{ .Content }}{{- if $last }}{{- if (ne .Role "assistant") }}<|im_end|><|im_start|>assistant{{ end }}{{- else }}<|im_end|>{{ end }}{{- end }}{{- else }}{{- if .System }}<|im_start|>system{{ .System }}<|im_end|>{{ end }}{{ if .Prompt }}<|im_start|>user{{ .Prompt }}<|im_end|>{{ end }}<|im_start|>assistant{{ end }}{{ .Response }}{{ if .Response }}<|im_end|>{{ end }}"""

SYSTEM """You are a helpful assistant."""

PARAMETER top_p 0.8
PARAMETER num_ctx 8192
PARAMETER stop ["<|im_start|>", "<|im_end|>"]
PARAMETER temperature 0.7
第一个 FROM第二个 FROMnum_ctx
语言模型 GGUF 路径视觉投影 GGUF 路径最大上下文长度

35B-A3B 时,把第一个 FROM 改为 MiniCPM-V-4.7-35B-A3B-gguf/MiniCPM-V-4_7-35B-A3B-Q4_K_M.gguf。

创建并运行:

Bash
ollama create minicpm-v4.7 -f minicpmv4.7.Modelfile
ollama run minicpm-v4.7

说明​

  • 模板:MiniCPM-V 4.7 的 chat_template.jinja 与 MiniCPM-V 4.6 逐字节相同,故上面的 TEMPLATE 与 openbmb/minicpm-v4.6 所用一致。
  • 不设 RENDERER:与官方 openbmb/minicpm-v4.6 一致(family qwen35、无 renderer 字段),Ollama 走 native 模式,使用 GGUF 内嵌对话模板 + mmproj。
  • 思考:模板默认开启;如需直答,可通过请求传 enable_thinking: false(或改用支持 chat_template_kwargs 的运行时)。