5090显卡,基于vllm完成大模型推理

背景

前一张显卡是48GB,运行 Qwen/Qwen3-30B-A3B-Instruct-2507-fp8模型。在我换到5090显卡后,显存就不足以运行原先的模型了。

为了充分利用好5090显卡的显存容量,我选择了下述两个模型:

  • models/Qwen--Qwen3-30B-A3B-GPTQ-Int4
  • models/cpatonn--Qwen3-30B-A3B-Instruct-2507-AWQ-4bit

这两个模型的磁盘占用均不到20GB,然而我在使用运行模型的过程中均遇到了OOM,显存空间不够的崩溃。按理说32G的显存应该够用。我发现模型在推理的过程中除了要保存模型的参数,还要保存KV cache一些中间状态所以就导致了显存不够。解决方案就是设置降低模型的token长度,就可解决。

VLLM

推理脚本

vLLM 采用了一种叫做 PagedAttention 的技术,它会像操作系统管理内存一样,将 GPU 显存划分为一个个固定大小的 "页面"。

在推理开始前,vLLM 会根据你设定的 max_model_len 和 batch_size,一次性地、预先分配好 足够容纳所有可能 token 的 KV Cache 显存空间。它会假设每个序列都会达到 max_model_len 的长度,并按此最大值来预留空间。

对短输入的影响

即使你的输入序列很短(比如只有 100 个 token),vLLM 依然已经为它在显存中预留了 max_model_len 个位置。

内存带宽开销:虽然实际只使用了 100 个位置,但 GPU 在访问这些缓存时,其内存控制器的访问模式和带宽占用,在某种程度上依然受到为 max_model_len 预分配的大块连续内存的影响。管理一个巨大的、大部分是空的缓存,本身就比管理一个大小合适的缓存要消耗更多的 "管理成本"。

并行计算效率:GPU 是为并行计算设计的。当 max_model_len 很大时,即使实际数据很短,一些为处理长序列而优化的并行计算单元(如 Tensor Cores)可能无法被充分利用,或者需要执行一些额外的逻辑来处理 "空" 的数据,从而影响了整体效率。

现代深度学习框架(如 PyTorch/TensorFlow)在执行计算时,会先构建一个 "计算图",它定义了所有操作的执行顺序和依赖关系。

  • 静态计算图:vLLM 为了追求极致性能,会在启动时根据 max_model_len 等参数,预先构建并 "固化" 一个最优的计算图。这个图一旦生成,在整个推理过程中就不会再改变。
  • 长序列的计算图开销:一个为 max_model_len=8192 构建的计算图,其内部的矩阵乘法、循环等操作的维度都是按照 8192 来优化的。当你用这个图去处理一个很短的序列时,这些为长序列设计的计算步骤中,有一部分就成了 "多余" 的开销。
  • 更优的短序列计算图:当你将 max_model_len 降低到 2048,vLLM 会构建一个全新的、为 2048 长度优化的计算图。这个新图的计算步骤更紧凑,循环次数更少,内存访问模式更高效,因此即使对于短输入,执行这个 "小而美" 的计算图也会比执行那个 "大而全" 的计算图要快得多。

max_model_len:规定了模型在单次推理过程中所能处理的输入序列长度和输出序列长度之和的上限。设置小一点,显存是够用的。

python 复制代码
from vllm import LLM, SamplingParams

prompts = [
    "Hello, who are you?",
    "The president of the United States is",
    "The capital of France is",
    "The future of AI is",
]

sampling_params = SamplingParams(temperature=0.8, top_p=0.95)

# model_name = "cpatonn/Qwen3-30B-A3B-Instruct-2507-AWQ-4bit"
model_name = "Qwen/Qwen3-30B-A3B-GPTQ-Int4"

llm = LLM(
    model=model_name, 
    gpu_memory_utilization=0.9,
    #  max_num_seqs=32, 
    # max_model_len=8192
    max_model_len=2048
)
outputs = llm.generate(prompts, sampling_params)

for output in outputs:
    prompt = output.prompt
    generated_text = output.outputs[0].text
    print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")

能成功运行,显存占用也达到了31.1G,再多一点,显存也不够用了。

API部署

同样也需要指定max_model_len参数

复制代码
vllm serve Qwen/Qwen3-30B-A3B-GPTQ-Int4 --max_model_len 512

langchain调用API

python 复制代码
import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser


# 1. 配置 LLM
# 使用 ChatOpenAI 并指向本地的 vLLM OpenAI 兼容接口
llm = ChatOpenAI(
    # model="Qwen/Qwen3-30B-A3B-GPTQ-Int4",  # 与实际模型对应
    model="cpatonn/Qwen3-30B-A3B-Instruct-2507-AWQ-4bit",  # 与实际模型对应
    base_url="http://localhost:8000/v1",  # 关键:指向本地 vLLM API 服务
    api_key="dummy_key",  # vLLM 服务通常不需要真实密钥,填写任意非空字符串即可
    temperature=0.7,
    max_tokens=2025, # 需要比设置的2048小一点
    # max_completion_tokens=128
)

# 2. 创建 Prompt
# 使用新的 ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个 helpful 的助手。"),
    ("user", "请用中文回答以下问题: {question}")
])

# 3. 创建输出解析器
output_parser = StrOutputParser()

# 4. 使用 LCEL 语法创建 Chain
chain = prompt | llm | output_parser

# 5. 运行 Chain
response = chain.invoke({"question": "什么是大语言模型?"})

print(response)
相关推荐
水如烟5 小时前
孤能子视角:“组织行为学–组织文化“
人工智能
大山同学5 小时前
图片补全-Context Encoder
人工智能·机器学习·计算机视觉
薛定谔的猫19825 小时前
十七、用 GPT2 中文对联模型实现经典上联自动对下联:
人工智能·深度学习·gpt2·大模型 训练 调优
壮Sir不壮5 小时前
2026年奇点:Clawdbot引爆个人AI代理
人工智能·ai·大模型·claude·clawdbot·moltbot·openclaw
PaperRed ai写作降重助手6 小时前
高性价比 AI 论文写作软件推荐:2026 年预算友好型
人工智能·aigc·论文·写作·ai写作·智能降重
玉梅小洋6 小时前
Claude Code 从入门到精通(七):Sub Agent 与 Skill 终极PK
人工智能·ai·大模型·ai编程·claude·ai工具
-嘟囔着拯救世界-6 小时前
【保姆级教程】Win11 下从零部署 Claude Code:本地环境配置 + VSCode 可视化界面全流程指南
人工智能·vscode·ai·编辑器·html5·ai编程·claude code
正见TrueView6 小时前
程一笑的价值选择:AI金玉其外,“收割”老人败絮其中
人工智能
Imm7776 小时前
中国知名的车膜品牌推荐几家
人工智能·python
风静如云6 小时前
Claude Code:进入dash模式
人工智能