系列篇章💥
No. | 文章 |
---|---|
1 | MiniCPM-V 2.6:端侧最强多模态大模型探索【本地部署实践】 |
2 | MiniCPM-V 2.6:端侧最强多模态大模型探索【推理实战大全】 |
3 | MiniCPM-V 2.6:端侧最强多模态大模型探索【微调实战体验】 |
目录
前言
在当今人工智能飞速发展的时代,强大的多态大模型不断涌现,为各个领域带来了前所未有的机遇和挑战。MiniCPM-V 2.6 作为一款备受瞩目的多态大模型,以其卓越的性能和广泛的适用性,成为了众多开发者和研究者关注的焦点。
MiniCPM-V 2.6 支持多种部署推理方案,包括 vllm、llama.cpp、Ollama、transformers 等。这些方案各有特点,能够满足不同用户的需求。本文将主要聚焦于 vllm和llama.cpp 这两种推理方案的体验实践,为大家展示 MiniCPM-V 2.6 在不同部署环境下的强大功能。
一、Vllm 部署推理
Vllm 是一种高效的推理框架,具有出色的性能和可扩展性,能够快速处理大规模的推理任务,为用户提供高效、稳定的推理服务;它能够充分发挥 MiniCPM-V 2.6 的性能优势。
在实际应用中,Vllm 部署推理具有以下优点:
1)高效性:Vllm 能够充分利用硬件资源,提高推理速度,减少响应时间。
2)灵活性:Vllm 支持多种模型格式和推理任务,可以根据不同的需求进行定制化配置。
3)可扩展性:Vllm 可以轻松地与其他软件和系统进行集成,实现更复杂的应用场景。
在进行 Vllm 部署推理时,首先需要进行一系列的准备工作,包括安装必要的软件和库,配置环境变量等。
接下来,我们可以按照以下步骤进行 Vllm 部署推理:
1、下载模型
下载 MiniCPM-V 2.6 的模型文件,并将其放置在合适的位置。
参考前面篇章《MiniCPM-V 2.6:端侧最强多模态大模型探索之本地部署实践》
2、安装 Vllm 框架
官方要求vLLM版本0.5.4)以上
pip install vllm
3、vllm部署推理
from transformers import AutoTokenizer # 导入Hugging Face的AutoTokenizer,用于自动加载与模型匹配的tokenizer
from PIL import Image # 导入Python Imaging Library,用于图像处理
from vllm import LLM, SamplingParams # 导入自定义的LLM类和SamplingParams类,用于生成文本
# 定义模型的路径,这里指定了本地模型的存储路径
MODEL_NAME = "/root/autodl-tmp/OpenBMB/MiniCPM-V-2_6"
# 下面两行是注释掉的其他模型的路径,可以在需要时取消注释使用
# MODEL_NAME = "openbmb/MiniCPM-Llama3-V-2_5"
# MODEL_NAME = "HwwwH/MiniCPM-V-2"
# 使用PIL库打开图像文件,并转换为RGB模式
image = Image.open("/root/autodl-tmp/MiniCPM-V/assets/airplane.jpeg").convert("RGB")
# 初始化tokenizer,指定模型路径,并允许加载远程代码
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
# 初始化LLM对象,用于加载模型并进行文本生成
llm = LLM(
model=MODEL_NAME,
trust_remote_code=True,
gpu_memory_utilization=1, # 设置GPU内存利用率为100%
max_model_len=2048 # 设置模型能处理的最大长度
)
# 准备输入的消息,这里使用了一个模板字符串来提示模型处理图像
messages = [{
"role": "user", # 指定角色为用户
"content":
# 模板字符串指示模型期待图像数据
"(<image>./</image>)" + \
"\n这张图片的内容是什么?" # 提问图像内容是什么
}]
# 使用tokenizer的apply_chat_template方法来准备prompt,设置不进行tokenize处理,并添加生成文本的提示
prompt = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
# 准备输入字典,用于单次推理
inputs = {
"prompt": prompt, # 提供prompt
"multi_modal_data": { # 提供多模态数据,这里是图像
"image": image
# 如果有多张图像,可以在这里添加,数量需与模板中的(<image>./</image>)标记匹配
# "image": [image, image]
},
}
# 注释掉的代码是批量推理的示例
# 为2.6版本设置结束标记,将这些标记的ID添加到停止token列表
stop_tokens = ['<|im_end|>', '<|endoftext|>']
stop_token_ids = [tokenizer.convert_tokens_to_ids(i) for i in stop_tokens]
# 下面三行是针对不同版本的模型设置结束token的注释掉的代码
# 2.0版本
# stop_token_ids = [tokenizer.eos_id]
# 2.5版本
# stop_token_ids = [tokenizer.eos_id, tokenizer.eot_id]
# 创建SamplingParams对象,设置采样参数
sampling_params = SamplingParams(
stop_token_ids=stop_token_ids, # 设置停止token的ID
use_beam_search=True, # 使用束搜索
temperature=0, # 设置采样温度,值为0表示贪婪采样
best_of=3, # 从多个候选中选择最佳结果的数量
max_tokens=1024 # 设置生成的最大token数量
)
# 使用llm对象的generate方法进行文本生成,传入inputs和sampling_params
outputs = llm.generate(inputs, sampling_params=sampling_params)
# 打印生成的文本结果
print(outputs[0].outputs[0].text)
输出:
4、部署API服务
1)发布API服务
执行以下指令发布OpenAI 风格的API服务
vllm serve /root/autodl-tmp/OpenBMB/MiniCPM-V-2_6 --dtype auto --max-model-len 2048 --api-key token-abc123 --gpu_memory_utilization 1 --trust-remote-code
启动成功如下:
2)网络图片推理
使用网络图片,调用API接口推理测试
from openai import OpenAI
openai_api_key = "token-abc123" # your api key set in launch server
openai_api_base = "http://localhost:8000/v1" # http id
client = OpenAI(
api_key=openai_api_key,
base_url=openai_api_base,
)
chat_response = client.chat.completions.create(
model="/root/autodl-tmp/OpenBMB/MiniCPM-V-2_6", # model_local_path or huggingface id
messages=[{
"role": "user",
"content": [
# NOTE: 使用图像令牌 <image> 的提示格式是不必要的,因为提示将由API服务器自动处理。
# 由于提示将由API服务器自动处理,因此不需要使用包含 <image> 图像令牌的提示格式。
{"type": "text", "text": "请描述这张图片"},
{
"type": "image_url",
"image_url": {
"url": "https://air-example-data-2.s3.us-west-2.amazonaws.com/vllm_opensource_llava/stop_sign.jpg",
},
},
],
}],
extra_body={
"stop_token_ids": [151645, 151643]
}
)
print("Chat response:", chat_response)
print("Chat response content:", chat_response.choices[0].message.content)
执行输出如下:
Chat response: ChatCompletion(id='chat-d917b1605e814f5db390f83abe5009ec', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='这张图片展示了一个城市街景,其中一个东亚风格的牌楼,可能代表着一个唐人街,鉴于牌楼和街牌上的汉字。牌楼是红色的,顶部有弯曲的檐口,门楣上装饰着中文字符。在牌楼的左侧,有一个坚固的雕塑狮子,这是唐人街入口的传统饰物。牌楼的背后,可以看到各种商店,包括一家标有“中华门”字样的商店,表明牌楼的名称。在前景,有一个红色的停车标志,安装在一个柱子上,柱子的顶部有一个装饰性的顶饰。街道上有一辆黑色SUV正在驶过,背景中可以看到行人。天气晴朗,地面上投下的阴影表明照片是在太阳照射的时候拍摄的。', refusal=None, role='assistant', function_call=None, tool_calls=[]), stop_reason=None)], created=1724158010, model='/root/autodl-tmp/OpenBMB/MiniCPM-V-2_6', object='chat.completion', service_tier=None, system_fingerprint=None, usage=CompletionUsage(completion_tokens=159, prompt_tokens=490, total_tokens=649))
Chat response content: 这张图片展示了一个城市街景,其中一个东亚风格的牌楼,可能代表着一个唐人街,鉴于牌楼和街牌上的汉字。牌楼是红色的,顶部有弯曲的檐口,门楣上装饰着中文字符。在牌楼的左侧,有一个坚固的雕塑狮子,这是唐人街入口的传统饰物。牌楼的背后,可以看到各种商店,包括一家标有“中华门”字样的商店,表明牌楼的名称。在前景,有一个红色的停车标志,安装在一个柱子上,柱子的顶部有一个装饰性的顶饰。街道上有一辆黑色SUV正在驶过,背景中可以看到行人。天气晴朗,地面上投下的阴影表明照片是在太阳照射的时候拍摄的。
3)本地图片推理
使用本地的图片,调用API接口推理测试
import base64
from openai import OpenAI
openai_api_key = "token-abc123" # your api key set in launch server
openai_api_base = "http://localhost:8000/v1" # http id
client = OpenAI(
api_key=openai_api_key,
base_url=openai_api_base,
)
# 用于传本地图片
with open('/root/autodl-tmp/MiniCPM-V/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="/root/autodl-tmp/OpenBMB/MiniCPM-V-2_6", # model_local_path or huggingface id
messages=[{
"role": "user",
"content": [
# NOTE: 使用图像令牌 <image> 的提示格式是不必要的,因为提示将由API服务器自动处理。
# 由于提示将由API服务器自动处理,因此不需要使用包含 <image> 图像令牌的提示格式。
{"type": "text", "text": "请描述这张图片"},
{
"type": "image_url",
"image_url": {
"url": image,
},
},
],
}],
extra_body={
"stop_token_ids": [151645, 151643]
}
)
print("Chat response:", chat_response)
print("Chat response content:", chat_response.choices[0].message.content)
执行输出如下:
Chat response: ChatCompletion(id='chat-8716c725a70e4cca8b6bc7f050b4ebcf', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='这张图片展示了一架商用客机在晴朗的蓝天中飞行。这是一架大型双发喷气飞机,机身主要为白色,中间有一条蓝色和金色的条纹,尾翼为鲜艳的蓝色,上面有一个红色的标志。飞机的注册编号清晰可见,机身侧面还印有中文字符。飞机略微朝向观看者,展示了其右翼、起落架和发动机。飞机的起落架已经伸出,表明它正在起飞或降落。背景中没有其他物体,突出了飞机在空中的孤独感。', refusal=None, role='assistant', function_call=None, tool_calls=[]), stop_reason=None)], created=1724158190, model='/root/autodl-tmp/OpenBMB/MiniCPM-V-2_6', object='chat.completion', service_tier=None, system_fingerprint=None, usage=CompletionUsage(completion_tokens=118, prompt_tokens=689, total_tokens=807))
Chat response content: 这张图片展示了一架商用客机在晴朗的蓝天中飞行。这是一架大型双发喷气飞机,机身主要为白色,中间有一条蓝色和金色的条纹,尾翼为鲜艳的蓝色,上面有一个红色的标志。飞机的注册编号清晰可见,机身侧面还印有中文字符。飞机略微朝向观看者,展示了其右翼、起落架和发动机。飞机的起落架已经伸出,表明它正在起飞或降落。背景中没有其他物体,突出了飞机在空中的孤独感。
二、llama.cpp 部署推理
llama.cpp 是另一种流行的推理框架,具有无需额外依赖可直接编译出可执行文件,它以其简洁高效的特点受到了广泛的关注。
llama.cpp 部署推理具有以下优势:
1)轻量级:llama.cpp 框架体积小,占用资源少,适合在资源受限的环境下使用。
2)易于使用:llama.cpp 的安装和配置相对简单,对于初学者来说比较友好。
3)高性能:尽管 llama.cpp 是一个轻量级框架,但它在推理性能方面表现出色,能够满足大多数应用场景的需求。
在进行 llama.cpp 部署推理时,我们可以按照以下步骤进行操作:
设备要求:运行非量化版内存超过19g,运行量化版超过8g内存
1、下载依赖包
sudo apt update
sudo apt install ffmpeg
sudo apt install pkg-config
2、下载llama.cpp
获取openbmb的llama.cpp分支
git clone -b minicpmv-main https://github.com/OpenBMB/llama.cpp.git
下载完成如下:
编译llama.cpp
cd llama.cpp
make
3、获取gguf文件
1)使用llama.cpp将模型权重转化为gguf文件
注意
:在llama.cpp目录下执行,下面参数中./OpenBMB/MiniCPM-V-2_6为模型的相对地址;
第一步:获得模型中间输出,为转换为gguf作准备
# 1、获得模型中间输出,为转换为gguf作准备
python ./examples/llava/minicpmv-convert/minicpmv2_6-surgery.py -m ../OpenBMB/MiniCPM-V-2_6
执行如下:
第二步:将siglip模型转换为gguf
提前安装gguf:pip install gguf
# 2、将siglip模型转换为gguf
python ./examples/llava/minicpmv-convert/minicpmv2_6-convert-image-encoder-to-gguf.py -m ../OpenBMB/MiniCPM-V-2_6 --minicpmv-projector ../OpenBMB/MiniCPM-V-2_6/minicpmv.projector --output-dir ../OpenBMB/MiniCPM-V-2_6/ --image-mean 0.5 0.5 0.5 --image-std 0.5 0.5 0.5
执行输出如下:
第三步:将语言模型转换为gguf
# 3、将语言模型转换为gguf
python ./convert-hf-to-gguf.py ../OpenBMB/MiniCPM-V-2_6/model
执行完成如下:
如果需要的话,对语言模块进行量化:
# quantize int4 version
./llama-quantize ../OpenBMB/MiniCPM-V-2_6/model/ggml-model-f16.gguf ../OpenBMB/MiniCPM-V-2_6/model/ggml-model-Q4_K_M.gguf Q4_K_M
2)直接下载gguf模型文件
也可以直接前往[MiniCPM-V 2.6-gguf](https://huggingface.co/openbmb/MiniCPM-V-2_6-gguf/tree/main)下载模型,ggml-model-Q4_K_M.gguf(量化版)和ggml-model-f16.gguf。
4、开始推理
1 )图片推理
# 运行f16 版本
./llama-minicpmv-cli -m ../OpenBMB/MiniCPM-V-2_6/model/ggml-model-f16.gguf --mmproj ../OpenBMB/MiniCPM-V-2_6/mmproj-model-f16.gguf -c 4096 --temp 0.7 --top-p 0.8 --top-k 100 --repeat-penalty 1.05 --image /root/autodl-tmp/MiniCPM-V/assets/airplane.jpeg -p "这张图片中有什么?"
推理结果如下:
注意:如果需要运行量化版本,参考如下:
# 运行int4量化版本
./llama-minicpmv-cli -m ../OpenBMB/MiniCPM-V-2_6/model/ggml-model-Q4_K_M.gguf --mmproj ../OpenBMB/MiniCPM-V-2_6/mmproj-model-f16.gguf -c 4096 --temp 0.7 --top-p 0.8 --top-k 100 --repeat-penalty 1.05 --image /root/autodl-tmp/MiniCPM-V/assets/airplane.jpeg -p "这张图片中有什么?"
2 )视频推理
./llama-minicpmv-cli -m ../OpenBMB/MiniCPM-V-2_6/model/ggml-model-f16.gguf --mmproj ../OpenBMB/MiniCPM-V-2_6/mmproj-model-f16.gguf -c 8192 --temp 0.7 --top-p 0.8 --top-k 100 --repeat-penalty 1.05 --video /root/autodl-tmp/test-video.mp4 -p "我接下来会给你一个视频,请告诉我视频中描述了什么"
输出如下:
注意:如果需要运行量化版本,参考如下:
# 运行int4量化版本
./llama-minicpmv-cli -m ../OpenBMB/MiniCPM-V-2_6/model/ggml-model-Q4_K_M.gguf --mmproj ../OpenBMB/MiniCPM-V-2_6/mmproj-model-f16.gguf -c 8192 --temp 0.7 --top-p 0.8 --top-k 100 --repeat-penalty 1.05 --video /root/autodl-tmp/test-video.mp4 -p "我接下来会给你一个视频,请告诉我视频中描述了什么"
参数说明
下面是命令中每个参数的具体解释:
./llama-minicpmv-cli
:这是要执行的命令行工具的路径,位于llama.cpp目录下。-m ../OpenBMB/MiniCPM-V-2_6/model/ggml-model-Q4_K_M.gguf
:-m
参数指定了主模型文件的路径。ggml-model-Q4_K_M.gguf
是模型的二进制文件,其中Q4_K_M
表示模型经过了特定的量化处理,以优化内存使用和推理速度。(也可以是为量化模型)--mmproj ../OpenBMB/MiniCPM-V-2_6/mmproj-model-f16.gguf
:--mmproj
参数指定了多模态(例如图像或视频)投影模型文件的路径。这个文件包含了模型处理非文本输入所需的参数,f16
表示使用了半精度浮点数(float16)。-c 8192
:-c
参数设置了上下文长度,即模型一次能够处理的 token 的最大数量。这里设置为 8192,意味着模型可以处理最多 8192 个 token。--temp 0.7
:--temp
参数设置了采样温度,0.7 是一个较低的值,表示生成文本时会倾向于更确定、更一致的结果。--top-p 0.8
:--top-p
参数用于控制 nucleus sampling 策略中的累积概率阈值,0.8 表示只有累积概率最高的 80% 的 token 会被考虑。--top-k 100
:--top-k
参数限制了在生成过程中考虑的 token 数量。这里设置为 100,表示只有概率最高的 100 个 token 会被考虑。--repeat-penalty 1.05
:--repeat-penalty
参数用于控制重复生成相同内容的惩罚,1.05 表示如果生成了重复的 token,其概率会降低。--video /root/autodl-tmp/test-video.mp4
:指定了要处理的视频文件的路径。-p "我接下来会给你一个视频,请告诉我视频中描述了什么"
:-p
参数提供了一个提示(prompt),这是给模型的指令,告诉它接下来的任务是接收一个视频并描述视频内容。
结语
通过对 MiniCPM-V 2.6 的 vllm和 llama.cpp 两种部署推理方案的体验实践,我们可以看到,这款多态大模型在不同的部署环境下都能够发挥出强大的功能。无论是在高效性、灵活性还是可扩展性方面,MiniCPM-V 2.6 都表现出色,为人工智能的发展和应用提供了有力的支持。
当然,不同的部署推理方案适用于不同的场景和需求,用户可以根据自己的实际情况进行选择。在未来的发展中,我们相信 MiniCPM-V 2.6 将会不断完善和优化,为更多的用户带来更好的体验和价值。
🎯🔖更多专栏系列文章:AI大模型提示工程完全指南、AI大模型探索之路(零基础入门)、AI大模型预训练微调进阶、AI大模型开源精选实践、AI大模型RAG应用探索实践🔥🔥🔥 其他专栏可以查看博客主页📑
😎 作者介绍:我是寻道AI小兵,资深程序老猿,从业10年+、互联网系统架构师,目前专注于AIGC的探索。
📖 技术交流:欢迎关注【小兵的AI视界】公众号或扫描下方👇二维码,加入技术交流群,开启编程探索之旅。
💘精心准备📚500本编程经典书籍、💎AI专业教程,以及高效AI工具。等你加入,与我们一同成长,共铸辉煌未来。
如果文章内容对您有所触动,别忘了点赞、⭐关注,收藏!加入我,让我们携手同行AI的探索之旅,一起开启智能时代的大门!