实战案例

三个可独立运行的例子:离线批生成、OpenAI 兼容客户端、简易并发冒烟。请先 安装 并准备 NVIDIA GPU。演示模型保持 未门控facebook/opt-125mQwen/Qwen2.5-0.5B-Instruct


案例 1:离线批推理

目标: 对一批 prompt 生成短补全,体会连续批处理(引擎内部会把列表一起跑)。

from vllm import LLM, SamplingParams

PROMPTS = [
    "PagedAttention is",
    "Continuous batching helps GPU utilization because",
    "An OpenAI-compatible base URL looks like",
]

llm = LLM(model="facebook/opt-125m")
params = SamplingParams(temperature=0.2, max_tokens=48, stop=["\n\n"])
outputs = llm.generate(PROMPTS, params)

for item in outputs:
    text = item.outputs[0].text.replace("\n", " ").strip()
    print(f"- {item.prompt!r}\n  {text}\n")
python batch_gen.py

验证: 三条都有非空输出;第二次运行应走缓存、启动更快。把列表加长到几十条,观察 GPU 利用率是否高于「一条条 Transformers generate」。


案例 2:指向 vLLM 的迷你聊天客户端

目标: 服务已用 vllm serve Qwen/Qwen2.5-0.5B-Instruct 拉起时,业务代码只依赖 openai 包。

from openai import OpenAI

MODEL = "Qwen/Qwen2.5-0.5B-Instruct"
client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")

messages = [
    {"role": "system", "content": "你是推理服务助手。用简体中文、不超过三句。"},
]

print("输入空行退出。服务须已在 8000 端口运行。")
while True:
    user = input("你: ").strip()
    if not user:
        break
    messages.append({"role": "user", "content": user})
    resp = client.chat.completions.create(
        model=MODEL,
        messages=messages,
        temperature=0.6,
        max_tokens=128,
    )
    text = resp.choices[0].message.content or ""
    messages.append({"role": "assistant", "content": text})
    print("助手:", text, "\n")

PowerShell 冒烟(WSL 里的服务被 Windows 访问时,确认端口转发):

Invoke-RestMethod -Method Post -Uri "http://localhost:8000/v1/chat/completions" `
  -ContentType "application/json" `
  -Body '{"model":"Qwen/Qwen2.5-0.5B-Instruct","messages":[{"role":"user","content":"ping"}],"max_tokens":16}'

验证: 第二轮能引用第一轮里的专有名词。把 base_url 改成错误端口应立刻失败,说明没有误打到公网 OpenAI。接到 LangChain 时同样只改兼容 endpoint。


案例 3:并发请求冒烟

目标: 同时发出多路 chat,确认服务接受并发(连续批处理的意义)。不要对 0.5B 期望「生产 SLA」,只验证不会串响应。

import concurrent.futures
from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")
MODEL = "Qwen/Qwen2.5-0.5B-Instruct"

def ask(i: int) -> str:
    r = client.chat.completions.create(
        model=MODEL,
        messages=[{"role": "user", "content": f"Reply with the number {i} only."}],
        temperature=0,
        max_tokens=8,
    )
    return (r.choices[0].message.content or "").strip()

with concurrent.futures.ThreadPoolExecutor(max_workers=8) as pool:
    futs = [pool.submit(ask, i) for i in range(8)]
    for f in concurrent.futures.as_completed(futs):
        print(f.result())

验证: 八个结果都能回来;允许小模型偶发不严格只回数字。若全部超时,查 --max-num-seqs、显存、是否其实在 CPU 排队。

更认真的压测用官方 vllm bench(子命令以当前 CLI 为准)或独立负载工具,不要用这 0.5B 脚本当容量规划。


反模式

反模式改进
教程全程只用门控 Llama-2用 Qwen 0.5B / OPT-125M 先跑通
无 GPU 却坚持 pip vLLMOllama 或云 GPU
localhost:8000 从其他容器访问compose 服务名或 host.docker.internal
--api-key 当公网防火墙反向代理 + 内网
一张卡同时开 Ollama 和 vLLM先停掉其中一个

下一步

评论