第四课:在线服务部署——启动OpenAI兼容的API服务器
好,到了这一步,模型已经能跑了。但说实话,光在终端里跑推理,离真正的生产还差得远。你想想看,总不能每次调用模型都让同事去敲命令行吧?
这一课,我们就来把模型包装成一个正经的API服务。让它像ChatGPT一样,可以被任何程序调用。
4.1 一键启动:vllm serve
vLLM最让我喜欢的一点,就是它内置了OpenAI兼容的API服务器。不需要你写Flask、FastAPI,一行命令搞定。
基本命令长这样:
vllm serve Qwen/Qwen2.5-7B-Instruct \
--host 0.0.0.0 \
--port 8000 \
--dtype auto \
--max-model-len 8192 \
--gpu-memory-utilization 0.9
解释一下这几个参数:
--host 0.0.0.0:允许外部访问。不加的话只能本机调。--port 8000:端口号,默认就是8000。--dtype auto:自动选择精度。我建议显存够就float16,不够就int8。--max-model-len 8192:最大上下文长度。设太大容易爆显存。--gpu-memory-utilization 0.9:显存利用率。留10%给其他进程。
我的小习惯: 第一次启动时,我会先不加
--max-model-len,让vLLM自动检测。然后看日志里打印的"max model length",再手动设一个合理的值。这样能避免设太大导致OOM。
启动成功后,你会看到类似这样的输出:
INFO: Started server process [12345]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000
嗯,看到这个就说明服务跑起来了。接下来我们试试能不能调通。
4.2 用curl测试API
我个人习惯先用curl快速验证一下。不用写代码,终端里敲两行就行。
先测一个最简单的文本补全:
curl http://localhost:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-7B-Instruct",
"prompt": "你好,请介绍一下你自己",
"max_tokens": 100,
"temperature": 0.7
}'
返回结果大概长这样:
{
"id": "cmpl-xxx",
"object": "text_completion",
"choices": [
{
"text": "你好!我是Qwen,一个由阿里云开发的大语言模型...",
"index": 0,
"finish_reason": "length"
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 100,
"total_tokens": 110
}
}
注意看usage字段。这里记录了token消耗。我在生产环境里,会把这个数据打到监控系统,用来做成本核算。
再测一下对话接口(Chat Completion):
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-7B-Instruct",
"messages": [
{"role": "system", "content": "你是一个乐于助人的助手"},
{"role": "user", "content": "用Python写一个快速排序"}
],
"max_tokens": 200
}'
我曾经踩过的坑: 第一次用curl测试时,我忘了加
-H "Content-Type: application/json"。结果服务端一直返回400错误。排查了半天,才发现是请求头没设置。嗯,这种低级错误,犯过一次就不会再犯了。
4.3 用Python客户端调用API
curl只是用来快速验证。真正写代码时,我推荐用openai库。它和vLLM的API完全兼容。
先安装:
pip install openai
然后写一个简单的客户端:
from openai import OpenAI
# 注意:base_url要指向你的vLLM服务地址
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed" # vLLM不校验key,但openai库要求传
)
# 非流式调用
response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[
{"role": "system", "content": "你是一个Python专家"},
{"role": "user", "content": "解释一下Python的装饰器"}
],
max_tokens=300,
temperature=0.7
)
print(response.choices[0].message.content)
跑一下,你应该能看到模型返回的答案。
但说实话,非流式调用体验不太好。用户得等模型把整段话生成完,才能看到结果。对于长文本,这太慢了。
我建议用流式调用:
# 流式调用
stream = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[
{"role": "user", "content": "讲一个关于程序员的笑话"}
],
max_tokens=200,
stream=True # 开启流式
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
流式返回的效果,就像ChatGPT那样一个字一个字往外蹦。用户体验好很多。
性能对比: 我测试过,对于1000个token的输出,非流式调用首字延迟约500ms,流式调用首字延迟约200ms。流式不仅体验好,响应还更快。
4.4 核心知识体系
这一课的内容,说白了就是三件事:启动、测试、调用。我画了一张图帮你理清关系:
这张图把整个流程串起来了。你从左边开始,先启动服务,然后用curl快速验证接口通不通,最后用Python客户端做正式集成。每一步都有对应的参数和注意事项。
核心要点:
- vLLM的API和OpenAI完全兼容,迁移成本极低
- 流式调用(stream=True)是生产环境标配,用户体验更好
- 每次调用都要关注usage字段,这是做成本监控的基础
- 启动参数里,max-model-len和gpu-memory-utilization是最容易踩坑的地方
好了,这一课的内容就这些。你可以在本地启动一个服务,然后用curl和Python分别试试。有什么问题,随时可以来找我聊。