故障排除¶
本文档概述了一些您可以考虑的故障排除策略。如果您认为发现了 bug,请先 搜索现有问题,看看是否已报告。如果没有,请 提交新问题,并提供尽可能多的相关信息。
注意
一旦您解决了问题,请记住关闭任何已定义的调试环境变量,或简单地启动一个新 shell,以避免受残留调试设置的影响。否则,系统可能会因为启用了调试功能而变慢。
下载模型时卡住¶
如果模型尚未下载到磁盘,vLLM 将会从互联网下载它,这可能需要时间,并且取决于您的互联网连接。建议使用 huggingface-cli 预先下载模型,然后将模型的本地路径传递给 vLLM。这样,您可以隔离问题。
从磁盘加载模型时卡住¶
如果模型很大,从磁盘加载它可能需要很长时间。注意您存储模型的位置。有些集群在节点之间有共享文件系统,例如分布式文件系统或网络文件系统,这可能很慢。最好将模型存储在本地磁盘上。此外,要注意 CPU 内存使用情况,当模型太大时,它可能会占用大量 CPU 内存,导致操作系统变慢,因为它需要频繁在磁盘和内存之间进行交换。
注意
要隔离模型下载和加载问题,您可以使用 --load-format dummy 参数来跳过加载模型权重。这样,您可以检查下载和加载模型是否是瓶颈。
内存不足¶
如果模型太大而无法放入单个 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以记录所有函数调用,以便在日志文件中进行检查,了解哪个函数崩溃或卡住。(警告:此标志会将令牌生成速度降低 **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=<your_ip_address> 覆盖 IP 地址。
您可能还需要设置 export NCCL_SOCKET_IFNAME=<your_network_interface> 和 export GLOO_SOCKET_IFNAME=<your_network_interface> 来指定 IP 地址的网络接口。
在 self.graph.replay() 附近出错¶
如果 vLLM 崩溃,并且错误跟踪在 vllm/worker/model_runner.py 的 self.graph.replay() 附近捕获到,那么这是 CUDAGraph 中的 CUDA 错误。要识别导致错误的特定 CUDA 操作,您可以将 --enforce-eager 添加到命令行,或者将 enforce_eager=True 添加到 LLM 类中,以禁用 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.cuda.device_count()
torch.cuda.set_device(local_rank)
data = torch.FloatTensor([1,] * 128).to("cuda")
dist.all_reduce(data, op=dist.ReduceOp.SUM)
torch.cuda.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 地址。然后,运行:
NCCL_DEBUG=TRACE torchrun --nnodes 2 \
--nproc-per-node=2 \
--rdzv_backend=c10d \
--rdzv_endpoint=$MASTER_ADDR test.py
如果脚本成功运行,您应该会看到消息 sanity check is successful!。
如果测试脚本挂起或崩溃,通常意味着硬件/驱动程序在某种程度上存在问题。您应该联系您的系统管理员或硬件供应商寻求进一步的帮助。作为一种常见的解决方法,您可以尝试调整一些 NCCL 环境变量,例如 export NCCL_P2P_DISABLE=1,看看是否有帮助。请参阅 其文档 以获取更多信息。请仅将这些环境变量作为临时解决方法,因为它们可能会影响系统的性能。最佳解决方案仍然是修复硬件/驱动程序,以便测试脚本能够成功运行。
注意
多节点环境比单节点环境更复杂。如果您看到类似 torch.distributed.DistNetworkError 的错误,很可能是网络/DNS 设置不正确。在这种情况下,您可以手动分配节点排名并通过命令行参数指定 IP:
- 在第一个节点上,运行
NCCL_DEBUG=TRACE torchrun --nnodes 2 --nproc-per-node=2 --node-rank 0 --master_addr $MASTER_ADDR test.py。 - 在第二个节点上,运行
NCCL_DEBUG=TRACE torchrun --nnodes 2 --nproc-per-node=2 --node-rank 1 --master_addr $MASTER_ADDR test.py。
根据您的设置调整 --nproc-per-node、--nnodes 和 --node-rank,确保在不同的节点上执行不同的命令(具有不同的 --node-rank)。
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 库。例如,请参阅 问题 #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 轮子中的 CUDA PTX 是使用您的系统不支持的工具链编译的。已发布的 vLLM 轮子必须使用特定版本的 CUDA 工具包进行编译,并且编译后的代码可能无法在较低版本的 CUDA 驱动程序上运行。请阅读 CUDA 兼容性 以获取更多详细信息。解决方案是安装您软件包管理器中的 cuda-compat 软件包。例如,在 Ubuntu 上,您可以运行 sudo apt-get install cuda-compat-12-9,然后将 export LD_LIBRARY_PATH=/usr/local/cuda-12.9/compat:$LD_LIBRARY_PATH 添加到您的 .bashrc 文件。成功安装后,您应该会看到 nvidia-smi 的输出显示 CUDA Version: 12.9。请注意,此处我们以 CUDA 12.9 为例,您可能需要安装更高版本的 cuda-compat 软件包,以防 vLLM 的默认 CUDA 版本更高。
已知问题¶
- 在
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 2.22.3 中已修复底层 NCCL bug,因此在新版 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来禁用该功能,或者将驱动程序升级到最新版本。