故障排除¶
本文件概述了一些您可以考慮的故障排除策略。如果您認為發現了 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://huggingface.tw 上請模型建立者更新其預設 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.tw/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.python.club.tw/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來停用該功能,或者將驅動程序升級到最新版本。