这篇适合谁
适合想把多模态模型(能同时处理图片、视频和文字)封装成本地接口,供自己的程序调用的开发者。读完你应该能启动 MiniCPM-o 2.6 的 FastAPI 服务,并用 Python 发送单图、多轮对话、多图比较和视频四类请求。
MiniCPM-o 2.6 和这套服务
MiniCPM-o 2.6 是 OpenBMB 的多模态模型,模型可以在 ModelScope 下载,模型页是 modelscope.cn/models/OpenBMB/MiniCPM-o-2_6[2]。本文的服务把它包成一个 FastAPI 应用,客户端只需向一个地址发 JSON 请求[1]。
环境准备
测试环境是 Ubuntu 22.04、Python 3.12.3、CUDA 12.1 和 PyTorch 2.3.0[1]:
----------------
ubuntu 22.04
Python 3.12.3
cuda 12.1
pytorch 2.3.0
----------------先切换到清华 pip 源并安装 modelscope[1]:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip install modelscope==1.20.0依赖有两种装法。一种是下载官方的依赖文件,然后一键安装;依赖文件位于 OpenBMB 的 GitHub 仓库[1]:
pip install -r requirements_o2.6.txt另一种是手动安装,命令如下[1]:
pip install Pillow==10.1.0 torch==2.3.1 torchaudio==2.3.1 torchvision==0.18.1 transformers==4.44.2 sentencepiece==0.2.0 vector-quantize-pytorch==1.18.5 vocos==0.1.0 accelerate==1.2.1 timm==0.9.10 soundfile==0.12.1 librosa==0.9.0 decord moviepy fastapi uvicorn python-multipart装完后要检查是否有漏装或报错[1]。两种方式任选其一即可,不要混装不同版本的依赖,否则容易在启动时出错。
下载模型
模型用 modelscope 的 snapshot_download 下载。第一个参数是模型名称,cache_dir 是下载路径[1]:
from modelscope import snapshot_download
# cache_dir记得修改为自己的目录路径
model_dir = snapshot_download('OpenBMB/MiniCPM-o-2_6', cache_dir='/root/autodl-tmp', revision='master')代码里的 cache_dir 要改成你自己的目录[1]。
启动 FastAPI 服务
服务端的应用只有一个 POST 路由 /,读取 JSON 请求体[1]。请求体里有 prompt,可选的 video_path,以及 history 消息列表[1]。服务端把 history 里的 base64 图片解码成 RGB 图像;如果解码失败,会打印错误并跳过这张图[1]。
视频要先用 decord 读取,大约每秒取一帧;帧数超过 MAX_NUM_FRAMES 时,改为均匀采样[1]:
MAX_NUM_FRAMES = 64 # 视频处理的最大帧数,如果显存不足可以设置更小的值调用模型时,use_image_id 设为 False,max_slice_nums 设为 2。注释里提示,显存不足且视频分辨率高于 448×448 时,可以把它改为 1[1]:
"max_slice_nums": 2 # 如果显存不足且视频分辨率>448*448时使用1每次请求结束后,服务会清空 CUDA 缓存[1]。返回结果包含 response、status(成功时为 200)和 time;出错时返回 error 信息和状态码 500[1]。服务还会把时间、提示和回答打印到日志中[1]。
入口处加载模型和分词器,然后在 6006 端口启动 uvicorn[1]。workers=1 表示只启动一个工作进程,所有请求都由同一份已加载的模型处理[1]:
if __name__ == '__main__':
# 设置随机种子
torch.manual_seed(1000)
# 加载模型和分词器
model = AutoModel.from_pretrained(
'autodl-tmp/OpenBMB/MiniCPM-o-2_6', # 替换为自己的具体路径
trust_remote_code=True,
attn_implementation='sdpa',
torch_dtype=torch.bfloat16
)
model = model.eval().cuda() # 将模型设置为评估模式并移到GPU
tokenizer = AutoTokenizer.from_pretrained(
'autodl-tmp/OpenBMB/MiniCPM-o-2_6', # 替换为自己的具体路径
trust_remote_code=True
)
# 启动FastAPI服务器
uvicorn.run(app, host='0.0.0.0', port=6006, workers=1)把两处 autodl-tmp/OpenBMB/MiniCPM-o-2_6 改成你自己下载的模型路径,再启动服务[1]:
# cd到自己存放代码的文件的路径,如 cd /root/autodl-tmp
python api_server.py启动成功后,服务默认部署在 6006 端口[1]。
单张图片,单轮对话
客户端的 send_request 向 http://localhost:6006 发送 JSON。状态为 200 时打印回答,否则打印错误[1]:
def send_request(data):
"""发送请求并处理响应"""
response = requests.post("http://localhost:6006", json=data)
try:
result = response.json()
if result.get('status') == 200:
print(f"MiniCPM-o: {result.get('response')}")
else:
print(f"错误: {result.get('error')}")
except Exception as e:
print(f"解析响应时出错: {str(e)}")
print(f"原始响应: {response.text}")读取本地图片时,把图片编码成 base64 的 data URI[1]:
with open("autodl-tmp/input/1-01.jpg", 'rb') as f: # 注意修改为自己输入图片的存放路径
image_base64 = f"data:image/jpeg;base64,{base64.b64encode(f.read()).decode('utf-8')}"图片的 data URI 和问题一起放在 history 中一条 user 消息的 content 列表里[1]。
单张图片,多轮对话
第一轮得到回答后,把回答追加到消息列表,再加上下一个问题,整个列表一起发送[1]。history 里要保留之前的 user 和 assistant 消息,模型才能接着上文回答。
msgs.append({'role': 'assistant', 'content': [first_response]})多张图片比较
多张图片可以放进同一条 user 消息,和问题一起发送。示例中有两张图,分别读取后都放进 content 列表,问题放在最后[1]:
with open("autodl-tmp/input/1-02.jpg", 'rb') as f: # 在这里修改
image2_base64 = f"data:image/jpeg;base64,{base64.b64encode(f.read()).decode('utf-8')}"视频输入
视频请求把 video_path 设为本地的 .mp4 文件路径。发送前先检查文件是否存在[1]:
video_path = os.path.join(os.path.expanduser("~"), "autodl-tmp", "input", "1-04.mp4") # 在这里修改下一步
模型的更多细节可以在 ModelScope 的模型页查看[2],依赖版本以官方 requirements 文件为准[1]。遇到问题时,可以先看服务端终端的报错,以及服务端为每次请求打印的时间、提示和回答,再对照上面的路径和依赖逐项检查[1]。
本文改编自 Datawhale 开源项目 self-llm 中的教程《MiniCPM-o 2.6 FastApi部署调用》[1],原文以 Apache-2.0 许可证发布。
来源
- 1MiniCPM-o 2.6 FastApi部署调用Datawhale self-llm (Apache-2.0)
- 2MiniCPM-o-2_6 · 模型库ModelScope
引用本页: MiniCPM-o 多模态模型部署调用. TellWorld, https://www.tellworld.net/zh/practice/practice-minicpm-o-fastapi. 更新于 2026-11-14