常见报错
主线位置:两处。启动时的报错在 KV 池建立之前(参数解析、模型加载、显存测量),对应显存预算;请求时的报错在「模板与分词」之后、进调度之前。本页的原文都取自两个引擎的 Python 代码。打开 Rust 前端(
VLLM_USE_RUST_FRONTEND=1或SGLANG_RUST_SERVER=1)后,模板、分词和一部分长度检查改由 Rust 做,报错原文可能不同,本页没有逐条核对。
版本:vLLM v0.32.0、SGLang v0.5.22
结论:
- 启动期的报错大多是一道算术题:权重、激活、KV 加起来超过预算。先看显存预算的公式,再对报错里的数字。
- 「放不下一个最大长度的请求」,vLLM 在启动时就报;SGLang 不报,而是把单请求上限降到 KV 池大小,等请求来了再拒。
- 请求期的超长报错,vLLM 在前端渲染时查,SGLang 分两道:分词管理器按上下文长度查,调度器再按 KV 池查。
- 小标题是源码里的原文片段,
{…}处是运行时填的数字;去掉了这部分,方便按原文搜索。PyTorch 自己的 CUDA OOM 报错不在这两个仓库里,本页不收。
flowchart TB
subgraph boot["启动"]
parse["参数解析"] --> load["加载权重、分词器"]
load --> prof["测显存 / 算比例"]
prof --> pool["建 KV 池"]
end
subgraph req["每个请求"]
tmpl["聊天模板"] --> tok["分词"]
tok --> len1["长度检查(前端)"]
len1 --> len2["长度检查(调度器,SGLang)"]
len2 --> run["进批、分配 KV"]
end
parse -.->|"max_model_len 超过模型配置<br/>预算互相矛盾"| e1["参数报错"]
load -.->|"分词器加载失败"| e2["分词器报错"]
prof -.->|"空闲显存不够<br/>权重占满预算"| e3["显存报错"]
pool -.->|"放不下一个满长请求(vLLM)"| e4["KV 报错"]
tmpl -.->|"没有模板"| e5["模板报错"]
len1 -.-> e6["超长报错"]
len2 -.-> e6
run -.->|"槽位、KV 分配失败(SGLang)"| e7["运行期 OOM"]
vLLM:启动
is less than desired GPU memory utilization
if init_snapshot.free_memory < requested_memory:
raise ValueError(
f"Free memory on device {init_snapshot.device_} "
# ...
f"is less than desired GPU memory utilization "
f"({cache_config.gpu_memory_utilization}, "
f"{format_gib(requested_memory)} GiB). Decrease GPU memory "
f"utilization or reduce GPU memory used by other processes."
)
- 触发:启动时的空闲显存小于「总显存 ×
gpu_memory_utilization」。比例是对总显存算的,所以卡上有别的进程(另一个 vLLM 实例、桌面、残留进程)就会触发。 - 调:
--gpu-memory-utilization调小到「空闲 / 总量」以下;同一张卡跑两个实例时各给一份,加起来不超过 1。
No available memory for the cache blocks.
vllm/v1/core/kv_cache_utils.py#L1011
- 触发:预算扣掉权重、其他占用、激活峰值和 CUDA graph 估计之后不剩显存。
- 调:
--gpu-memory-utilization调大;--max-num-batched-tokens调小(假前向的 token 数就是它,激活峰值随之变小);权重太大时换量化权重或开张量并行(-tp)。
To serve at least one request with the model's max seq len
vllm/v1/core/kv_cache_utils.py#L1031
raise ValueError(
f"To serve at least one request with the model's max seq len "
f"({max_model_len}), ({format_gib(needed_memory)} GiB KV "
f"cache is needed, which is larger than the available KV cache "
f"memory ({format_gib(available_memory)} GiB). {estimated_msg}"
# ...
- 触发:KV 池放不下一个
max_model_len长的请求。max_model_len默认取模型配置,长上下文模型在小卡上必中:估算下 Llama-3.1-8B 满长 131072 要 16 GiB KV,24 GiB 卡扣掉权重最多剩 7.12 GiB。 - 报错里的
the estimated maximum model length is …是二分搜索出的可用长度(estimate_max_model_len)。 - 调:
--max-model-len设成业务需要的长度或报错给的估计值;或设-1让它自动缩;或--kv-cache-dtype fp8让每 token 的 KV 减半。
Cannot auto-fit max_model_len: not enough GPU memory available to serve even a single token.
vllm/v1/core/kv_cache_utils.py#L2455
- 触发:
--max-model-len -1时,连一个 token 的 KV 都放不下。和上面的No available memory是同一个原因。 - 调:同上,先把预算做大或把权重变小。
is greater than the derived max_model_len
- 触发:手设的
--max-model-len大于模型配置推出的长度(max_position_embeddings等字段,乘上 RoPE 缩放系数,再和分词器的model_max_length取小)。 - 调:改小;确有把握时设
VLLM_ALLOW_LONG_MAX_MODEL_LEN=1。报错原文同时警告:用 RoPE 的模型超出后会得到 nan。
smaller than max_model_len
- 触发:关了分块预填充(
--no-enable-chunked-prefill),又手设了比max_model_len小的--max-num-batched-tokens。不分块时一个 prompt 必须一步算完,预算小于最大长度就意味着长请求永远进不来。 - 调:二选一:打开分块预填充,或把
--max-num-batched-tokens设到不小于--max-model-len。没手设预算时 vLLM 会自动抬(arg_utils.py#L3141),不会报这条。 - 同一函数里还有一条:
max_num_batched_tokens不能小于max_num_seqs(#L329)。
Error in memory profiling.
vllm/v1/worker/gpu_worker.py#L719
- 触发:测显存期间,同一张卡上别的进程释放了显存,测得的「消耗」成了负数。原文建议把 vLLM 放进独立容器。
- 注意它是
assert,Python 带-O运行时这道检查不存在,测量会悄悄出错。
Failed to load the tokenizer. If the tokenizer is a custom tokenizer not yet available in the HuggingFace transformers library
- 触发:分词器类在当前 transformers 里不存在,或者要执行仓库里的分词器代码,而没开
trust_remote_code。 - 调:确认模型仓库可信后加
--trust-remote-code(默认False);或按原文提示升级 transformers。
vLLM:请求
This model's maximum context length is
if len(tokens) > max_input_tokens:
# ...
raise VLLMValidationError(
f"This model's maximum context length is "
f"{self.max_total_tokens} tokens. However, your prompt "
f"contains {qualifier}{token_count} input tokens, which "
f"exceeds this limit even without any output tokens. "
# ...
- 触发:分词后的 prompt 长度超过输入上限(由
max_model_len决定)。分词前还有一道按字符数的粗查,文本超过「输入上限 × 分词器每 token 最多字符数」直接拒,原文开头相同(#L389)。 - 调:服务端调大
--max-model-len(受 KV 池限制,见上一节);客户端缩短输入,或在请求里传truncate_prompt_tokens。
longer than the maximum model length of
vllm/v1/engine/input_processor.py#L589
- 触发:进引擎前的第二道检查。prompt 长度大于
max_model_len;等于时也报,因为至少要留一个输出 token(#L593)。多模态模型的提示里会说明图像 token 也算在内。 - 调:同上。
Please request fewer output tokens.
- 触发:请求里的
max_tokens(或max_completion_tokens)大于模型的总长度上限。 - 调:客户端调小。客户端不传
max_tokens时,vLLM 用「max_model_len− 输入长度」作为上限(api_utils.py#L169),不会触发这条。
As of transformers v4.44, default chat template is no longer allowed, so you must provide a chat template if the tokenizer does not define one.
- 触发:调
/v1/chat/completions,而模型没有聊天模板:启动参数没给,处理器和分词器里都没有,vLLM 内置的兜底模板也没有这个模型(查找顺序见 resolve_chat_template)。常见于基座模型。 - 调:
--chat-template给一个模板文件;或者改用/v1/completions,自己拼 prompt。
SGLang:启动
Loaded weights leave no GPU memory for the KV cache under
python/sglang/srt/mem_cache/kv_cache_configurator.py#L2732
raise ValueError(
f"Loaded weights leave no GPU memory for the KV cache under "
f"--mem-fraction-static={get_schedule().mem_fraction_static}. "
f"Raise --mem-fraction-static above "
f"{suggested_mem_fraction_static:.3f} "
# ...
- 触发:加载完权重(开了投机解码时包括草稿模型)后,空闲显存已经小于「加载前空闲 × (1 −
mem_fraction_static)」。也就是权重本身超过了静态比例。 - 调:按原文给的最小值调大
--mem-fraction-static,再留些 KV 的余量;或换量化权重、开--tp-size。默认比例在小卡上偏低(24 GiB 卡约 0.704),8B bf16 模型只剩约 1.9 GiB 给 KV(估算),更大的模型在这张卡上会直接撞到这条。
Not enough memory. Please try to increase --mem-fraction-static.
python/sglang/srt/model_executor/pool_configurator.py#L93
- 触发:算出的 KV 池 token 数不大于 0。和上一条同源,走的是另一条代码路径(比如各池扣掉固定开销之后)。
- 调:同上。
Failed to load the tokenizer. If the tokenizer is a custom tokenizer not yet available in the HuggingFace transformers library
python/sglang/srt/utils/hf_transformers/tokenizer.py#L203
- 触发、调法和 vLLM 那条相同:
--trust-remote-code(默认False)。同一函数里另一条Failed to load the tokenizer. If you are using a LLaMA V1 model针对 LLaMA V1 的慢速分词器(#L184)。
No chat template found, defaulting to 'string' content format
python/sglang/srt/parser/template_manager.py#L181
- 这是一条
info日志,不是报错:SGLang 在启动时发现分词器没有聊天模板,不拦。之后的/v1/chat/completions请求会在 transformers 套模板时失败,那条报错的原文在 transformers 里,不在 SGLang 仓库。 - 调:
--chat-template。看到这行日志就该补,不必等到请求失败。
SGLang:请求
is longer than the model's context length
python/sglang/srt/managers/tokenizer_manager.py#L1354
- 触发:分词后的输入长度(加上保留 token)不小于
context_len。context_len默认取模型配置,--context-length可改。 - 调:
--allow-auto-truncate打开后不报错,截掉超出的部分并打 warning(#L1346)。默认关。
Requested token count exceeds the model's maximum context length
python/sglang/srt/managers/tokenizer_manager.py#L1377
- 触发:输入加请求的
max_new_tokens超过context_len。只在客户端传了输出上限时检查。 - 调:客户端调小输出上限;
--allow-auto-truncate时改为把max_new_tokens截到剩余长度。
exceeds the maximum allowed length
python/sglang/srt/managers/utils.py#L278
error_msg = (
f"Input length ({len(req.origin_input_ids)} tokens) exceeds "
f"the maximum allowed length ({max_req_input_len} tokens). "
f"Use a shorter input or enable --allow-auto-truncate."
)
- 触发:调度器收请求时的第二道检查(scheduler.py#L3119)。上限
max_req_input_len= min(context_len, KV 池 token 数) − 6(tp_worker.py#L549)。所以输入比上下文长度短、却比 KV 池长时,过得了上一条,过不了这一条。这是 vLLM 在启动时就报的那类问题,SGLang 推到了请求时。 - 调:让 KV 池更大(
--mem-fraction-static、更小的--chunked-prefill-size、--kv-cache-dtype);或--allow-auto-truncate。
Request prompt exceeds the KV memory budget
python/sglang/srt/managers/scheduler.py#L2624
- 触发:给请求定输出上限时,KV 分配器算出「输入本身就放不下」(考虑页对齐、滑动窗口、分块大小),请求直接以 abort 结束。
- 调:同上一条,让 KV 池更大或缩短输入。
SGLang:运行期
alloc_req_slots runs out of memory.
python/sglang/srt/mem_cache/allocation.py#L338
- 触发:请求槽位池(
req_to_token,行数就是max_running_requests)分不出位置。 - 调:原文建议调小
--max-running-requests。
Prefill out of memory. Try to lower your batch size. / Decode out of memory. Try to lower your batch size.
- 触发:给预填充或解码分配 KV 槽位时,驱逐前缀树之后仍不够。正常情况下调度器收请求时的预算和解码前的 retract(见抢占)会先挡住,走到这里说明预估失准。报错后会打印前缀树。
- 调:原文建议减小批,即调小
--max-running-requests;也可以调大--schedule-conservativeness让收请求更保守。哪种负载下会走到这里,待实测(C3-2)。
小结
- vLLM 启动:空闲显存不够预算(调低比例)、预算扣完不剩(调高比例或减小每步 token)、KV 放不下一个满长请求(调小
--max-model-len或设-1)、--max-model-len超过模型配置、关分块时预算小于最大长度。 - vLLM 请求:输入超过
max_model_len(两道检查)、输出上限超过总长度、没有聊天模板(--chat-template)。 - SGLang 启动:权重超过静态比例(调大
--mem-fraction-static)。KV 池小于上下文长度不报错,到请求时以exceeds the maximum allowed length拒掉。没有聊天模板只打一行 info。 - 两边分词器加载失败都指向
--trust-remote-code。 - 打开 Rust 前端后,请求侧的部分报错原文会变,本页未核对。