[Bugfix] Defer VoxCPM2 NPU patch to avoid platform import cycle (#8330)

Signed-off-by: amy-why-3459 <wuhaiyan17@huawei.com>
This commit is contained in:
amy-why-3459 authored and GitHub committed 2026-09-30 05:25:36 -07:00
1 parent 56763cd6c3
commit 4af28f33bd
4 files changed
+34 -10

No files matched your search

@@ -231,8 +231,12 @@ def _cfm_inputs(
time_emb = torch.randn(batch_size, 1, hidden, device=device)
cnn_cache = torch.randn(depth, batch_size, hidden, 2, device=device)
att_cache = torch.randn(depth, batch_size, 1, old_att_len, hidden, device=device)
cnn_out = torch.empty(depth, batch_size, hidden, 2, device=device)
att_out = torch.empty(depth, batch_size, 1, old_att_len + chunk_size, hidden, device=device)
# The fake estimator only fills ``att_out[:, :, :, :chunk_size]``. The tail
# is the previous cache slot and is not written. ``empty`` leaves it
# uninitialized, so eager and replay compare different garbage and CI
# fails when that garbage is NaN.
cnn_out = torch.zeros(depth, batch_size, hidden, 2, device=device)
att_out = torch.zeros(depth, batch_size, 1, old_att_len + chunk_size, hidden, device=device)
return estimator_input, time_emb, cnn_cache, att_cache, cnn_out, att_out
@@ -76,12 +76,13 @@ def test_model_patch_wraps_init_and_is_idempotent(monkeypatch) -> None:
assert model.prefix == "talker"
def test_npu_platform_registers_patch_and_keeps_worker_cls(monkeypatch) -> None:
def test_npu_platform_defers_patch_until_device_setup(monkeypatch) -> None:
pytest.importorskip(
"vllm_ascend",
reason="NPU platform registration requires the optional vllm-ascend plugin",
)
from vllm_ascend import utils as ascend_utils
from vllm_ascend.platform import NPUPlatform
from vllm_omni.platforms.npu import _310p
from vllm_omni.platforms.npu.models import (
@@ -115,7 +116,21 @@ def test_npu_platform_registers_patch_and_keeps_worker_cls(monkeypatch) -> None:
worker_cls = NPUOmniPlatform.get_omni_ar_worker_cls()
assert worker_cls == "vllm_omni.platforms.npu.worker.npu_ar_worker.NPUARWorker"
assert calls == ["voxcpm2"]
assert calls == []
device = torch.device("npu:0")
monkeypatch.setattr(
NPUPlatform,
"set_device",
classmethod(lambda cls, device: calls.append(("set_device", device))),
)
monkeypatch.setattr(ascend_utils, "enable_custom_op", lambda: calls.append("custom_ops"))
monkeypatch.setattr(torch.npu, "config", SimpleNamespace(allow_internal_format=False))
NPUOmniPlatform.set_device(device)
assert calls == [("set_device", device), "voxcpm2", "custom_ops"]
assert torch.npu.config.allow_internal_format
def test_loc_dit_npugraph_supports_wrapped_subclass_and_wraps_once(monkeypatch) -> None:
@@ -38,8 +38,8 @@ def apply_voxcpm2_talker_patch() -> None:
if _PATCHED:
return
# The model defers resolving ``current_omni_platform`` until construction,
# so importing it while NPUOmniPlatform is initialized is cycle-free.
# Call this only after platform initialization: the model's transitive
# imports resolve ``current_omni_platform``.
from vllm_omni.model_executor.models.voxcpm2.voxcpm2_talker import (
VoxCPM2TalkerForConditionalGeneration,
)
+9 -4
View File
@@ -68,21 +68,26 @@ class NPUOmniPlatform(OmniPlatform, NPUPlatform):
from vllm_omni.platforms.npu.models.qwen3_tts_tokenizer_v2 import (
apply_qwen3_tts_tokenizer_v2_patch,
)
from vllm_omni.platforms.npu.models.voxcpm2_talker import (
apply_voxcpm2_talker_patch,
)
adapt_patch(is_global_patch=True)
apply_minicpmo_4_5_code2wav_patch()
apply_qwen3_tts_patches()
apply_qwen3_tts_tokenizer_v2_patch()
apply_voxcpm2_talker_patch()
apply_310p_patches()
@classmethod
def set_device(cls, device: torch.device) -> None:
super().set_device(device)
# The model's dependencies resolve current_omni_platform, so importing
# it in __init__ would re-enter platform initialization. Install the
# patch in the worker, before it constructs the model instead.
from vllm_omni.platforms.npu.models.voxcpm2_talker import (
apply_voxcpm2_talker_patch,
)
apply_voxcpm2_talker_patch()
# Register vllm_ascend custom ops (torch.ops._C_ascend.*).
from vllm_ascend.utils import enable_custom_op