故障排除¶
本文档概述了您可以考虑的一些故障排查策略。如果您认为自己发现了 Bug,请先搜索现有问题,看看是否已有人报告。如果没有,请提交一个新问题,并提供尽可能多的相关信息。
注意
一旦调试完成,请记得关闭所定义的任何调试环境变量,或者直接启动一个新的 shell,以避免受到残留调试设置的影响。否则,由于启用了调试功能,系统运行可能会变慢。
模型下载时卡住¶
如果模型尚未下载到磁盘,vLLM 会从互联网下载模型,这可能需要一些时间,具体取决于您的网络连接状况。建议先使用 huggingface-cli 下载模型,并将模型所在本地路径传递给 vLLM。通过这种方式,您可以隔离该问题。
从磁盘加载模型时卡住¶
如果模型很大,从磁盘加载可能需要很长时间。请注意模型存放的位置。一些集群在不同节点间共享文件系统(例如分布式文件系统或网络文件系统),这可能会很慢。最好将模型存放在本地磁盘上。此外,请查看 CPU 内存使用情况,当模型过大时,它可能会占用大量 CPU 内存,导致操作系统频繁在磁盘和内存之间进行交换(Swap),从而减慢运行速度。
注意
为了排查模型下载和加载问题,您可以使用 --load-format dummy 参数来跳过加载模型权重。这样,您可以检查模型下载和加载是否是瓶颈所在。
内存溢出 (Out of memory)¶
如果模型过大,无法放入单个 GPU 中,您将会收到内存溢出 (OOM) 错误。请考虑采用这些选项来降低内存消耗。
生成质量发生变化¶
在 v0.8.0 版本中,默认采样参数的来源已在 Pull Request #12622 中进行了更改。在 v0.8.0 之前,默认采样参数来自 vLLM 的一组中性默认值。从 v0.8.0 开始,默认采样参数来自模型创建者提供的 generation_config.json。
在大多数情况下,这应该会带来更高质量的响应,因为模型创建者通常更了解哪些采样参数最适合其模型。然而,在某些情况下,模型创建者提供的默认值可能会导致性能下降。
您可以通过在线模式设置 --generation-config vllm 或在离线模式设置 generation_config="vllm" 来使用旧版默认值,从而确认是否发生了这种情况。如果在尝试后生成质量有所改善,我们建议继续使用 vLLM 默认值,并在 https://hugging-face.cn 上请求模型创建者更新其默认的 generation_config.json,以便产生更高质量的生成结果。
启用更多日志记录¶
如果其他策略无法解决问题,很可能是 vLLM 实例卡在了某个地方。您可以使用以下环境变量来帮助调试问题:
export VLLM_LOGGING_LEVEL=DEBUG以开启更多日志记录。export VLLM_LOG_STATS_INTERVAL=1.以更频繁地获取日志统计信息,从而追踪运行队列、等待队列和缓存命中状态。export CUDA_LAUNCH_BLOCKING=1以识别是哪个 CUDA 内核导致了问题。export NCCL_DEBUG=TRACE以开启 NCCL 的更多日志记录。export VLLM_TRACE_FUNCTION=1以记录所有函数调用以便在日志文件中进行检查,从而确定是哪个函数崩溃或卡住。(警告:此标志会使 token 生成速度减慢 100 倍以上。除非绝对必要,否则请勿使用。)
断点调试¶
如果设置的普通 pdb 断点在子进程中执行,它们可能无法在 vLLM 的代码库中生效。您会遇到类似这样的情况:
File "/usr/local/uv/cpython-3.12.11-linux-x86_64-gnu/lib/python3.12/bdb.py", line 100, in trace_dispatch
return self.dispatch_line(frame)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/uv/cpython-3.12.11-linux-x86_64-gnu/lib/python3.12/bdb.py", line 125, in dispatch_line
if self.quitting: raise BdbQuit
^^^^^^^^^^^^^
bdb.BdbQuit
一种解决方案是使用 forked-pdb。安装命令为 pip install fpdb,并使用类似如下方式设置断点:
另一种选择是完全禁用多进程,使用 VLLM_ENABLE_V1_MULTIPROCESSING 环境变量。这将使调度程序保持在同一个进程中,因此您可以使用标准的 pdb 断点。
网络配置错误¶
如果您有复杂的网络配置,vLLM 实例可能无法获取正确的 IP 地址。您可以找到类似 DEBUG 06-10 21:32:17 parallel_state.py:88] world_size=8 rank=0 local_rank=0 distributed_init_method=tcp://xxx.xxx.xxx.xxx:54641 backend=nccl 的日志,其中的 IP 地址应该是正确的。如果不是,请使用环境变量 export VLLM_HOST_IP=<您的IP地址> 来覆盖该 IP 地址。
您可能还需要设置 export NCCL_SOCKET_IFNAME=<您的网络接口> 和 export GLOO_SOCKET_IFNAME=<您的网络接口> 来指定 IP 地址的网络接口。
self.graph.replay() 附近报错¶
如果 vLLM 崩溃且错误追踪显示在 vllm/worker/model_runner.py 中的 self.graph.replay() 附近,说明这是 CUDAGraph 内部的 CUDA 错误。为了确定导致错误的具体 CUDA 操作,您可以在命令行中添加 --enforce-eager,或者在 LLM 类中设置 enforce_eager=True,以禁用 CUDAGraph 优化并隔离导致错误的具体 CUDA 操作。
硬件/驱动程序错误¶
如果无法建立 GPU/CPU 通信,您可以使用以下 Python 脚本并按照下方的说明操作,以确认 GPU/CPU 通信是否正常工作。
代码
# Test PyTorch NCCL
import torch
import torch.distributed as dist
dist.init_process_group(backend="nccl")
local_rank = dist.get_rank() % torch.accelerator.device_count()
torch.accelerator.set_device_index(local_rank)
data = torch.FloatTensor([1,] * 128).to("cuda")
dist.all_reduce(data, op=dist.ReduceOp.SUM)
torch.accelerator.synchronize()
value = data.mean().item()
world_size = dist.get_world_size()
assert value == world_size, f"Expected {world_size}, got {value}"
print("PyTorch NCCL is successful!")
# Test PyTorch GLOO
gloo_group = dist.new_group(ranks=list(range(world_size)), backend="gloo")
cpu_data = torch.FloatTensor([1,] * 128)
dist.all_reduce(cpu_data, op=dist.ReduceOp.SUM, group=gloo_group)
value = cpu_data.mean().item()
assert value == world_size, f"Expected {world_size}, got {value}"
print("PyTorch GLOO is successful!")
if world_size <= 1:
exit()
# Test vLLM NCCL, with cuda graph
from vllm.distributed.device_communicators.pynccl import PyNcclCommunicator
pynccl = PyNcclCommunicator(group=gloo_group, device=local_rank)
# pynccl is enabled by default for 0.6.5+,
# but for 0.6.4 and below, we need to enable it manually.
# keep the code for backward compatibility when because people
# prefer to read the latest documentation.
pynccl.disabled = False
s = torch.cuda.Stream()
with torch.cuda.stream(s):
data.fill_(1)
out = pynccl.all_reduce(data, stream=s)
value = out.mean().item()
assert value == world_size, f"Expected {world_size}, got {value}"
print("vLLM NCCL is successful!")
g = torch.cuda.CUDAGraph()
with torch.cuda.graph(cuda_graph=g, stream=s):
out = pynccl.all_reduce(data, stream=torch.cuda.current_stream())
data.fill_(1)
g.replay()
torch.cuda.current_stream().synchronize()
value = out.mean().item()
assert value == world_size, f"Expected {world_size}, got {value}"
print("vLLM NCCL with cuda graph is successful!")
dist.destroy_process_group(gloo_group)
dist.destroy_process_group()
如果您是在单节点上进行测试,请将 --nproc-per-node 调整为您要使用的 GPU 数量。
如果您是在多节点上进行测试,请根据您的配置调整 --nproc-per-node 和 --nnodes,并将 MASTER_ADDR 设置为所有节点均可访问的主节点 IP 地址和端口(例如 10.0.0.1:29400)。然后运行:
NCCL_DEBUG=TRACE torchrun --nnodes 2 \
--nproc-per-node=2 \
--rdzv_backend=static \
--rdzv_endpoint=$MASTER_ADDR \
--node-rank $NODE_RANK test.py
将 MASTER_ADDR 设置为所有节点均可访问的主节点 IP 地址和端口(例如 10.0.0.1:29400)。将 NODE_RANK 在主节点上设置为 0,在工作节点上分别设置为 1、2 等。根据您的配置调整 --nproc-per-node 和 --nnodes。
注意
我们使用 --rdzv_backend=static 代替 c10d,因为在多节点配置中,c10d 集合点后端可能会因 DNS 解析错误而失败(参见 pytorch/pytorch#85300)。static 后端通过要求显式指定节点排名来避免此问题。
如果脚本运行成功,您应该会看到消息 sanity check is successful!。
如果测试脚本卡住或崩溃,通常意味着硬件/驱动程序在某些方面存在问题。您应该尝试联系您的系统管理员或硬件供应商以获取进一步的协助。作为一个常见的解决方法,您可以尝试调整一些 NCCL 环境变量,例如 export NCCL_P2P_DISABLE=1,看看是否有帮助。请查阅 其文档 以获取更多信息。请仅将这些环境变量作为临时的权宜之计,因为它们可能会影响系统的性能。最好的解决方案仍然是修复硬件/驱动程序,以便测试脚本可以成功运行。
Python 多进程¶
RuntimeError 异常¶
如果您在日志中看到类似这样的警告:
WARNING 12-11 14:50:37 multiproc_worker_utils.py:281] CUDA was previously
initialized. We must use the `spawn` multiprocessing start method. Setting
VLLM_WORKER_MULTIPROC_METHOD to 'spawn'. See
https://docs.vllm.com.cn/en/latest/usage/troubleshooting.html#python-multiprocessing
for more information.
或者 Python 抛出的错误如下所示:
日志
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
To fix this issue, refer to the "Safe importing of main module"
section in https://docs.pythonlang.cn/3/library/multiprocessing.html
那么您必须更新 Python 代码,将 vllm 的使用放在 if __name__ == '__main__': 代码块内。例如,不要这样写:
尝试改用以下方式:
torch.compile 错误¶
vLLM 很大程度上依赖 torch.compile 来优化模型以获得更好的性能,这引入了对 torch.compile 功能和 triton 库的依赖。默认情况下,我们使用 torch.compile 来 优化模型中的某些函数。在运行 vLLM 之前,您可以通过运行以下脚本来检查 torch.compile 是否按预期工作:
代码
如果它抛出来自 torch/_inductor 目录的错误,通常意味着您拥有一个与您所使用的 PyTorch 版本不兼容的自定义 triton 库。例如,请参见 Issue #12219。
模型无法被检测¶
如果您看到类似这样的错误:
File "vllm/model_executor/models/registry.py", line xxx, in _raise_for_unsupported
raise ValueError(
ValueError: Model architectures ['<arch>'] failed to be inspected. Please check the logs for more details.
这意味着 vLLM 无法导入模型文件。通常,这与缺失的依赖项或 vLLM 构建中过时的二进制文件有关。请仔细阅读日志,以确定错误的根本原因。
不支持该模型¶
如果您看到类似这样的错误:
Traceback (most recent call last):
...
File "vllm/model_executor/models/registry.py", line xxx, in inspect_model_cls
for arch in architectures:
TypeError: 'NoneType' object is not iterable
或
File "vllm/model_executor/models/registry.py", line xxx, in _raise_for_unsupported
raise ValueError(
ValueError: Model architectures ['<arch>'] are not supported for now. Supported architectures: [...]
但您确定该模型在支持的模型列表中,则 vLLM 的模型解析可能存在问题。在这种情况下,请按照这些步骤明确指定该模型的 vLLM 实现。
设备类型推断失败¶
如果您看到类似 RuntimeError: Failed to infer device type 的错误,说明 vLLM 无法推断运行环境的设备类型。您可以查看代码,了解 vLLM 是如何推断设备类型以及为何未按预期工作。在此 PR 之后,您还可以设置环境变量 VLLM_LOGGING_LEVEL=DEBUG 以查看更详细的日志,从而帮助调试该问题。
NCCL 错误:ncclCommInitRank 期间发生未处理的系统错误¶
如果您的服务工作负载使用 GPUDirect RDMA 进行跨多节点的分布式服务,并在 ncclCommInitRank 期间遇到错误,且即使设置了 NCCL_DEBUG=INFO 也没有清晰的错误消息,它可能看起来如下所示:
Error executing method 'init_device'. This might cause deadlock in distributed execution.
Traceback (most recent call last):
...
File "/usr/local/lib/python3.12/dist-packages/vllm/distributed/device_communicators/pynccl.py", line 99, in __init__
self.comm: ncclComm_t = self.nccl.ncclCommInitRank(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/dist-packages/vllm/distributed/device_communicators/pynccl_wrapper.py", line 277, in ncclCommInitRank
self.NCCL_CHECK(self._funcs["ncclCommInitRank"](ctypes.byref(comm),
File "/usr/local/lib/python3.12/dist-packages/vllm/distributed/device_communicators/pynccl_wrapper.py", line 256, in NCCL_CHECK
raise RuntimeError(f"NCCL error: {error_str}")
RuntimeError: NCCL error: unhandled system error (run with NCCL_DEBUG=INFO for details)
...
这表明 vLLM 初始化 NCCL 通信器失败,可能是因为缺少 IPC_LOCK Linux 功能或未挂载 /dev/shm。请参考 启用 GPUDirect RDMA 以获取关于为 GPUDirect RDMA 正确配置环境的指南。
CUDA 错误:提供的 PTX 使用了不支持的工具链编译¶
如果您看到类似 RuntimeError: CUDA error: the provided PTX was compiled with an unsupported toolchain 的错误,说明 vLLM wheels 中的 CUDA PTX 是用您系统不支持的工具链编译的。如果您收到错误 RuntimeError: The NVIDIA driver on your system is too old,本节同样适用。
发布的 vLLM wheels 是使用特定版本的 CUDA 工具包编译的,编译后的代码可能无法在较低版本的 CUDA 驱动程序上运行。请阅读 CUDA 兼容性 以获取更多详细信息。这仅在部分专业级和数据中心 NVIDIA GPU 上受支持。
如果您使用的是 vLLM 官方 Docker 镜像,可以通过在 docker run 命令中添加 -e VLLM_ENABLE_CUDA_COMPATIBILITY=1 来解决此问题。这将启用预安装的 CUDA 向前兼容库。
如果您在 Docker 外部运行 vLLM,解决方法是启用 CUDA 存储库,并通过软件包管理器安装 cuda-compat 软件包。例如,在 Ubuntu 上,您可以运行 sudo apt-get install cuda-compat-12-9,然后设置 export VLLM_ENABLE_CUDA_COMPATIBILITY=1 和 export VLLM_CUDA_COMPATIBILITY_PATH="/usr/local/cuda-12.9/compat"。
在 Conda 上,您可以安装 conda-forge::cuda-compat 软件包(例如 conda install -c conda-forge cuda-compat=12.9),然后在激活环境后,设置 export VLLM_ENABLE_CUDA_COMPATIBILITY=1 和 export VLLM_CUDA_COMPATIBILITY_PATH="${CONDA_PREFIX}/cuda-compat"。
您可以通过运行一个通过 vLLM 初始化 CUDA 的最小 Python 脚本来验证配置是否生效:
export VLLM_ENABLE_CUDA_COMPATIBILITY=1
export VLLM_CUDA_COMPATIBILITY_PATH="/usr/local/cuda-12.9/compat"
python3 - << 'EOF'
import vllm
import torch
print(f"CUDA available: {torch.cuda.is_available()}")
print(f"CUDA device count: {torch.accelerator.device_count()}")
EOF
请注意,此处我们以 CUDA 12.9 为例,如果 vLLM 的默认 CUDA 版本更高,您可能需要安装更高版本的 cuda-compat 软件包。
ptxas 致命错误:选项 'gpu-name' 中未定义值 'sm_110a'¶
如果您在 CUDA 13 上使用 triton 内核,可能会看到类似 ptxas fatal: Value 'sm_110a' is not defined for option 'gpu-name' 的错误。
(EngineCore_0 pid=9492) triton.runtime.errors.PTXASError: PTXAS error: Internal Triton PTX codegen error
(EngineCore_0 pid=9492) `ptxas` stderr:
(EngineCore_0 pid=9492) ptxas fatal : Value 'sm_110a' is not defined for option 'gpu-name'
(EngineCore_0 pid=9492)
(EngineCore_0 pid=9492) Repro command: /home/jetson/.venv/lib/python3.12/site-packages/triton/backends/nvidia/bin/ptxas -lineinfo -v --gpu-name=sm_110a /tmp/tmp95oy_b9d.ptx -o /tmp/tmp95oy_b9d.ptx.o
(EngineCore_0 pid=9492)
outputs = self.engine_core.get_output()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jetson/.venv/lib/python3.12/site-packages/vllm/v1/engine/core_client.py", line 668, in get_output
raise self._format_exception(outputs) from None
vllm.v1.engine.exceptions.EngineDeadError: EngineCore encountered an issue. See stack trace (above) for the root cause.
这意味着 triton 包中的 ptxas 与您的设备不兼容。您需要手动设置 TRITON_PTXAS_PATH 环境变量以使用 CUDA 工具包的 ptxas。
export CUDA_HOME=/usr/local/cuda
export TRITON_PTXAS_PATH="${CUDA_HOME}/bin/ptxas"
export PATH="${CUDA_HOME}/bin:$PATH"
已知问题¶
- 在
v0.5.2、v0.5.3和v0.5.3.post1版本中,存在由 zmq 引起的 Bug,根据机器配置的不同,这偶尔会导致 vLLM 卡住。解决方案是升级到最新版本的vllm以包含此 修复。 - 为了解决旧版 NCCL 中的内存开销问题(参见 Bug),vLLM 版本
>= 0.4.3, <= 0.10.1.1会设置环境变量NCCL_CUMEM_ENABLE=0。连接到 vLLM 的外部进程也需要设置此变量以防止卡住或崩溃。由于底层的 NCCL Bug 已在 NCCL 2.22.3 中修复,因此在较新的 vLLM 版本中移除了此覆盖设置,以允许进行 NCCL 性能优化。 - 在一些 PCIe 机器(例如没有 NVLink 的机器)上,如果您看到错误
transport/shm.cc:590 NCCL WARN Cuda failure 217 'peer access is not supported between these two devices',这很可能是驱动程序 Bug 引起的。有关更多详细信息,请参阅 此问题。在这种情况下,您可以尝试设置NCCL_CUMEM_HOST_ENABLE=0以禁用该功能,或将驱动程序升级到最新版本。