
文章目录
-
- 遇到报错如下
-
- 最简单直接的解决方案(强烈推荐)
- 其他可选优化(如果还想挤更多空间)
- 验证一下你的显卡显存
- 推荐设置
- [为什么 12GB GPU 上不建议用太大上下文?](#为什么 12GB GPU 上不建议用太大上下文?)
- [所运行代码 - Qwen3VL - vllm 离线推理](#所运行代码 - Qwen3VL - vllm 离线推理)
- [❤️ 一起学AI](#❤️ 一起学AI)
遇到报错如下
ValueError: To serve at least one request with the models's max seq len (262144), (36.00 GiB KV cache is needed, which is larger than the available KV cache memory (7.84 GiB). Based on the available memory, the estimated maximum model length is 57104. Try increasing `gpu_memory_utilization` or decreasing `max_model_len` when initializing the engine.
raise RuntimeError(
RuntimeError: Engine core initialization failed. See root cause above. Failed core proc(s): {}
你的报错核心是 KV cache 内存不足:
- 模型默认 max seq len = 262144(超长上下文)
- 要支持这么长的序列,需要 36 GiB 的 KV cache
- 但你的 GPU 只预留了 7.84 GiB 用于 KV cache(说明你大概是 12GB 左右的显卡,比如 RTX 3060/4060/4070 这种常见卡)
vLLM 默认 gpu_memory_utilization=0.9,但模型权重 + 多模态部分(视觉编码器)占用了大部分显存,留给 KV cache 的空间很少,导致只能支持最大 ~57104 tokens。
最简单直接的解决方案(强烈推荐)
在你的脚本 vLLM_Qwen3-VL_4B_infer.py 第 71 行创建 LLM 的地方,手动限制 max_model_len 为一个合理值(比如 32768 或 65536,够日常图文/视频推理用了):
python
llm = LLM(
model="/home/moli/.cache/modelscope/hub/models/Qwen/Qwen3-VL-4B-Instruct",
mm_encoder_tp_mode="data",
disable_log_stats=True,
max_model_len=32768, # ← 加这一行!关键
# gpu_memory_utilization=0.95, # 可选:再挤一点显存(慎用,容易 OOM)
# 其他参数保持不变
)
- 32768:安全值,基本所有场景够用(包括多张图 + 长对话)
- 如果你偶尔需要更长,可以试 65536,但先看启动是否 OOM
- Qwen3-VL-4B 实际常用上下文远低于 262k,限制后性能几乎无影响
改完保存,直接重新运行脚本,这次初始化就能通过。
其他可选优化(如果还想挤更多空间)
-
提高 gpu_memory_utilization(默认 0.9):
pythongpu_memory_utilization=0.95, # 或 0.97,挤出更多 KV cache注意:太高容易启动时 OOM,先从小步调(0.92 → 0.95 → 0.97)
-
组合使用(推荐最终配置):
pythonllm = LLM( model=..., max_model_len=65536, # 目标上下文长度 gpu_memory_utilization=0.95, # 多挤点显存 mm_encoder_tp_mode="data", # enforce_eager=True, # 可选:如果 CUDA Graph 占额外显存,加这个禁用(略慢) ) -
如果还是不够:
- 用 FP8 量化版模型(如果有的话):
Qwen/Qwen3-VL-4B-Instruct-FP8,权重更小,留更多 KV cache - 或者换成更小的 Qwen3-VL-2B(如果项目允许)
- 用 FP8 量化版模型(如果有的话):
验证一下你的显卡显存
运行前先查查:
bash
nvidia-smi
看总显存多少 GiB,通常 12GB 卡留给 KV cache 就 7-8GB,很正常。
改完 max_model_len=32768 后,基本 100% 能跑起来。Qwen3-VL-4B 在小卡上表现已经很强了,图文理解速度也快。
如果你只是用来理解图像内容(比如单张图片的描述、OCR 文字提取、物体识别等),不需要处理长对话或多轮交互,那么上下文长度(max_model_len)不需要太大。Qwen3-VL-4B 的视觉部分(多模态嵌入)通常只需几百到几千个 tokens,就能完美处理单张图片。
推荐设置
-
最合适的大小:8192 tokens(8K)
-
为什么合适?
- 单张图片的视觉 tokens 通常在 256-1024 个(取决于图片分辨率和细节)。
- 加上你的提示文本(prompt,比如"描述这张图片")和生成的输出,轻松控制在 2K-4K tokens 内。
够用!不会浪费资源,还能保证速度快(生成更快,显存压力小)。
-
在你的 vLLM 脚本中设置:
pythonllm = LLM( model="/home/moli/.cache/modelscope/hub/models/Qwen/Qwen3-VL-4B-Instruct", max_model_len=8192, # ← 就改成这个 gpu_memory_utilization=0.95, mm_encoder_tp_mode="data", # 其他参数不变 )
-
-
如果图片很复杂(高分辨率、多物体) :可以上调到 16384 tokens(16K)
- 这样能处理更精细的细节,比如多张小图或带文字的文档。
- 但别超过这个,12GB 显卡上 KV cache 会吃紧。
为什么 12GB GPU 上不建议用太大上下文?
- 模型权重 + 视觉编码器已经占了 ~8-9GB。
- KV cache(用于存储上下文)每 1K tokens 大约吃 100-200MB 显存(取决于 dtype)。
- 如果设成默认的 262144(256K),KV cache 需要 30+GB,启动就 OOM。
- 用 8192:KV cache 只占 ~1-2GB,总显存用量控制在 10-11GB 内,留点缓冲防崩溃。
所运行代码 - Qwen3VL - vllm 离线推理
python
# -*- coding: utf-8 -*-
import torch
from qwen_vl_utils import process_vision_info
from transformers import AutoProcessor
from vllm import LLM, SamplingParams
import os
os.environ['VLLM_WORKER_MULTIPROC_METHOD'] = 'spawn'
def prepare_inputs_for_vllm(messages, processor):
text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
# qwen_vl_utils 0.0.14+ reqired
image_inputs, video_inputs, video_kwargs = process_vision_info(
messages,
image_patch_size=processor.image_processor.patch_size,
return_video_kwargs=True,
return_video_metadata=True
)
print(f"video_kwargs: {video_kwargs}")
mm_data = {}
if image_inputs is not None:
mm_data['image'] = image_inputs
if video_inputs is not None:
mm_data['video'] = video_inputs
return {
'prompt': text,
'multi_modal_data': mm_data,
'mm_processor_kwargs': video_kwargs
}
if __name__ == '__main__':
# messages = [
# {
# "role": "user",
# "content": [
# {
# "type": "video",
# "video": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-VL/space_woaudio.mp4",
# },
# {"type": "text", "text": "这段视频有多长"},
# ],
# }
# ]
messages = [
{
"role": "user",
"content": [
{
"type": "image",
"image": "https://ofasys-multimodal-wlcb-3-toshanghai.oss-accelerate.aliyuncs.com/wpf272043/keepme/image/receipt.png",
},
{"type": "text", "text": "Read all the text in the image."},
],
}
]
# TODO: change to your own checkpoint path
#checkpoint_path = "Qwen/Qwen3-VL-235B-A22B-Instruct-FP8"
checkpoint_path = "Qwen/Qwen3-VL-4B-Instruct"
processor = AutoProcessor.from_pretrained(checkpoint_path)
inputs = [prepare_inputs_for_vllm(message, processor) for message in [messages]]
llm = LLM(
model=checkpoint_path,
max_model_len=8192,
gpu_memory_utilization=0.9, # 多挤点显存
mm_encoder_tp_mode="data",
# 小模型不需要专家并行
enable_expert_parallel=False,
tensor_parallel_size=torch.cuda.device_count(),
seed=0
)
sampling_params = SamplingParams(
temperature=0,
max_tokens=1024,
top_k=-1,
stop_token_ids=[],
)
for i, input_ in enumerate(inputs):
print()
print('=' * 40)
print(f"Inputs[{i}]: {input_['prompt']=!r}")
print('\n' + '>' * 40)
outputs = llm.generate(inputs, sampling_params=sampling_params)
for i, output in enumerate(outputs):
generated_text = output.outputs[0].text
print()
print('=' * 40)
print(f"Generated text: {generated_text!r}")
❤️ 一起学AI
- ❤️ 如果文章对你有些许帮助、蟹蟹各位读者大大点赞、评论鼓励博主的每一分认真创作
