vLLM部署多模態大模型Qwen2.5-VL-3B-Instruct
原文 https://blog.csdn.net/qq_41934789/article/details/147906736?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-4-147906736-blog-145811670.235^v43^pc_blog_bottom_relevance_base7&spm=1001.2101.3001.4242.3&utm_relevant_index=7
一、前提環境
1、系統環境
2、安裝相關環境
安裝依賴
%pip install accelerate qwen-vl-utils[decord]==0.0.8
%pip install transformers==4.50.0
%pip install modelscope==1.24.0
%pip install torch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 --index-url https://download.pytorch.org/whl/cu121
%pip install pillow requests python-dotenv
%pip install vllm==0.7.3
AI寫代碼
shell
注意:flash-attn 不是必須安裝的,可安可不安
注意:如果安裝 flash-attn 失敗,使用離線安裝
下載地址:flash-attn下載
下載界面:根據自己系統的版本進行下載
安裝命令
pip install flash-att本地地址
AI寫代碼
shell
1
3、查看相關環境
%pip show torchvision modelscope flash-attn
AI寫代碼
shell
1
%pip show transformers accelerate qwen-vl-utils
AI寫代碼
shell
1
%pip show torch
AI寫代碼
shell
1
二、模型下載
使用 魔搭 下載模型
# model_download.py
#模型下載
from modelscope import snapshot_download
model_dir = snapshot_download('Qwen/Qwen2.5-VL-3B-Instruct', cache_dir='/root/autodl-tmp', revision='master')
AI寫代碼
python
運行
1
2
3
4
5
三、運行模型
1、方式一(使用代碼 直接運行 模型)
首先從 vLLM 庫中導入 LLM 和 SamplingParams 類。LLM 類是使用 vLLM 引擎運行離線推理的主要類。SamplingParams 類指定采樣過程的參數,用于控制和調整生成文本的隨機性和多樣性。
vLLM 提供了非常方便的封裝,我們直接傳入模型名稱或模型路徑即可,不必手動初始化模型和分詞器
詳細代碼如下:
# vllm_model.py
# 使用 vllm 本地模式 使用
from transformers import AutoProcessor
from vllm import LLM, SamplingParams
from qwen_vl_utils import process_vision_info
class QwenVLModel:
def __init__(self, model_path="/root/autodl-tmp/Qwen/Qwen2.5-VL-3B-Instruct"):
self.model_path = model_path
self.llm = LLM(
model=self.model_path,
limit_mm_per_prompt={"image": 1, "video": 1},
tensor_parallel_size=1, # 設置為1以減少GPU內存使用
gpu_memory_utilization=0.9, # 控制GPU內存使用率
max_model_len=2048, # 限制最大序列長度
# quantization="awq", # 使用AWQ量化來減少內存使用
)
self.sampling_params = SamplingParams(
temperature=0.1,
top_p=0.001,
repetition_penalty=1.05,
max_tokens=512,
stop_token_ids=[],
)
self.processor = AutoProcessor.from_pretrained(self.model_path)
def generate(self, messages):
prompt = self.processor.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
)
image_inputs, video_inputs = process_vision_info(messages)
mm_data = {}
if image_inputs is not None:
mm_data["image"] = image_inputs
if video_inputs is not None:
mm_data["video"] = video_inputs
llm_inputs = {
"prompt": prompt,
"multi_modal_data": mm_data,
}
outputs = self.llm.generate([llm_inputs], sampling_params=self.sampling_params)
return outputs[0].outputs[0].text
from tqdm import tqdm
img_path = "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg"
prompt_str = "請用中文描述一下這張圖片"
image_messages = [
{"role": "system", "content": "You are a helpful assistant."},
{
"role": "user",
"content": [
{
"type": "image",
"image": img_path,
"min_pixels": 256 * 28 * 28,
"max_pixels": 1280 * 28 * 28,
},
{"type": "text", "text": prompt_str},
],
},
]
model = QwenVLModel()
output_text = model.generate(image_messages)
print(output_text)
AI寫代碼
python
運行
代碼運行結果
2、方式二(提高 openai 式接口)
運行指令
#vllm 執行命令
python -m vllm.entrypoints.openai.api_server \
--model /root/autodl-tmp/Qwen/Qwen2.5-VL-3B-Instruct \
--served-model-name qwen-vl \
--max-model-len 64000 \
--limit-mm-per-prompt "image=5" \ # 允許每個prompt處理5張圖像[9](@ref)
--port 8000
AI寫代碼
shell
解釋:
--port 參數指定地址。
–model 參數指定模型名稱。
–served-model-name 指定服務模型的名稱。
–max-model-len 指定模型的最大長度。
--limit-mm-per-prompt "image=5" 允許每個prompt處理5張圖像
AI寫代碼
1
2
3
4
5
指令運行結果
測試代碼
#使用langchain 調用 openai 的方式調用
# 引入 OpenAI 支持庫
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
import base64, os
base_url ="http://localhost:8000/v1"
api_key ="EMPTY"
# 初始化LangChain客戶端
llm = ChatOpenAI(
model="qwen-vl", # 與--served-model-name一致
temperature=0.7,
max_tokens=1024,
base_url=base_url,
api_key=api_key
)
# 處理多模態輸入(示例:文本+圖像)
def image_to_base64(image_path):
with open(image_path, "rb") as img_file:
return base64.b64encode(img_file.read()).decode('utf-8')
# 構造多模態消息
messages = [
{
"role": "user",
"content": [
{"type": "text", "text": "請用中文描述這張圖片的內容"},
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{image_to_base64('demo.jpeg')}"
}
}
]
}
]
# 發送請求
response = llm.invoke(messages)
print(f"模型回復:{response.content}")
AI寫代碼
python
運行
運行結果
模型回復:這張圖片展示了一位年輕女子和她的金毛犬在海灘上。女子坐在沙灘上,微笑著與狗狗互動。狗狗戴著項圈,看起來非常溫順和友好。背景是廣闊的海洋,海浪輕輕拍打著海岸,整個場景充滿了溫馨和幸福的氛圍。陽光灑在沙灘和海洋上,給人一種溫暖而寧靜的感覺。
AI寫代碼
python
運行
1
3、方式三(使用 transformers 運行模型)
# 本地加載使用
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
from qwen_vl_utils import process_vision_info
import torch
class QwenVLModel:
def __init__(self, model_path="/root/autodl-tmp/Qwen/Qwen2.5-VL-3B-Instruct", use_flash_attention=False):
"""
初始化Qwen VL模型
Args:
model_path: 模型路徑
use_flash_attention: 是否使用flash attention加速
"""
# 加載模型
if use_flash_attention:
self.model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
model_path,
torch_dtype=torch.bfloat16,
attn_implementation="flash_attention_2",
device_map="auto",
)
else:
self.model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
model_path, torch_dtype="auto", device_map="auto"
)
# 初始化處理器
min_pixels = 256*28*28
max_pixels = 1280*28*28
self.processor = AutoProcessor.from_pretrained(
model_path,
min_pixels=min_pixels,
max_pixels=max_pixels,
use_fast=True
)
def process_image(self, image_path, prompt):
"""
處理圖片并生成輸出
Args:
image_path: 圖片路徑
prompt: 提示文本
Returns:
生成的文本輸出
"""
messages = [
{
"role": "user",
"content": [
{
"type": "image",
"image": image_path,
},
{"type": "text", "text": prompt},
],
}
]
# 準備推理輸入
text = self.processor.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
image_inputs, video_inputs = process_vision_info(messages)
inputs = self.processor(
text=[text],
images=image_inputs,
videos=video_inputs,
padding=True,
return_tensors="pt",
)
inputs = inputs.to(self.model.device)
# 生成輸出
generated_ids = self.model.generate(**inputs, max_new_tokens=512)
generated_ids_trimmed = [
out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)
]
output_text = self.processor.batch_decode(
generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False
)
return output_text
#測試
model = QwenVLModel()
img_path = "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg"
output_text = model.process_image(
img_path,
"請用中文描述一下這張圖片"
)
print(f"輸出信息: {output_text}")
————————————————
版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
原文鏈接:https://blog.csdn.net/qq_41934789/article/details/147906736
java新手自學群 626070845
java/springboot/hadoop/JVM 群 4915800
Hadoop/mongodb(搭建/開發/運維)Q群481975850
GOLang Q1群:6848027
GOLang Q2群:450509103
GOLang Q3群:436173132
GOLang Q4群:141984758
GOLang Q5群:215535604
C/C++/QT群 1414577
單片機嵌入式/電子電路入門群群 306312845
MUD/LIB/交流群 391486684
Electron/koa/Nodejs/express 214737701
大前端群vue/js/ts 165150391
操作系統研發群:15375777
匯編/輔助/破解新手群:755783453
大數據 elasticsearch 群 481975850
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。

浙公網安備 33010602011771號