3、快速启动:加载第一个模型、使用vLLM进行文本生成、理解vLLM的输出格式、常见启动参数解析

好,咱们直接进入正题。

这一章,我带你亲手跑通第一个模型。别怕,vLLM 的启动其实比你想的简单。你想想看,一个能支撑生产级推理的框架,启动命令居然就一行?嗯,确实如此。

我个人习惯,学任何新工具,第一件事就是让它“动起来”。先看到输出,再回头理解原理,这样心里踏实。

3.1 加载第一个模型:从 Hugging Face 到 vLLM

vLLM 加载模型,本质上是对 Hugging Face Transformers 的封装。但它做了大量优化,比如 PagedAttention 和连续批处理。

最简单的启动方式,就是直接用 vllm.LLM 类。你只需要告诉它模型名字或路径。

核心代码:

from vllm import LLM

# 加载模型
llm = LLM(model="Qwen/Qwen2.5-7B-Instruct")

就这么一行。我第一次跑的时候,心里还嘀咕:这么简单?结果它真的开始下载模型权重了。

这里有个坑,我提醒你一下:

注意: 模型名字要跟 Hugging Face 上的一致。如果你在内网环境,或者想用本地模型,直接传本地路径就行:

llm = LLM(model="/data/models/Qwen2.5-7B-Instruct")

加载过程会打印一些日志,比如显存分配、模型配置等。别被吓到,这些都是正常信息。

3.2 使用 vLLM 进行文本生成

模型加载好了,接下来就是生成文本。vLLM 提供了两种方式:离线批处理在线 API。这一章我们先讲离线方式,API 后面章节会细说。

生成文本的核心方法是 llm.generate()。你传一个 prompt 列表进去,它返回一个结果列表。

# 准备输入
prompts = [
    "请用一句话解释什么是量子计算。",
    "写一首关于春天的五言绝句。"
]

# 生成
outputs = llm.generate(prompts)

# 打印结果
for output in outputs:
    print(output.outputs[0].text)

你看,代码非常直观。我建议你第一次跑的时候,先用短文本测试,比如 10 个字以内的 prompt。为什么呢?因为如果模型加载有问题,短文本能快速暴露错误。

小技巧: 如果你想让生成结果更稳定,可以设置 temperature=0。这样模型每次输出都一样,方便调试。

outputs = llm.generate(prompts, sampling_params={"temperature": 0})

3.3 理解 vLLM 的输出格式

vLLM 的输出格式,说白了就是一个嵌套结构。很多新手第一次看到输出时,会有点懵。我来拆解一下。

每个 output 对象包含:

  • prompt:你输入的原始文本
  • prompt_token_ids:prompt 对应的 token ID 列表
  • outputs:一个列表,里面是 CompletionOutput 对象

而每个 CompletionOutput 又包含:

  • index:第几个生成结果(如果你设置 n>1,会有多个)
  • text:生成的文本内容
  • token_ids:生成文本的 token ID 列表
  • cumulative_logprob:整个序列的对数概率之和
  • logprobs:每个 token 的对数概率(需要设置 logprobs=True

我画了一张图,帮你理清这个结构:

vLLM 输出结构解析 LLM.generate() 返回 List[RequestOutput] RequestOutput prompt: str prompt_token_ids: List[int] outputs: List[CompletionOutput] CompletionOutput index: int text: str token_ids: List[int] cumulative_logprob: float logprobs: List[float] (可选)

实际使用时,你通常只需要 output.outputs[0].text 就能拿到生成的文本。但如果你在做质量评估或调试,cumulative_logproblogprobs 就很有用了。

经验之谈: 我在做模型对比时,经常用 cumulative_logprob 来判断哪个生成结果更“自信”。数值越大(越接近0),说明模型对这个输出越有把握。

3.4 常见启动参数解析

vLLM 的启动参数非常多,但常用的其实就十几个。我帮你整理了一张表,把最核心的参数列出来。

参数名 类型 默认值 说明
model str 必填 模型名称或本地路径
tensor_parallel_size int 1 张量并行数,多卡时设置。比如 2 表示用 2 张 GPU
dtype str auto 模型精度,可选 float16、bfloat16、float32
max_model_len int 模型默认 最大上下文长度。我建议根据显存手动设置,避免 OOM
gpu_memory_utilization float 0.9 GPU 显存利用率。0.9 表示最多用 90% 显存
trust_remote_code bool False 是否信任远程代码。有些模型需要设为 True
seed int None 随机种子,设置后结果可复现

我来重点说几个参数:

  • tensor_parallel_size:如果你有多张 GPU,这个参数是必设的。我曾经在 4 卡 A100 上跑 70B 模型,设成 4 后,显存刚好够用。
  • gpu_memory_utilization:这个参数很关键。默认 0.9 是安全的,但如果你显存紧张,可以降到 0.8。反过来,如果你确定模型不会爆显存,可以升到 0.95。
  • max_model_len:这个参数我吃过亏。有一次跑长文本任务,没设这个参数,结果模型默认的 8192 长度直接 OOM 了。后来我改成 4096,问题解决。

避坑指南: 我曾经在加载一个自定义模型时,忘了设 trust_remote_code=True,结果报错说找不到配置类。这个参数虽然默认是 False,但很多社区模型都需要它。如果你遇到奇怪的加载错误,先试试这个参数。

最后,给你一个完整的启动示例:

from vllm import LLM

llm = LLM(
    model="Qwen/Qwen2.5-7B-Instruct",
    tensor_parallel_size=1,      # 单卡
    dtype="bfloat16",            # 用 bfloat16 节省显存
    max_model_len=4096,          # 限制最大长度
    gpu_memory_utilization=0.9,  # 显存利用率
    trust_remote_code=True,      # 信任远程代码
    seed=42                      # 固定随机种子
)

嗯,到这里,你已经掌握了 vLLM 的快速启动流程。加载模型、生成文本、理解输出、调参,这四个步骤是后续所有操作的基础。你想想看,是不是比想象中简单?


专注资料整理