From 44fc57d7b72eafaaefdcb0983451e08648be4d49 Mon Sep 17 00:00:00 2001 From: Andreas Karatzas Date: Sat, 15 Aug 2026 01:30:56 -0500 Subject: [PATCH] [ROCm][CI] Select CPU platform for native no-GPU jobs (#49515) Signed-off-by: Andreas Karatzas --- .../scripts/hardware_ci/run-amd-test.sh | 6 +++ tests/test_zen_cpu_platform_detection.py | 24 +++++++++- vllm/platforms/__init__.py | 45 +++++++++++++------ 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/.buildkite/scripts/hardware_ci/run-amd-test.sh b/.buildkite/scripts/hardware_ci/run-amd-test.sh index 42fe3f4546..eb8b53c6cc 100755 --- a/.buildkite/scripts/hardware_ci/run-amd-test.sh +++ b/.buildkite/scripts/hardware_ci/run-amd-test.sh @@ -434,6 +434,12 @@ initialize_native_environment() { TIKTOKEN_RS_CACHE_DIR="${HF_HOME}/tiktoken-rs-cache" : "${HF_HUB_DOWNLOAD_TIMEOUT:=300}" : "${HF_HUB_ETAG_TIMEOUT:=60}" + if [[ "${VLLM_CI_EXPECTED_GPU_COUNT:-1}" == "0" ]]; then + # CPU-only native jobs intentionally reuse the ROCm wheel. Make that target + # explicit so platform selection does not depend on wheel metadata. + VLLM_TARGET_DEVICE=cpu + export VLLM_TARGET_DEVICE + fi export TMPDIR VLLM_RPC_BASE_PATH export TORCHINDUCTOR_CACHE_DIR TRITON_CACHE_DIR VLLM_CACHE_ROOT XDG_CACHE_HOME export HF_HOME HF_DATASETS_CACHE HF_HUB_DOWNLOAD_TIMEOUT HF_HUB_ETAG_TIMEOUT diff --git a/tests/test_zen_cpu_platform_detection.py b/tests/test_zen_cpu_platform_detection.py index a1798d2b52..2857b1ac11 100644 --- a/tests/test_zen_cpu_platform_detection.py +++ b/tests/test_zen_cpu_platform_detection.py @@ -2,7 +2,9 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project from unittest.mock import mock_open, patch -from vllm.platforms import _is_amd_zen_cpu +import pytest + +from vllm.platforms import _is_amd_zen_cpu, resolve_current_platform_cls_qualname def test_is_amd_zen_cpu_detects_amd_with_avx512(): @@ -35,3 +37,23 @@ def test_is_amd_zen_cpu_returns_false_for_intel_with_avx512(): def test_is_amd_zen_cpu_returns_false_when_cpuinfo_missing(): with patch("os.path.exists", return_value=False): assert not _is_amd_zen_cpu() + + +def test_cpu_target_selects_cpu_platform_from_non_cpu_wheel( + monkeypatch: pytest.MonkeyPatch, +): + monkeypatch.setenv("VLLM_TARGET_DEVICE", "cpu") + + with ( + patch("vllm.platforms.vllm_version_matches_substr") as version_matches, + patch("vllm.platforms._is_amd_zen_cpu", return_value=False), + patch("vllm.platforms.rocm_platform_plugin") as rocm_plugin, + ): + assert ( + resolve_current_platform_cls_qualname() == "vllm.platforms.cpu.CpuPlatform" + ) + + # An explicit target does not depend on the installed wheel's version + # suffix or host accelerators (a native CI job can reuse a ROCm wheel). + version_matches.assert_not_called() + rocm_plugin.assert_not_called() diff --git a/vllm/platforms/__init__.py b/vllm/platforms/__init__.py index ac536aff00..718e2520c4 100644 --- a/vllm/platforms/__init__.py +++ b/vllm/platforms/__init__.py @@ -160,24 +160,32 @@ def _is_amd_zen_cpu() -> bool: def cpu_platform_plugin() -> str | None: - is_cpu = False logger.debug("Checking if CPU platform is available.") - try: - is_cpu = vllm_version_matches_substr("cpu") - if is_cpu: - logger.debug( - "Confirmed CPU platform is available because vLLM is built with CPU." - ) - if not is_cpu: - import sys - - is_cpu = sys.platform.startswith("darwin") + is_cpu = envs.VLLM_TARGET_DEVICE == "cpu" + if is_cpu: + logger.debug( + "Confirmed CPU platform is available because " + "VLLM_TARGET_DEVICE is set to CPU." + ) + else: + try: + is_cpu = vllm_version_matches_substr("cpu") if is_cpu: logger.debug( - "Confirmed CPU platform is available because the machine is MacOS." + "Confirmed CPU platform is available because vLLM is built " + "with CPU." ) - except Exception as e: - logger.debug("CPU platform is not available because: %s", str(e)) + if not is_cpu: + import sys + + is_cpu = sys.platform.startswith("darwin") + if is_cpu: + logger.debug( + "Confirmed CPU platform is available because the machine " + "is MacOS." + ) + except Exception as e: + logger.debug("CPU platform is not available because: %s", str(e)) if not is_cpu: return None @@ -209,6 +217,15 @@ builtin_platform_plugins = { def resolve_current_platform_cls_qualname() -> str: + # An explicit CPU target is authoritative. Native CPU-only CI jobs reuse + # an accelerator wheel and can run on accelerator hosts, so probing every + # plugin would otherwise activate both CPU and the host accelerator. + if envs.VLLM_TARGET_DEVICE == "cpu": + cpu_platform_cls_qualname = cpu_platform_plugin() + assert cpu_platform_cls_qualname is not None + logger.debug("Explicitly selected CPU platform.") + return cpu_platform_cls_qualname + platform_plugins = load_plugins_by_group(PLATFORM_PLUGINS_GROUP) activated_plugins = []