【vLLM 学习】调试技巧

vLLM 是一款专为大语言模型推理加速而设计的框架,实现了 KV 缓存内存几乎零浪费,解决了内存管理瓶颈问题。

更多 vLLM 中文文档及教程可访问 →https://vllm.hyper.ai/

调试挂起与崩溃问题

当一个 vLLM 实例挂起或崩溃时,调试问题会非常困难。但请稍等,也有可能 vLLM 正在执行某些确实需要较长时间的任务:

  • 下载模型: 您的磁盘中是否已经下载了模型?如果没有,vLLM 将从互联网上下载模型,这可能需要很长时间。请务必检查互联网连接。最好先使用 huggingface-cli 下载模型,然后使用模型的本地路径。这样可以就没有问题了。
  • 从磁盘加载模型: 如果模型很大,从磁盘加载模型可能需要很长时间。请注意存储模型的位置。一些集群在节点之间共享文件系统的速度可能很慢,例如分布式文件系统或网络文件系统。最好将模型存储在本地磁盘中。另外,还请注意 CPU 内存使用情况。当模型太大时,可能会占用大量 CPU 内存,这可能会降低操作系统的速度,因为它需要频繁地在磁盘和内存之间交换内存。
  • 张量并行推理: 如果模型太大而无法容纳在单个 GPU 中,您可能需要使用张量并行将模型拆分到多个 GPU 上。在这种情况下,每个进程都会读取整个模型并将其拆分成块,这会使磁盘读取时间更长(与张量并行度的大小成正比)。您可以使用该脚本将模型检查点转换为分片检查点。转换过程可能需要一些时间,但之后您可以更快地加载分片检查点。无论张量并行度的大小如何,模型加载时间都应维持稳定。

如果您已经解决了上述问题,但 vLLM 实例仍然挂起,CPU 和 GPU 的利用率接近于零,那么 vLLM 实例可能卡在了某个地方。以下是一些有助于调试问题的提示:

  • 设置环境变量 export VLLM_LOGGING_LEVEL=DEBUG 以打开更多日志记录。
  • 设置环境变量 export CUDA_LAUNCH_BLOCKING=1 以准确定位哪个 CUDA 内核引发了问题。
  • 设置环境变量 export NCCL_DEBUG=TRACE 以开启 NCCL 的更多日志记录。
  • 设置环境变量 export VLLM_TRACE_FUNCTION=1。vLLM 中的所有函数调用将被记录下来。检查这些日志文件,找出哪个函数崩溃或挂起。

通过更多日志记录,希望您能够找到问题的根本原因。

如果程序崩溃,并且错误追踪显示在 vllm/worker/model_runner.py 中的 self.graph.replay() 附近,那么这是一个发生在 cudagraph 内部的 CUDA 错误。要知道引发错误的具体 CUDA 操作,您可以在命令行中添加 --enforce-eager,或者在 LLM 类中设置 enforce_eager=True,以禁用 cudagraph 优化。通过这种方式,您可以准确定位导致错误的 CUDA 操作。

以下是一些可能导致挂起的常见问题:

  • 错误的网络设置:如果你的网络配置很复杂,vLLM 实例可能无法获取正确的 IP 地址。您可以找到类似 DEBUG 06-10 21:32:17 parallel_state.py:88] world_size=8rank=0 local_rank=0Distributed_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 地址的网络接口。
  • 错误的硬件 / 驱动:无法建立 GPU/CPU 通信。您可以运行以下完整性检查脚本来查看 GPU/CPU 通信是否正常工作。
# Test PyTorch NCCL
# 测试 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
# 测试 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!")


# Test vLLM NCCL, with cuda graph
# 使用 cuda 图测试 vLLM NCCL


from vllm.distributed.device_communicators.pynccl import PyNcclCommunicator


pynccl = PyNcclCommunicator(group=gloo_group, device=local_rank)
pynccl.disabled = False


s = torch.cuda.Stream()
with torch.cuda.stream(s):
    data.fill_(1)
    pynccl.all_reduce(data, stream=s)
    value = data.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):
    pynccl.all_reduce(data, stream=torch.cuda.current_stream())


data.fill_(1)
g.replay()
torch.cuda.current_stream().synchronize()
value = data.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()

提示

将脚本保存为test.py 。

如果您在单节点中进行测试,请使用 NCCL_DEBUG=TRACE torchrun --nproc-per-node=8 test.py 运行它,将 --nproc-per-node 调整为您想使用的 GPU 数量。

如果您正在使用多节点进行测试,请使用 NCCL_DEBUG=TRACE torchrun --nnodes 2 --nproc-per-node=2 --rdzv_backend=c10d --rdzv_endpoint=$MASTER_ADDR test.py 运行它。根据您的设置调整 --nproc-per-node 和 --nnodes。确保 MASTER_ADDR 满足以下条件:

  • 是主节点的正确 IP 地址
  • 所有节点均可访问
  • 在运行脚本之前设置

如果脚本成功运行,您会看到消息 sanity check is successful! 。

如果问题仍然存在,请随时在 GitHub 上新建一个 issue,并详细描述问题、您的环境以及日志。

一些已知问题:

  • v0.5.2v0.5.3和 v0.5.3.post1中,存在由 zmq 引起的错误,这可能会导致低概率挂起(大约 20 次挂起一次,具体取决于机器配置)。解决方案是升级到最新版本的 vllm以包含修复程序。

警告

在找到根本原因并解决问题后,请记得关闭上述定义的所有调试环境变量,或者简单地启动一个新 shell,以避免受到调试设置的影响。如果不这样做,系统可能会因为许多调试功能被打开而变慢。

### 如何启动 vLLM 服务 为了成功启动 vLLM 服务,可以按照以下方法操作并配置环境。以下是关于如何运行 vLLM 的具体说明: #### 安装依赖项 在启动之前,需确保安装了必要的 Python 库以及 NVIDIA Triton Inference Server。可以通过 pip 命令来完成这些库的安装[^1]。 ```bash pip install vllm tritonclient[all] ``` #### 配置模型仓库 Triton 推理服务器需要一个指定路径下的模型存储库,在该存储库中定义所要加载的大规模语言模型及其参数设置文件 `config.pbtxt`。此文件描述了模型的基本属性和推理选项。 例如创建如下结构: ``` model_repository/ └── my_model/ ├── config.pbtxt └── model_weights.pt ``` 其中 `config.pbtxt` 文件可能看起来像这样: ```protobuf name: "my_vllm_model" platform: "huggingface_llm" max_batch_size: 0 input [ { name: "INPUT_TEXT" data_type: TYPE_STRING dims: [ -1 ] } ] output [ { name: "OUTPUT_TEXT" data_type: TYPE_STRING dims: [ -1 ] } ] instance_group [ { kind: KIND_GPU count: 1 } ] parameters [ { key: "tokenizer" value: { string_value: "gpt2" } }, { key: "trust_remote_code", value: { bool_value: true } } ] ``` #### 启动 Triton Server 通过命令行工具启动 Triton Inference Server 并指向已准备好的模型存储库位置: ```bash tritonserver --model-repository=/path/to/model_repository ``` 这一步会初始化 GPU 资源并将所有可用模型加载到内存中以便后续调用。 #### 测试 API 请求 一旦服务正常工作,则可通过 RESTful 或 gRPC 协议向其发送请求来进行预测任务验证。下面展示了一个简单的 curl 示例用于发起 HTTP POST 请求: ```bash curl -X POST http://localhost:8000/v2/models/my_model/infer \ -H "Content-Type: application/json" \ -d '{ "inputs": [{ "name": "INPUT_TEXT", "shape": [1], "datatype": "BYTES", "data": ["Hello world!"] }] }' ``` 如果一切顺利的话, 将返回由选定 LLM 模型生成的结果字符串. --- ### 注意事项 - 确认硬件支持 CUDA 和 cuDNN 版本匹配当前使用的深度学习框架版本. - 如果遇到任何错误消息,请查阅官方文档获取更多调试技巧.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值