第四课:在线服务部署——启动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 核心知识体系

这一课的内容,说白了就是三件事:启动、测试、调用。我画了一张图帮你理清关系:

vLLM在线服务部署核心流程 vllm serve 启动 curl 快速验证 openai库 集成 --host 0.0.0.0 --port 8000 --max-model-len /v1/completions /v1/chat/completions 检查usage字段 非流式 vs 流式 stream=True 首字延迟优化 生产环境:启动 → 测试 → 集成 → 监控

这张图把整个流程串起来了。你从左边开始,先启动服务,然后用curl快速验证接口通不通,最后用Python客户端做正式集成。每一步都有对应的参数和注意事项。

核心要点:
  • vLLM的API和OpenAI完全兼容,迁移成本极低
  • 流式调用(stream=True)是生产环境标配,用户体验更好
  • 每次调用都要关注usage字段,这是做成本监控的基础
  • 启动参数里,max-model-len和gpu-memory-utilization是最容易踩坑的地方

好了,这一课的内容就这些。你可以在本地启动一个服务,然后用curl和Python分别试试。有什么问题,随时可以来找我聊。


专注资料整理