[CI/Build] Move L1/E2E coverage to weekly and split scheduled L4/L5 pipelines (#6311)

Signed-off-by: wangyu <410167048@qq.com>
Signed-off-by: [Your Name] <your.email@example.com>
Co-authored-by: amy-why-3459 <wuhaiyan17@huawei.com>
This commit is contained in:
wangyuandamy-why-3459 authored and GitHub committed 2026-08-23 11:49:37 +08:00
1 parent 2e096788a6
commit 0db262de2a
24 files changed
+353 -249

No files matched your search

+26 -5
View File
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
from __future__ import annotations
import sys
@@ -61,16 +62,23 @@ def test_bootstrap_steps_loaded_from_file() -> None:
def test_docs_only_allows_main_scheduled_nightly_weekly_only() -> None:
"""skip_all: no PR labels; main + NIGHTLY=1 / WEEKLY=1 still gates scheduled CI."""
"""skip_all: no PR labels; main + NIGHTLY=1 / WEEKLY=1 / NON_CRITICAL=1 still gates scheduled CI."""
rendered = _render(["docs/foo.md"])
assert "key: image-build" in rendered
assert "key: upload-nightly-pipeline" in rendered
assert "key: upload-weekly-pipeline" in rendered
# Scheduled nightly also uploads L2/L3 with --e2e
assert "key: upload-ready-pipeline" in rendered
assert "key: upload-merge-pipeline" in rendered
assert 'build.env("NIGHTLY") == "1"' in rendered
# Scheduled main+WEEKLY=1 uploads L2/L3 with --e2e; NIGHTLY still gates L4 only.
doc = yaml.safe_load(rendered)
by_key = {step["key"]: step for step in doc["steps"]}
assert "NIGHTLY" not in by_key["upload-ready-pipeline"]["if"]
assert 'build.branch == "main"' in by_key["upload-ready-pipeline"]["if"]
assert 'build.env("WEEKLY") == "1"' in by_key["upload-ready-pipeline"]["if"]
assert "NIGHTLY" not in by_key["upload-merge-pipeline"]["if"]
assert 'build.branch == "main"' in by_key["upload-merge-pipeline"]["if"]
assert 'build.env("WEEKLY") == "1"' in by_key["upload-merge-pipeline"]["if"]
assert 'build.env("NIGHTLY") == "1"' in by_key["upload-nightly-pipeline"]["if"]
assert 'build.env("WEEKLY") == "1"' in rendered
assert 'build.env("NON_CRITICAL") == "1"' in rendered
assert "nightly-test" not in rendered
assert "weekly-test" not in rendered
assert "merge-test" not in rendered
@@ -78,6 +86,19 @@ def test_docs_only_allows_main_scheduled_nightly_weekly_only() -> None:
assert "if: false" not in rendered
def test_npu_docs_only_does_not_upload_ready_on_nightly() -> None:
"""NPU skip_all: scheduled NIGHTLY still uploads L4, not L2 ready."""
rendered = _render_bootstrap_pipeline(
BOOTSTRAP_STEPS_TEMPLATE,
decision=resolve_ci_decision(["docs/foo.md"]),
path=Path(".buildkite/npu/bootstrap-upload-steps.yml"),
)
doc = yaml.safe_load(rendered)
by_key = {step["key"]: step for step in doc["steps"]}
assert "upload-ready-pipeline" not in by_key
assert 'build.env("NIGHTLY") == "1"' in by_key["upload-nightly-pipeline"]["if"]
def test_yaml_gated_l45_only_does_not_unconditionally_build_image() -> None:
rendered = _render([".buildkite/cuda/test-nightly.yml"])
assert "if: true" not in rendered
@@ -10,7 +10,7 @@
"num_cards": 3
}
},
"full_model",
"slow",
"omni"
],
"server_params": {
@@ -10,7 +10,7 @@
"num_cards": 2
}
},
"full_model",
"slow",
"omni"
],
"server_params": {
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
"""
Quantization quality gate for diffusion models.
@@ -53,6 +53,7 @@ _BENCH_MODULE_NAME = "benchmarks.diffusion.quantization_quality"
if _BENCH_MODULE_NAME not in sys.modules:
_spec = importlib.util.spec_from_file_location(_BENCH_MODULE_NAME, _BENCH_MODULE_PATH)
assert _spec is not None and _spec.loader is not None
_mod = importlib.util.module_from_spec(_spec)
sys.modules[_BENCH_MODULE_NAME] = _mod
_spec.loader.exec_module(_mod)
@@ -93,7 +94,7 @@ class QualityTestConfig:
return self.quantized_model
return self.model or ""
def quantization_ref(self) -> str | None:
def quantization_ref(self) -> str | dict[str, object] | None:
if self.quantized_model is not None:
return None
return self.quantization
@@ -500,6 +501,8 @@ def _quality_param(c: QualityTestConfig):
marks.append(
pytest.mark.skip(reason="Qwen-Image FP8 quality gate temporarily disabled (see CI / issue tracker).")
)
if c.id == "fp8_ltx2":
marks.append(pytest.mark.skip(reason="https://github.com/vllm-project/vllm-omni/issues/6245"))
return pytest.param(c, id=c.id, marks=marks)
@@ -3,15 +3,27 @@
from __future__ import annotations
import functools
import importlib.util
import pytest
from PIL import Image
from examples.offline_inference.image_to_video.image_to_video import build_image_to_video_prompt
from examples.offline_inference.text_to_image.text_to_image import build_text_to_image_prompt
from tests.examples.helpers import EXAMPLES
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
@functools.cache
def _load_example_module(relative_path: str, module_name: str):
path = EXAMPLES / relative_path
spec = importlib.util.spec_from_file_location(module_name, path)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
@pytest.mark.parametrize(
("negative_prompt", "expected_negative_prompt"),
[(None, None), ("", ""), ("blurry", "blurry")],
@@ -20,7 +32,11 @@ def test_text_to_image_builds_canonical_prompt(
negative_prompt: str | None,
expected_negative_prompt: str | None,
) -> None:
result = build_text_to_image_prompt("a red fox", negative_prompt)
mod = _load_example_module(
"offline_inference/text_to_image/text_to_image.py",
"text_to_image_example",
)
result = mod.build_text_to_image_prompt("a red fox", negative_prompt)
assert result["prompt"] == "a red fox"
assert result["modalities"] == ["image"]
@@ -31,9 +47,13 @@ def test_text_to_image_builds_canonical_prompt(
def test_image_to_video_builds_canonical_prompt() -> None:
mod = _load_example_module(
"offline_inference/image_to_video/image_to_video.py",
"image_to_video_example",
)
image = Image.new("RGB", (32, 16), "red")
result = build_image_to_video_prompt(
result = mod.build_image_to_video_prompt(
prompt="the fox turns toward the camera",
negative_prompt="flicker",
media_inputs={"image": image},
@@ -1,3 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
"""
Offline inference tests: text-to-image.
See examples/offline_inference/text_to_image/README.md
@@ -26,6 +29,8 @@ EXAMPLE_OUTPUT_SUBFOLDER = "example_offline_t2i"
def _skip_readme_snippet(language: str, code: str, h2_title: str) -> tuple[bool, str]:
if h2_title == "Web UI Demo":
return True, f"README section '{h2_title}' is intentionally excluded for examples tests"
if "krea/Krea-2-Raw" in code:
return True, "krea/Krea-2-Raw is gated on Hugging Face Hub; CI has no access"
return False, ""
@@ -3,19 +3,27 @@
from __future__ import annotations
import functools
import importlib.util
import pytest
import torch
from examples.offline_inference.text_to_video.text_to_video import (
_MODEL_PRESETS,
_detect_preset,
_normalize_float_tensor,
build_text_to_video_prompt,
)
from tests.examples.helpers import EXAMPLES
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
@functools.cache
def _load_text_to_video():
path = EXAMPLES / "offline_inference" / "text_to_video" / "text_to_video.py"
spec = importlib.util.spec_from_file_location("text_to_video_example", path)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
@pytest.mark.parametrize(
("negative_prompt", "expected_negative_prompt"),
[(None, None), ("", ""), ("blurry", "blurry")],
@@ -24,7 +32,8 @@ def test_text_to_video_builds_canonical_prompt(
negative_prompt: str | None,
expected_negative_prompt: str | None,
) -> None:
result = build_text_to_video_prompt("a robot waves", negative_prompt)
mod = _load_text_to_video()
result = mod.build_text_to_video_prompt("a robot waves", negative_prompt)
assert result["prompt"] == "a robot waves"
assert result["modalities"] == ["video"]
@@ -50,11 +59,13 @@ def test_detect_preset_is_scoped_to_model_family(
model_class_name: str | None,
preset_name: str,
) -> None:
assert _detect_preset(model, model_class_name) is _MODEL_PRESETS[preset_name]
mod = _load_text_to_video()
assert mod._detect_preset(model, model_class_name) is mod._MODEL_PRESETS[preset_name]
def test_lingbot_preset_matches_lingbot_defaults() -> None:
assert _MODEL_PRESETS["lingbot"] == {
mod = _load_text_to_video()
assert mod._MODEL_PRESETS["lingbot"] == {
"model_class_name": "LingBotVideoPipeline",
"height": 192,
"width": 320,
@@ -68,24 +79,27 @@ def test_lingbot_preset_matches_lingbot_defaults() -> None:
def test_normalize_float_tensor_preserves_zero_to_one_frames() -> None:
mod = _load_text_to_video()
frames = torch.tensor([0.0, 0.25, 1.0, 1.5])
assert torch.equal(_normalize_float_tensor(frames, "zero_to_one"), torch.tensor([0.0, 0.25, 1.0, 1.0]))
assert torch.equal(mod._normalize_float_tensor(frames, "zero_to_one"), torch.tensor([0.0, 0.25, 1.0, 1.0]))
def test_normalize_float_tensor_maps_negative_one_to_one_frames() -> None:
mod = _load_text_to_video()
frames = torch.tensor([-1.5, -1.0, 0.0, 1.0, 1.5])
assert torch.equal(
_normalize_float_tensor(frames, "negative_one_to_one"),
mod._normalize_float_tensor(frames, "negative_one_to_one"),
torch.tensor([0.0, 0.0, 0.5, 1.0, 1.0]),
)
def test_normalize_float_tensor_uses_one_contract_for_ambiguous_frames() -> None:
mod = _load_text_to_video()
frames = [torch.tensor([0.0, 0.5, 1.0]), torch.tensor([-1.0, 0.0, 1.0])]
normalized = [_normalize_float_tensor(frame, "negative_one_to_one") for frame in frames]
normalized = [mod._normalize_float_tensor(frame, "negative_one_to_one") for frame in frames]
assert torch.equal(normalized[0], torch.tensor([0.5, 0.75, 1.0]))
assert torch.equal(normalized[1], torch.tensor([0.0, 0.5, 1.0]))
@@ -14,7 +14,7 @@ from packaging.requirements import Requirement
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
ROOT = Path(__file__).parents[1]
ROOT = Path(__file__).parents[4]
TEXT_PROCESSING_PATH = ROOT / "vllm_omni" / "model_executor" / "models" / "indextts2" / "text_processing_v2_5.py"
INDEXTTS2_FRONTEND_PACKAGES = {
"fugashi",