目錄
環境
qwen2.5-1.5b-instruct
模型下載
vllm 安裝
驗證安裝
vllm 啟動
查看當前模型列表
OpenAI Completions API(文本生成)
OpenAI Chat Completions API(chat 對話)
vllm 進程查看,kill
llama3
deepseek-蒸餾版 qwen
環境
Name: vllm
Version: 0.7.3
Name: torch
Version: 2.5.1
Name: transformers
Version: 4.49.0
cuda:V100-32GB
Version:12.1
qwen2.5-1.5b-instruct
模型下載
from modelscope import snapshot_download
model_dir = snapshot_download('Qwen/Qwen2.5-1.5B-Instruct', cache_dir='/root/autodl-tmp/')
?cache_dir 保存路徑
vllm 安裝
直接 pip 即可
pip install vllm
驗證安裝
安裝好 vllm,下載好模型后,可以用以下代碼試下 vllm 推理,如果正常會有運行結果
import os
import warnings
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
warnings.filterwarnings('ignore')from transformers import AutoTokenizer
from vllm import LLM, SamplingParams
import pandas as pd
import timeclass vllmModel():def __init__(self, model_path, temperature=0.1, max_tokens=4096, tp_size=1):"""model_path: 模型路徑temperature: 溫度max_tokens: 模型最大輸出 tokentp_size: gpu 數量,可以為 1 張卡卡,多余一張卡,必須是雙數,如 2,4,6"""print(f'加載本地模型:{model_path}')self.tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)self.llm = LLM(model=model_path,tensor_parallel_size=tp_size,max_model_len=4096,trust_remote_code=True,enforce_eager=True,dtype="float16",# 如果遇見 OOM 現象,建議開啟下述參數# enable_chunked_prefill=True,# max_num_batched_tokens=8192)self.sampling_params = SamplingParams(temperature=temperature, max_tokens=max_tokens)print("模型加載完畢")def infer(self, prompts):"""prompts: prompt 列表"""prompts = [{"role": "user", "content": prompt} for prompt in prompts]inputs = []for prompt in prompts:_input = self.tokenizer.apply_chat_template([prompt], tokenize=False, add_generation_prompt=True)inputs.append(_input)outputs = self.llm.generate(prompts=inputs, sampling_params=self.sampling_params)result = []for output in outputs:text = output.outputs[0].textresult.append(text)return result# 加載模型
model_path = "/root/autodl-tmp/Qwen/Qwen2___5-1___5B-Instruct/"
llm = vllmModel(model_path)# infer
print(llm.infer(['你好', '你能做什么?']))
vllm 啟動
qwen2.5 兼容 openai 的 api 服務,可以用一下命令啟動:
VLLM_WORKER_MULTIPROC_METHOD=spawn \
vllm serve /root/autodl-tmp/Qwen/Qwen2___5-1___5B-Instruct \
--trust-remote-code \
--served-model-name qwen2_5_1_5 \
--gpu-memory-utilization 0.2 \
--tensor-parallel-size 1 \
--port 8000 \
--dtype=half
--dtype=half 跟 gpu 有關,因為我報錯了,提示加這參數,是精度
--port 8000 開啟端口為 8000
--trust-remote-code??允許執行遠程代碼
--served-model-name qwen2_5_1_5? 模型名稱定義,不是模型路徑
--gpu-memory-utilization 0.2? gpu 顯存占用,如果太高,我最開始 0.98,調用會崩掉
--tensor-parallel-size 1 使用 gpu 的數量
serve /root/autodl-tmp/Qwen/Qwen2___5-1___5B-Instruct 模型加載路徑
--quantization awq 如果部署量化模型,即模型后綴為 AWQ,需要加上
vllm_use_v1=1 寫在最開頭,代表境變量為?1
,表示你希望使用 vLLM 的 V1 API 版本。這通常涉及到API的設計,這個參數加上了,我這里不僅掉不通,一調就掛了,或者沒多久也會自己掛,所以去掉
VLLM_WORKER_MULTIPROC_METHOD=spawn? 寫在最開頭
這個變量指定在多進程模式下,worker(工作進程)啟動的方法。在這個例子中,值被設置為?spawn
。在Python的multiprocessing模塊中有多種方法可以創建新進程,其中包括fork
、spawn
和forkserver
。spawn
方法意味著每個新的進程都是通過啟動一個全新的Python解釋器實例來創建的。這種方法相較于fork
更加安全,尤其是在使用非Unix平臺(如Windows)時,因為fork
可能會導致一些問題,比如子進程繼承了父進程的所有資源,可能導致死鎖或其他意外行為。
--max_model_len 4096?模型能夠處理的最大序列長度(以token為單位),顯存不夠報錯了,可以調小
CUDA_VISIBLE_DEVICES=0,2 寫在最開頭,指定使用哪張 gpu,這里是第 1,3 卡
啟動成功會顯示如下:
查看當前模型列表
curl http://localhost:8000/v1/models
{"object": "list","data": [{"id": "qwen2_5_1_5","object": "model","created": 1740235117,"owned_by": "vllm","root": "/root/autodl-tmp/Qwen/Qwen2___5-1___5B-Instruct","parent": null,"max_model_len": 32768,"permission": [{"id": "modelperm-514811fdf7464bc9bbd72db39850ef49","object": "model_permission","created": 1740235117,"allow_create_engine": false,"allow_sampling": true,"allow_logprobs": true,"allow_search_indices": false,"allow_view": true,"allow_fine_tuning": false,"organization": "*","group": null,"is_blocking": false}]}]
}
OpenAI Completions API(文本生成)
一般指文本生成類的使用,非 chat,即非對話的使用方式
curl http://localhost:8000/v1/completions \-H "Content-Type: application/json" \-d '{"model": "qwen2_5_1_5","prompt": "你好,你是?","max_tokens": 2048,"temperature": 0.7,"top_p": 0.8,"repetition_penalty": 1.05}'
加 repetition_penalty 之前,會有很多重復:?
加之后:
"max_tokens": 2048,?生成文本的最大長度(以token為單位)
"temperature": 0.7,?生成文本的隨機性,值越小,創造能力越強,輸出更加多樣,適合創造場景
"top_p": 0.8,?核采樣,類似溫度,
"repetition_penalty": 1.05?用來減少重復詞語出現的一個調節器。當其值大于1時(例如這里的?repetition_penalty: 1.05
),會降低之前已經出現在生成文本中的詞語被再次選中的概率。這有助于提高生成文本的新穎性,避免不必要的重復
{"id": "cmpl-adb0ffa50a1142a1880620126e341a70","object": "text_completion","created": 1740236869,"model": "qwen2_5_1_5","choices": [{"index": 0,"text": " 答案:我是小明。 A. 錯誤 B. 正確\nA. 錯誤\n\n解析:\"我是小明\"是一個常見的自我介紹,但它并不一定正確,因為每個人在回答\"你是誰\"的問題時,通常會提供自己真實的姓名或名字。\"小明\"可能是一個昵稱或別名,這取決。。。。。。。。。。。。。。。。。。。","logprobs": null,"finish_reason": "length","stop_reason": null,"prompt_logprobs": null}],"usage": {"prompt_tokens": 4,"total_tokens": 2052,"completion_tokens": 2048,"prompt_tokens_details": null}
}
?python openai 接口:
from openai import OpenAI# 設置 OpenAI 的 API key 和 API base 來使用 vLLM 的 API server.
openai_api_key = "EMPTY" # 如果不需要 API key,可以留空或設置為 "EMPTY"
openai_api_base = "http://localhost:8000/v1"client = OpenAI(api_key=openai_api_key,base_url=openai_api_base,
)# 創建 Completion 請求
completion_response = client.completions.create(model="qwen2_5_1_5",prompt="你好,你是?",max_tokens=2048,temperature=0.7,top_p=0.8,# 注意:OpenAI Python 客戶端可能不直接支持 repetition_penalty,需要確認服務是否接受額外參數extra_body={"repetition_penalty": 1.05},
)# 檢查響應并打印結果
if hasattr(completion_response, 'choices') and len(completion_response.choices) > 0:print("成功獲取數據:")print(completion_response.choices[0].text)
else:print(f"請求失敗,響應內容:{completion_response}")
python vllm 接口
import requests
import json# 設置請求的URL
url = "http://localhost:8000/v1/completions"# 設置請求頭部
headers = {"Content-Type": "application/json"
}# 準備請求數據
data = {"model": "qwen2_5_1_5","prompt": "你好,你是?","max_tokens": 2048,"temperature": 0.7,"top_p": 0.8,"repetition_penalty": 1.05
}# 發送POST請求
response = requests.post(url, headers=headers, data=json.dumps(data))# 檢查響應狀態并打印結果
if response.status_code == 200:try:# 嘗試解析響應中的 'choices' 字段,并獲取生成的文本choices = response.json().get('choices', [])if choices:print("成功獲取數據:")# 注意這里的 'text' 字段可能需要根據實際API響應結構調整print(choices[0].get('text', ''))else:print("沒有獲取到任何選擇結果")except json.JSONDecodeError:print("無法解析JSON響應")
else:print(f"請求失敗,狀態碼:{response.status_code}, 響應內容:{response.text}")
OpenAI Chat Completions API(chat 對話)
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "qwen2_5_1_5","messages": [{"role": "system", "content": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant."},{"role": "user", "content": "你好,你是?"}],"temperature": 0.7,"top_p": 0.8,"repetition_penalty": 1.05,"max_tokens": 2048
}'
{"id": "chatcmpl-189df22813aa4b358e795596f0e2c420","object": "chat.completion","created": 1740238345,"model": "qwen2_5_1_5","choices": [{"index": 0,"message": {"role": "assistant","reasoning_content": null,"content": "你好!我是阿里云開發的一款語言模型,我叫通義千問。","tool_calls": []},"logprobs": null,"finish_reason": "stop","stop_reason": null}],"usage": {"prompt_tokens": 33,"total_tokens": 51,"completion_tokens": 18,"prompt_tokens_details": null},"prompt_logprobs": null
}
?python 代碼 openai 接口
from openai import OpenAI# 設置 OpenAI 的 API key 和 API base 來使用 vLLM 的 API server.
openai_api_key = "EMPTY"
openai_api_base = "http://localhost:8000/v1"client = OpenAI(api_key=openai_api_key,base_url=openai_api_base,
)chat_response = client.chat.completions.create(model="qwen2_5_1_5",messages=[{"role": "system", "content": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant."},{"role": "user", "content": "你是誰?"},],temperature=0.7,top_p=0.8,max_tokens=512,extra_body={"repetition_penalty": 1.05,},
)# 直接訪問響應對象的屬性,而不是嘗試調用 .json()
print("Chat response:", chat_response.choices[0].message.content)
python vllm 接口
import requests
import json# 設置API的基本URL和端點
base_url = "http://localhost:8000/v1"
endpoint = "/chat/completions"url = base_url + endpoint# 設置請求頭部
headers = {"Content-Type": "application/json",
}# 準備請求數據
data = {"model": "qwen2_5_1_5","messages": [{"role": "system", "content": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant."},{"role": "user", "content": "你是誰?"},],"temperature": 0.7,"top_p": 0.8,"max_tokens": 512,"repetition_penalty": 1.05, # 直接包含在請求體中
}# 發送POST請求
response = requests.post(url, headers=headers, data=json.dumps(data))# 檢查響應狀態并打印結果
if response.status_code == 200:print("Chat response:", response.json()['choices'][0]['message'])
else:print(f"請求失敗,狀態碼:{response.status_code}, 響應內容:{response.text}")
vllm 進程查看,kill
ps aux | grep vllm
kill -9 6947
服務殺死了,但顯存沒釋放
llama3
跟 qwen2.5 一樣
deepseek-蒸餾版 qwen
vllm 啟動需要加個參數?--enforce-eager
始終使用急切模式PyTorch,如果為False,則在混合模式下使用急切模式和CUDA圖以獲得最大性能和靈活性
vllm serve /root/autodl-tmp/deepseek-ai/DeepSeek-R1-Distill-Qwen-1___5B/ \
--trust-remote-code \
--served-model-name qwen2_5_1_5 \
--gpu-memory-utilization 0.7 \
--tensor-parallel-size 1 \
--max-model-len 32768 \
--dtype=half \
--enforce-eager
參數說明:VLLM參數解釋-中文表格形式-CSDN博客
參考:
https://github.com/datawhalechina/self-llm/blob/master/models/Qwen2.5/03-Qwen2.5-7B-Instruct%20vLLM%20%E9%83%A8%E7%BD%B2%E8%B0%83%E7%94%A8.md
使用vLLM部署Qwen2.5-VL-7B-Instruct模型的詳細指南_vllm qwen2.5-vl-CSDN博客
vLLM - Qwen