vLLM部署使用指南(适合新手食用~)
手把手待你如何部署使用VLLM!
前言
vLLM 是目前最令人兴奋的 LLM 项目之一。每月下载量超过 60 万,且采用宽松的 Apache 2.0 许可证,vLLM 正成为一个在生产环境中进行大规模 LLM 部署的热门工具。
在本教程中,我将向你展示如何配置和运行 vLLM,以便在生产环境中部署和服务开源 LLM。
什么是 vLLM?
vLLM 是一个开源项目,专注于大规模 LLM 推理和服务。它提供了 Python API,使用户可以通过下载模型权重并将其传递给 vLLM 来实现推理。例如,下面的代码展示了如何使用 vLLM 执行推理:
from vllm import LLM, SamplingParams
prompts = [
"Hello, my name is",
"The president of the United States is",
"The capital of France is",
"The future of AI is",
]
# 初始化
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
llm = LLM(model="facebook/opt-125m")
# 执行推理
outputs = llm.generate(prompts, sampling_params)
# 打印输出
for output in outputs:
prompt = output.prompt
generated_text = output.outputs[0].text
print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
在这一方面,vLLM 与 Hugging Face 的 transformers 库相似。下面是 transformers 库中执行相同模型推理的示例:
from transformers import pipeline
generator = pipeline('text-generation', model="facebook/opt-125m")
generator("Hello, my name is")
使用 Python API 进行推理非常适合快速测试,但在生产环境中,我们希望提供一个接口,以便系统的其他部分可以轻松调用模型。一个不错的方案是通过 API 公开我们的模型。
假设你发现了 vLLM,并希望构建一个 REST API 来提供模型服务,可以构建如下的 Flask 应用:
from flask import Flask, request, jsonify
from vllm import LLM, SamplingParams
app = Flask(__name__)
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
llm = LLM(model="facebook/opt-125m")
@app.route('/generate', methods=['POST'])
def generate():
data = request.get_json()
prompts = data.get('prompts', [])
outputs = llm.generate(prompts, sampling_params)
# 准备输出结果
results = []
for output in outputs:
prompt = output.prompt
generated_text = output.outputs[0].text
results.append({
'prompt': prompt,
'generated_text': generated_text
})
return jsonify(results)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
用户现在可以通过调用 /generate 端点来访问我们的模型。然而,这样的实现有很多限制:如果有大量用户同时访问该端点,Flask 会尝试并发处理它们,这可能导致崩溃。此外,我们还需要自己实现身份验证机制,并且与其他系统的互操作性有限,用户必须阅读我们的模型 REST API 文档才能使用模型。
vLLM 的服务功能解决了这些问题。如果 vLLM 的 Python API 类似于 transformers 库,那么 vLLM 的服务器功能就类似于 TGI。
安装 vLLM
安装 vLLM 非常简单:
pip install vllm
注意,vLLM 仅支持 Linux 系统,要求 Python >=3.8。此外,它还需要计算能力 >=7.0 的 GPU(如 V100、T4、RTX20xx、A100、L4、H100 等)。
vLLM 是基于 CUDA 12.1 编译的,所以需要确保系统上运行的是该版本的 CUDA。检查 CUDA 版本,可以运行:
nvcc --version
如果没有运行 CUDA 12.1,可以安装适用于当前 CUDA 版本的 vLLM,或者升级到 CUDA 12.1。
检查安装
在继续操作之前,建议进行安装检查,确保 CUDA 能够与 torch 正常工作。可以运行以下命令:
# 确保 torch 可以与 CUDA 一起工作,应该输出:True
python -c 'import torch; print(torch.cuda.is_available())'
然后,将以下内容存储为 check-vllm.py 文件:
from vllm import LLM, SamplingParams
prompts = [
"Mexico is famous for ",
"The largest country in the world is ",
]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
llm = LLM(model="facebook/opt-125m")
responses = llm.generate(prompts, sampling_params)
for response in responses:
print(response.outputs[0].text)
运行此脚本:
python check-vllm.py
加载模型后,你会看到一些输出,例如:
~~national~~ cultural and artistic art. They've already worked with him.
~~the country~~ a capitalist system with the highest GDP per capita in the world
启动 vLLM 服务器
安装完成后,可以启动 vLLM 服务器,基本命令如下:
python -m vllm.entrypoints.openai.api_server --model=MODELTORUN
#示例
python -m vllm.entrypoints.openai.api_server --model=google/gemma-2b其中,MODELTORUN 是要服务的模型,例如 google/gemma-2b。
需要注意的是,一些模型(如 google/gemma-2b)需要接受其许可证,因此需要创建 Hugging Face 账号,接受模型的许可证,并生成一个令牌。
例如,打开 google/gemma-2b 页面时(需要登录),你会看到接受许可的选项。接受许可后,前往令牌部分,获取一个令牌,然后在启动 vLLM 之前设置令牌,如下:
export HF_TOKEN=YOURTOKEN
然后即可启动服务器。
python -m vllm.entrypoints.openai.api_server --model=google/gemma-2b
即使已经下载了权重文件,仍然需要该令牌。否则会收到以下错误:
File "/opt/conda/lib/python3.10/site-packages/huggingface_hub/hf_file_system.py", line 863, in _raise_file_not_found
raise FileNotFoundError(msg) from err
FileNotFoundError: google/gemma-2b (repository not found)
设置数据类型
数据类型(dtype)参数控制模型权重的数据类型。你可能需要根据 GPU 调整该参数。例如,尝试运行 google/gemma-2b 时,可以使用以下命令:
python -m vllm.entrypoints.openai.api_server --model=google/gemma-2b --dtype=auto
在 NVIDIA Tesla T4 上运行时会出现以下错误:
ValueError: Bfloat16 is only supported on GPUs with compute capability of at least 8.0.
Your Tesla T4 GPU has compute capability 7.5. You can use float16 instead by explicitly setting the `dtype` flag in CLI, for example: --dtype=half.
更改 --dtype 参数即可在 T4 上运行模型:
python -m vllm.entrypoints.openai.api_server --model=google/gemma-2b --dtype=half
首次启动 vLLM 时,它会下载权重文件,因此可能需要几分钟。之后的启动会更快,但加载模型到内存仍然需要一些时间(取决于模型大小)。
看到以下消息后,vLLM 就准备好接收请求:
INFO: Started server process [428]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
这表明 vLLM 已准备好接收请求!
发起请求
服务器运行后,可以使用 requests 库进行请求:
# 记得运行:pip install requests
import requests
import json
# 修改为你的主机地址
VLLM_HOST = "https://autumn-snow-1380.ploomberapp.io"
url = f"{VLLM_HOST}/v1/completions"
headers = {"Content-Type": "application/json"}
data = {
"model": "google/gemma-2b",
"prompt": "JupySQL is",
"max_tokens": 100,
"temperature": 0
}
response = requests.post(url, headers=headers, data=json.dumps(data))
print(response.json()["choices"][0]["text"])
此响应输出如下:
JupySQL 是一个 Python 库,允许您在 Jupyter 笔记本中创建和运行 SQL 查询。它是一个强大的数据分析和可视化工具,可以用于探索和操作大型数据集。
使用 OpenAI 客户端
vLLM 提供了一个类似 OpenAI API 的接口,因此可以使用 OpenAI 的 Python 包,但将请求定向到 vLLM 服务器。以下是示例:
# 注意:记得运行:pip install openai
from openai import OpenAI
# 未配置身份验证,可以传递一个占位值
openai_api_key = "EMPTY" #得自己设置
# 修改为你的主机地址,并添加 /v1
openai_api_base = "https://autumn-snow-1380.ploomberapp.io/v1"
client = OpenAI(
api_key=openai_api_key,
base_url=openai_api_base,
)
chat_response = client.chat.completions.create(
model="google/gemma-2b-it",
messages=[
{"role": "user", "content": "Tell me in one sentence what Mexico is famous for"},
]
)
print(chat_response.choices[0].message.content)
#输出
#Mexico is known for its rich culture, vibrant cities, stunning natural beauty,
and delicious cuisine.使用 OpenAI 客户端的请求方式非常类似于直接调用 OpenAI API,因此如果您之前用过 OpenAI 的服务,这种方法能直接迁移现有代码到 vLLM 服务器上。
如果你之前常用的话,会发现其中messages参数的常见形式为: {"role": "system", "content": ...}
chat_response = client.chat.completions.create(
model="google/gemma-2b-it",
messages=[
{"role": "system", "content": "You're a helful assistant."},
{"role": "user", "content": "Tell me in one sentence what Mexico is famous for"},
]但是有些情况下,比如说 gemma-2b-it不支持,会报错。
BadRequestError: Error code: 400 - {'object': 'error', 'message': 'System role not
supported', 'type': 'BadRequestError', 'param': None, 'code': 400}所以需要自行确认不同模型中需要的输入形式。
常见问题排查
- 网络问题:如果您无法连接到 Hugging Face 或 vLLM 服务器,检查您的网络连接或代理设置。
- 令牌问题:确保您已正确设置 Hugging Face 的 HF_TOKEN,否则您可能会遇到 403 错误。
- 模型兼容性问题:某些模型可能对显存和 GPU 计算能力有较高要求,建议根据 vLLM 的官方文档选择合适的模型和参数配置。
至此,您已了解如何安装 vLLM、启动服务器、配置 API 并发起请求。希望这能帮助您轻松实现大型语言模型的推理和服务化。
在生产环境中部署 vLLM
1. 自动重启
- 使用 systemd:可以使用
systemd来管理 vLLM API 进程,这样如果 API 崩溃或服务器重启,vLLM 将自动重新启动。
- 示例
systemd单元配置:
2. 使用 Docker 提高可移植性
- 推荐使用 Docker:使用 Docker 可以提高部署的可移植性。为确保一致性,请锁定所有 Python 依赖项,以避免升级时影响安装(例如使用
pip freeze锁定依赖版本)。
3. 使用 PyTorch 官方 Docker 镜像
- 推荐使用 PyTorch 官方镜像:PyTorch 的官方 Docker 镜像已经包含了
torch和 CUDA 驱动,这有助于简化环境设置。
示例 Dockerfile:
FROM pytorch/pytorch:2.1.2-cuda12.1-cudnn8-devel
WORKDIR /srv
RUN pip install vllm==0.3.3 --no-cache-dir
# 如果要服务的模型要求接受许可条款,需设置 HF_TOKEN 环境变量
# 还需要设置 VLLM_API_KEY 环境变量来认证 API
ENTRYPOINT ["python", "-m", "vllm.entrypoints.openai.api_server", \
"--host", "0.0.0.0", "--port", "80", \
"--model", "google/gemma-2b-it", \
"--dtype=half"]
4. 关于 transformers==4.39.1 包的兼容性问题
- 注意 PyTorch 版本一致性:确保 vLLM 使用的 PyTorch 版本与 transformers 依赖的版本一致,以避免兼容性问题。
- 在编写此指南时,我们遇到了一些与
transformers包相关的错误。例如,当 Dockerfile 使用torch==2.2.2和vllm==0.3.3时,会出现以下错误:
- 原因分析:问题出在
transformers包中,该包中用到了 PyTorch 的register_pytree_node方法,而 vLLM 安装后可能会降级 PyTorch 版本(从2.2.2降级到2.1.2),导致 transformers 假设的版本不匹配,从而引发错误。
- 解决方案:确保安装的 PyTorch 版本与 vLLM 及 transformers 所需的版本一致;或者在遇到版本不匹配问题时,手动调整到兼容的版本。
原文链接
追求一体化验证和更快的Python部署可以使用FastAPI 结合 pydantic