3. 离线推理基础:vLLM的LLM类、模型加载与生成参数详解

好,咱们进入正题。这一章我打算把vLLM离线推理最核心的几个概念讲透。说白了,就是让你能真正上手跑通一条文本生成任务。我刚开始接触vLLM时,也踩过不少坑,比如参数调了半天效果不对,或者模型加载失败。今天咱们就把这些基础打牢。

3.1 vLLM的LLM类:离线推理的入口

vLLM里最重要的类就是LLM。你可以把它理解成一个“大模型管家”。你告诉它模型在哪、用什么配置,它帮你搞定加载、推理、资源管理这些脏活累活。

我个人习惯把LLM类实例化放在脚本最前面,因为它的初始化比较耗时。一旦初始化完成,后续的推理调用就非常快了。

核心要点: LLM类是线程安全的,可以并发调用。但注意,它内部会占用显存,所以别开太多实例。

3.2 从Hugging Face加载模型

加载模型有两种常见方式:直接从HF Hub拉取,或者从本地路径加载。我建议你第一次用的时候,先试试从HF Hub拉取,因为vLLM会自动处理模型格式转换。

from vllm import LLM

# 方式一:从HF Hub加载(推荐)
llm = LLM(model="Qwen/Qwen2.5-7B-Instruct")

# 方式二:从本地路径加载
llm = LLM(model="/path/to/your/model")

嗯,这里要注意一点。vLLM对模型格式有要求,必须是SafeTensors格式。如果你从HF拉取,它自动就是这种格式。但如果你自己下载的模型是bin格式,需要先转换一下。我曾经因为这个问题折腾了半天,后来发现vLLM官方提供了转换脚本。

小技巧: 加载时可以指定trust_remote_code=True,有些模型需要这个参数才能正常加载。

3.3 单条文本生成:最简单的推理

模型加载好了,接下来就是生成文本。vLLM的API设计得很简洁,你只需要调用llm.generate()方法。

from vllm import SamplingParams

# 定义生成参数
sampling_params = SamplingParams(temperature=0.7, top_p=0.9, max_tokens=512)

# 单条文本生成
prompt = "请用中文解释什么是量子计算。"
outputs = llm.generate([prompt], sampling_params)

# 获取结果
for output in outputs:
    generated_text = output.outputs[0].text
    print(generated_text)

你看,代码就这么几行。但这里有个坑:llm.generate()接收的是一个列表,即使你只生成一条,也要用列表包起来。我刚开始写的时候经常忘记,结果报错说类型不匹配。

3.4 生成参数详解:temperature, top_p, max_tokens

这三个参数是控制生成质量的关键。咱们一个一个说。

3.4.1 temperature(温度)

temperature控制生成结果的随机性。值越低,模型越倾向于选择概率最高的词,结果更确定;值越高,模型越可能选择概率较低的词,结果更多样。

temperature值 效果 适用场景
0.1 - 0.3 非常确定,几乎每次结果一样 代码生成、数学推理
0.5 - 0.7 平衡,有一定多样性 一般对话、文本摘要
0.8 - 1.0 高随机性,结果多样 创意写作、故事生成

我个人习惯在代码生成任务里用0.1,在对话任务里用0.7。你想想看,如果写代码时模型每次都给你不同的答案,那得多崩溃。

3.4.2 top_p(核采样)

top_p是另一种控制随机性的方式。它只从累积概率达到p的词汇中采样。比如top_p=0.9,就只从概率最高的、加起来占90%的那些词里选。

为什么需要top_p?因为有时候temperature调高了,模型可能会选到一些概率极低的词,导致生成结果很奇怪。top_p相当于加了一个安全网。

经验之谈: 我建议你同时使用temperature和top_p,而不是只用其中一个。比如temperature=0.7, top_p=0.9就是一个很常用的组合。

3.4.3 max_tokens(最大生成长度)

这个参数最简单,就是限制模型最多生成多少个token。注意,是token不是汉字。一个汉字大约对应1-2个token。

设置max_tokens时,要考虑你的任务类型:

  • 短文本生成(如标题):50-100 tokens
  • 中等长度(如段落):200-500 tokens
  • 长文本(如文章):1000-2000 tokens

注意: max_tokens设置得太大,会占用更多显存,而且生成时间会变长。我曾经在生成长文档时设了4096,结果显存直接爆了。建议根据实际需求合理设置。

3.5 知识体系结构图

下面这张图展示了本章的核心逻辑,你可以对照着理解:

vLLM离线推理核心流程 1. 加载模型 LLM(model="...") 2. 设置参数 SamplingParams(...) 3. 生成文本 llm.generate() 生成参数详解 temperature 控制随机性 低→确定,高→多样 常用:0.1 ~ 1.0 top_p 核采样 从高概率词中采样 常用:0.8 ~ 0.95 max_tokens 最大生成长度 限制输出token数 常用:100 ~ 2000

3.6 完整示例:跑通一条推理

最后,给你一个完整的示例代码,你可以直接复制运行:

from vllm import LLM, SamplingParams

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

# 2. 设置参数
sampling_params = SamplingParams(
    temperature=0.7,
    top_p=0.9,
    max_tokens=512
)

# 3. 生成文本
prompt = "请用通俗的语言解释什么是机器学习。"
outputs = llm.generate([prompt], sampling_params)

# 4. 输出结果
for output in outputs:
    print(f"输入: {output.prompt}")
    print(f"输出: {output.outputs[0].text}")

运行这段代码,你就能看到模型生成的文本了。如果遇到显存不足的问题,可以试试加载小一点的模型,比如Qwen/Qwen2.5-1.5B-Instruct

避坑指南: 我曾经在Jupyter Notebook里重复运行LLM()初始化,结果显存越占越多。建议只初始化一次,后续推理复用同一个实例。

好了,这一章的内容就到这里。你掌握了LLM类的使用、模型加载、单条生成和三个核心参数。这些是离线推理的基石,后面的章节会在这个基础上做更多有意思的事情。


公众号:蓝海资料掘金营,微信deep3321