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)
相关推荐
池央1 分钟前
CANN GE 深度解析:图编译器的核心优化策略、执行流调度与模型下沉技术原理
人工智能·ci/cd·自动化
七月稻草人4 分钟前
CANN ops-nn:AIGC底层神经网络算力的核心优化引擎
人工智能·神经网络·aigc·cann
种时光的人4 分钟前
CANN仓库核心解读:ops-nn打造AIGC模型的神经网络算子核心支撑
人工智能·神经网络·aigc
晚霞的不甘6 分钟前
守护智能边界:CANN 的 AI 安全机制深度解析
人工智能·安全·语言模型·自然语言处理·前端框架
谢璞8 分钟前
中国AI最疯狂的一周:50亿金元肉搏,争夺未来的突围之战
人工智能
池央8 分钟前
CANN 算子生态的深度演进:稀疏计算支持与 PyPTO 范式的抽象层级
运维·人工智能·信号处理
方见华Richard9 分钟前
世毫九实验室(Shardy Lab)研究成果清单(2025版)
人工智能·经验分享·交互·原型模式·空间计算
Maynor99610 分钟前
OpenClaw 玩家必备:用 AI 自动追踪社区最新动态
java·服务器·人工智能
aini_lovee10 分钟前
MATLAB基于小波技术的图像融合实现
开发语言·人工智能·matlab
ujainu19 分钟前
CANN仓库中的AIGC多模态统一抽象工程:昇腾AI软件栈如何用一套接口驾驭图文音视
人工智能·aigc