MiniCPM-V 2.6:端侧最强多模态大模型探索【推理实战大全】

系列篇章💥

No.文章
1MiniCPM-V 2.6:端侧最强多模态大模型探索【本地部署实践】
2MiniCPM-V 2.6:端侧最强多模态大模型探索【推理实战大全】
3MiniCPM-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的探索之旅,一起开启智能时代的大门!

评论 101
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值