2026-04-19 10:36:00 +08:00
|
|
|
|
# SPDX-License-Identifier: Apache-2.0
|
2026-10-04 03:11:35 +08:00
|
|
|
|
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
2026-04-19 10:36:00 +08:00
|
|
|
|
"""Tests for vllm_omni.engine.arg_utils — invariants that must
|
|
|
|
|
|
hold for the orchestrator/engine/server CLI flag partition."""
|
|
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
2026-06-02 07:56:24 -06:00
|
|
|
|
from dataclasses import fields
|
2026-04-19 10:36:00 +08:00
|
|
|
|
|
|
|
|
|
|
import pytest
|
2026-10-02 10:37:50 +08:00
|
|
|
|
from vllm.config import AuxOutputConfig
|
2026-04-19 10:36:00 +08:00
|
|
|
|
|
|
|
|
|
|
from vllm_omni.engine.arg_utils import (
|
|
|
|
|
|
SHARED_FIELDS,
|
2026-06-02 07:56:24 -06:00
|
|
|
|
OmniEngineArgs,
|
2026-04-19 10:36:00 +08:00
|
|
|
|
internal_blacklist_keys,
|
|
|
|
|
|
orchestrator_field_names,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2026-06-02 07:56:24 -06:00
|
|
|
|
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
|
2026-04-19 10:36:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_no_ambiguous_overlap_with_real_engine():
|
2026-06-02 07:56:24 -06:00
|
|
|
|
"""OrchestratorArgs ∩ OmniEngineArgs must be ⊆ SHARED_FIELDS ∪ orchestrator-captured.
|
|
|
|
|
|
|
|
|
|
|
|
Fields that the orchestrator intentionally captures to prevent uniform
|
|
|
|
|
|
propagation (async_chunk, tokenizer) are excluded — they exist in both
|
|
|
|
|
|
classes by design but flow through DeployConfig, not kwargs forwarding.
|
|
|
|
|
|
"""
|
|
|
|
|
|
# Fields on both classes by design: orchestrator captures them to prevent
|
|
|
|
|
|
# uniform per-stage propagation; redistributed via DeployConfig.
|
|
|
|
|
|
orchestrator_captured = {"async_chunk", "tokenizer"}
|
2026-04-19 10:36:00 +08:00
|
|
|
|
|
|
|
|
|
|
orch = orchestrator_field_names()
|
|
|
|
|
|
engine = {f.name for f in fields(OmniEngineArgs)}
|
|
|
|
|
|
overlap = orch & engine
|
2026-06-02 07:56:24 -06:00
|
|
|
|
unexpected = overlap - SHARED_FIELDS - orchestrator_captured
|
2026-04-19 10:36:00 +08:00
|
|
|
|
assert not unexpected, (
|
2026-06-02 07:56:24 -06:00
|
|
|
|
f"OmniEngineArgs has ambiguous overlap with OrchestratorArgs: "
|
2026-04-19 10:36:00 +08:00
|
|
|
|
f"{sorted(unexpected)}. Update SHARED_FIELDS or remove duplication."
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_internal_blacklist_keys_derived_from_orchestrator():
|
|
|
|
|
|
"""Blacklist is exactly OrchestratorArgs fields minus SHARED_FIELDS.
|
|
|
|
|
|
|
|
|
|
|
|
This function replaces the old hardcoded INTERNAL_STAGE_OVERRIDE_KEYS
|
|
|
|
|
|
frozenset. Asserts the contract so future changes to OrchestratorArgs
|
|
|
|
|
|
automatically propagate to the blacklist.
|
|
|
|
|
|
"""
|
|
|
|
|
|
blacklist = internal_blacklist_keys()
|
|
|
|
|
|
assert blacklist == orchestrator_field_names() - SHARED_FIELDS
|
2026-10-02 10:37:50 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"aux_args",
|
|
|
|
|
|
[
|
|
|
|
|
|
{"enable_return_routed_experts": True},
|
|
|
|
|
|
{"aux_output_config": {"enable_return_routed_experts": True}},
|
|
|
|
|
|
{"aux_output_config": AuxOutputConfig(enable_return_routed_experts=True)},
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("use_v2_model_runner", [False, True])
|
2026-10-04 13:40:24 +08:00
|
|
|
|
@pytest.mark.parametrize("is_npu", [False, True])
|
|
|
|
|
|
def test_aux_outputs_require_a_supported_omni_stage_runner(aux_args, use_v2_model_runner, is_npu, monkeypatch):
|
2026-10-02 10:37:50 +08:00
|
|
|
|
# Upstream runner selection reads this environment variable; Omni workers
|
|
|
|
|
|
# select their runner from the separate per-stage flag instead.
|
|
|
|
|
|
monkeypatch.setenv("VLLM_USE_V2_MODEL_RUNNER", "1")
|
2026-10-04 13:40:24 +08:00
|
|
|
|
monkeypatch.setattr("vllm_omni.engine.arg_utils.current_omni_platform.is_npu", lambda: is_npu)
|
|
|
|
|
|
if use_v2_model_runner or is_npu:
|
|
|
|
|
|
args = OmniEngineArgs(model="unused", use_v2_model_runner=use_v2_model_runner, **aux_args)
|
2026-10-02 10:37:50 +08:00
|
|
|
|
assert args.aux_output_config.enabled
|
|
|
|
|
|
else:
|
|
|
|
|
|
with pytest.raises(ValueError, match="use_v2_model_runner=True for this Omni stage"):
|
|
|
|
|
|
OmniEngineArgs(model="unused", **aux_args)
|