故障排除¶
本文档概述了一些您可以考虑的故障排除策略。如果您认为发现了错误,请先搜索现有问题查看是否已有人报告。如果没有,请提交新问题,并尽可能提供相关详细信息。
注意
调试完问题后,请记得关闭所有定义的调试环境变量,或者直接启动一个新的shell以避免残留调试设置的影响。否则,系统可能会因为调试功能保持激活状态而运行缓慢。
下载模型时卡住¶
如果模型尚未下载到本地磁盘,vLLM会从互联网下载,这可能需要时间并取决于您的网络连接。建议先使用huggingface-cli下载模型,然后将模型的本地路径传递给vLLM。这样可以隔离问题。
从磁盘加载模型时卡住¶
如果模型较大,从磁盘加载可能需要很长时间。请注意模型的存储位置。某些集群在节点间共享文件系统,例如分布式文件系统或网络文件系统,这些系统可能速度较慢。最好将模型存储在本地磁盘上。此外,当模型过大时,还需关注CPU内存使用情况,可能会占用大量CPU内存,导致操作系统因频繁在磁盘和内存之间交换数据而变慢。
注意
为了隔离模型下载和加载的问题,你可以使用--load-format dummy参数来跳过加载模型权重。这样,你可以检查模型下载和加载是否是瓶颈。
Out of memory¶
If the model is too large to fit in a single GPU, you will get an out-of-memory (OOM) error. Consider adopting these options to reduce the memory consumption.
生成质量发生变化¶
在v0.8.0版本中, Pull Request #12622修改了默认采样参数的来源。在v0.8.0之前,默认采样参数来自vLLM的中性默认值集合。从v0.8.0开始,默认采样参数改为来自模型创建者提供的generation_config.json文件。
在大多数情况下,这应该会带来更高质量的响应,因为模型创建者可能最清楚哪些采样参数最适合他们的模型。然而,在某些情况下,模型创建者提供的默认设置可能会导致性能下降。
您可以通过在在线模式下使用--generation-config vllm参数,离线模式下使用generation_config="vllm"来尝试旧版默认设置,以检查是否发生此情况。如果尝试后生成质量有所改善,我们建议您继续使用vLLM的默认设置,并前往https://huggingface.co向模型创建者请愿更新其默认的generation_config.json文件,以获得更高质量的生成结果。
启用更多日志记录¶
如果其他策略无法解决问题,很可能是vLLM实例卡在某个地方。您可以使用以下环境变量来帮助调试问题:
export VLLM_LOGGING_LEVEL=DEBUG开启更多日志记录。export CUDA_LAUNCH_BLOCKING=1用于识别是哪个CUDA内核导致了问题。export NCCL_DEBUG=TRACE以开启NCCL更详细的日志记录。export VLLM_TRACE_FUNCTION=1用于记录所有函数调用以便在日志文件中检查,从而定位崩溃或挂起的函数。除非绝对需要调试,否则不要使用此标志,它将显著增加启动时间。
网络设置不正确¶
如果您的网络配置较为复杂,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地址设置。
您可能还需要设置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通信是否正常工作。
Code
# 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
troubleshooting.html#python-multiprocessing
for more information.
或者来自Python的错误如下所示:
Logs
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.python.org/3/library/multiprocessing.html
那么你必须更新你的Python代码,将vllm的使用放在if __name__ == '__main__':代码块中进行保护。例如,不要这样写:
试试这个替代方案:
torch.compile 错误¶
vLLM 高度依赖 torch.compile 来优化模型以获得更好的性能,这引入了对 torch.compile 功能和 triton 库的依赖。默认情况下,我们使用 torch.compile 来 优化模型中的某些函数。在运行 vLLM 之前,您可以通过运行以下脚本来检查 torch.compile 是否按预期工作:
Code
如果出现来自torch/_inductor目录的错误,通常意味着您使用的自定义triton库与当前PyTorch版本不兼容。具体示例可参考 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所致。请参考分布式推理与服务获取正确配置分布式服务环境的指导。