Signed-off-by: MarkPoloChina <1228479724@qq.com> Signed-off-by: XiongZhongwei <1228479724@qq.com>
122 lines
4.3 KiB
Python
122 lines
4.3 KiB
Python
# SPDX-License-Identifier: Apache-2.0
|
|
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
|
|
"""Guard the NPU pytest circular import through DiffusionOutput."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import ast
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def _top_level_import_modules(path: Path) -> set[str]:
|
|
tree = ast.parse(path.read_text(encoding="utf-8"))
|
|
modules: set[str] = set()
|
|
for node in tree.body:
|
|
if isinstance(node, ast.ImportFrom) and node.module:
|
|
modules.add(node.module)
|
|
elif isinstance(node, ast.Import):
|
|
modules.update(alias.name for alias in node.names)
|
|
return modules
|
|
|
|
|
|
def _assert_isolated_import_succeeds(script: str) -> None:
|
|
env = os.environ.copy()
|
|
env.pop("CUDA_VISIBLE_DEVICES", None)
|
|
env.pop("HIP_VISIBLE_DEVICES", None)
|
|
result = subprocess.run(
|
|
[sys.executable, "-c", script],
|
|
cwd=REPO_ROOT,
|
|
env=env,
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=120,
|
|
check=False,
|
|
)
|
|
assert result.returncode == 0, result.stderr
|
|
|
|
|
|
def test_config_package_does_not_eagerly_import_pipeline_registry() -> None:
|
|
imported = _top_level_import_modules(REPO_ROOT / "vllm_omni" / "config" / "__init__.py")
|
|
assert "vllm_omni.config.config_factory" not in imported
|
|
assert "vllm_omni.config.pipeline_registry" not in imported
|
|
|
|
|
|
def test_config_package_lazy_exports_still_resolve() -> None:
|
|
from vllm_omni.config import StageConfigFactory, register_pipeline
|
|
from vllm_omni.config.config_factory import StageConfigFactory as DirectStageConfigFactory
|
|
from vllm_omni.config.pipeline_registry import register_pipeline as direct_register_pipeline
|
|
|
|
assert StageConfigFactory is DirectStageConfigFactory
|
|
assert register_pipeline is direct_register_pipeline
|
|
|
|
|
|
def test_npu_platform_defers_minimax_h3_encoder_patch() -> None:
|
|
src = (REPO_ROOT / "vllm_omni" / "platforms" / "npu" / "platform.py").read_text(encoding="utf-8")
|
|
init_start = src.index("def __init__(self) -> None:")
|
|
runtime_start = src.index("def init_diffusion_model_runner_runtime")
|
|
init_src = src[init_start:runtime_start]
|
|
runtime_src = src[runtime_start:]
|
|
assert "apply_minimax_h3_qwen3vl_patch" not in init_src
|
|
assert "apply_minimax_h3_qwen3vl_patch" in runtime_src
|
|
assert "apply_minimax_h3_qwen3vl_sdpa_patch" not in init_src
|
|
assert "apply_minimax_h3_qwen3vl_sdpa_patch" in runtime_src
|
|
assert "apply_minimax_h3_qwen3vl_swiglu_patch" in runtime_src
|
|
|
|
|
|
def test_lora_config_import_does_not_load_pipeline_registry() -> None:
|
|
"""Import LoRAConfig and diffusion.data in a fresh interpreter.
|
|
|
|
The NPU failure was ``data.py`` importing LoRAConfig while still loading,
|
|
then ``vllm_omni.config`` re-entering ``pipeline_registry`` → PI0 →
|
|
DiffusionOutput. This child process must not preload those exports.
|
|
"""
|
|
_assert_isolated_import_succeeds(
|
|
"""
|
|
import sys
|
|
|
|
from vllm_omni.config.lora import LoRAConfig
|
|
|
|
if "vllm_omni.config.pipeline_registry" in sys.modules:
|
|
raise SystemExit("LoRAConfig import loaded pipeline_registry")
|
|
if "vllm_omni.diffusion.models.pi0.pipeline_pi0" in sys.modules:
|
|
raise SystemExit("LoRAConfig import loaded PI0_PIPELINE")
|
|
|
|
from vllm_omni.diffusion.data import DiffusionOutput
|
|
|
|
if DiffusionOutput is None or LoRAConfig is None:
|
|
raise SystemExit("expected LoRAConfig and DiffusionOutput")
|
|
"""
|
|
)
|
|
|
|
|
|
def test_pipeline_registry_does_not_import_pi0_runtime() -> None:
|
|
"""Resolving the pi0 topology must not import its runtime pipeline.
|
|
|
|
``pipeline_pi0`` imports ``diffusion.data``. Importing it while
|
|
``diffusion.data`` is only partially initialized closes the Ascend plugin's
|
|
circular-import loop, so the registry must depend only on a lightweight
|
|
pipeline-config module.
|
|
"""
|
|
_assert_isolated_import_succeeds(
|
|
"""
|
|
import sys
|
|
|
|
from vllm_omni.config.pipeline_registry import resolve_pipeline_config
|
|
|
|
if "vllm_omni.diffusion.models.pi0.pipeline_pi0" in sys.modules:
|
|
raise SystemExit("pipeline_registry imported the pi0 runtime pipeline")
|
|
|
|
pipeline = resolve_pipeline_config("pi0")
|
|
if pipeline is None or pipeline.model_type != "pi0":
|
|
raise SystemExit("expected the registered pi0 pipeline config")
|
|
"""
|
|
)
|