Files
vllm-omni/tests/worker/test_cpu_ar_model_runner.py
T
tzhouamandClaude Fable 5.1 35e43b9983 [Edge][WP3] Add CPU OmniPlatform (AR + generation stages on vLLM's CPU backend)
* vllm_omni/platforms/cpu/platform.py: CPUOmniPlatform(OmniPlatform, CpuPlatform)
  selected when VLLM_TARGET_DEVICE=cpu or a +cpu vLLM wheel is installed
  (builtin plugin "cpu"; explicit CPU target short-circuits accelerator probes
  like vLLM does). NUMA-based memory queries, one logical device, no graph
  wrapper (sentinel type for isinstance checks), inductor opt-in via
  VLLM_OMNI_CPU_INDUCTOR=1, diffusion stages unsupported.
* vllm_omni/platforms/cpu/worker: CPUARWorker / CPUGenerationWorker compose
  vLLM's CPUWorker with the Omni mixin (XPU pattern); CPUARModelRunner /
  CPUGenerationModelRunner compose the Omni runners with CPUModelRunner
  (no graphs, no async omni output; sleep/wake return error ACKs).
* patch.py skips the CuMem patch on CPU-only torch; Qwen3-TTS speaker encoder
  and prompt-embeds dtype follow the model dtype (float32/float16 on CPU).
* vllm_omni/deploy/qwen3_tts.yaml: `platforms: cpu:` overlay (eager, no async
  scheduling, absolute kv_cache_memory_bytes, disjoint OMP thread ranges).
* requirements/cpu.txt (+psutil, intel-openmp), docs/getting_started/installation/cpu.md.

Measured (this x86 Xeon 8480C host, vllm 0.28.0+cpu, bf16, 12+4 threads):
Qwen3-TTS 0.6B CustomVoice end-to-end on CPU, 12 prompts: TTFA p50 292 ms,
RTF ~1.7 (25-frame chunk ~4.6 s), init 185 s. Result JSON + init timeline
committed under benchmarks/tts/edge_results/.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 11:02:14 +08:00

75 lines
3.3 KiB
Python

"""CPU Omni runners/workers: MRO and override resolution (import-only, CPU)."""
from __future__ import annotations
import pytest
from vllm.v1.worker.cpu_model_runner import CPUModelRunner
from vllm.v1.worker.cpu_worker import CPUWorker
from vllm.v1.worker.gpu_model_runner import GPUModelRunner
from vllm_omni.platforms.cpu.worker.cpu_ar_model_runner import (
CPUARModelRunner,
CPUGenerationModelRunner,
_CPUOmniRunnerMixin,
)
from vllm_omni.platforms.cpu.worker.cpu_ar_worker import CPUARWorker, CPUGenerationWorker
from vllm_omni.worker.gpu_ar_model_runner import GPUARModelRunner
from vllm_omni.worker.gpu_generation_model_runner import GPUGenerationModelRunner
from vllm_omni.worker.mixins import OmniWorkerMixin
from vllm_omni.worker.omni_connector_model_runner_mixin import OmniConnectorModelRunnerMixin
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
def test_ar_runner_mro():
mro = CPUARModelRunner.__mro__
assert (
mro.index(_CPUOmniRunnerMixin)
< mro.index(GPUARModelRunner)
< mro.index(CPUModelRunner)
< mro.index(GPUModelRunner)
)
# CPU overrides win over the GPU runner implementations
assert CPUARModelRunner._init_device_properties is _CPUOmniRunnerMixin._init_device_properties
assert CPUARModelRunner._sync_device is _CPUOmniRunnerMixin._sync_device
assert CPUARModelRunner.capture_model is _CPUOmniRunnerMixin.capture_model
assert CPUARModelRunner._capture_talker_mtp_graphs is _CPUOmniRunnerMixin._capture_talker_mtp_graphs
# vLLM CPU shims (triton/tensor post-processing, warm-up) are reachable
assert CPUARModelRunner.warming_up_model is CPUModelRunner.warming_up_model
assert CPUARModelRunner._postprocess_triton is CPUModelRunner._postprocess_triton
# omni connector mixin is present for the worker-class validation
assert issubclass(CPUARModelRunner, OmniConnectorModelRunnerMixin)
def test_generation_runner_mro():
mro = CPUGenerationModelRunner.__mro__
assert mro.index(GPUGenerationModelRunner) < mro.index(CPUModelRunner)
assert CPUGenerationModelRunner.capture_model is _CPUOmniRunnerMixin.capture_model
def test_workers_compose_cpu_worker_and_omni_mixin():
for worker_cls, runner_cls in ((CPUARWorker, CPUARModelRunner), (CPUGenerationWorker, CPUGenerationModelRunner)):
assert issubclass(worker_cls, CPUWorker) and issubclass(worker_cls, OmniWorkerMixin)
assert worker_cls.model_runner_cls is runner_cls
assert hasattr(worker_cls, "handle_sleep_task") and hasattr(worker_cls, "handle_wake_task")
def test_worker_cls_validation_accepts_cpu_workers():
from vllm_omni.worker.omni_connector_validation import validate_worker_omni_connector
validate_worker_omni_connector("vllm_omni.platforms.cpu.worker.cpu_ar_worker.CPUARWorker", required=True)
validate_worker_omni_connector(
"vllm_omni.platforms.cpu.worker.cpu_generation_worker.CPUGenerationWorker", required=True
)
def test_sleep_and_wake_return_error_acks():
class _Task:
task_id = "t1"
level = 1
ack = CPUARWorker.handle_sleep_task(object.__new__(CPUARWorker), _Task())
assert ack.status == "ERROR" and ack.task_id == "t1"
ack = CPUARWorker.handle_wake_task(object.__new__(CPUARWorker), _Task())
assert ack.status == "ERROR"