[Diffusion] [NPU] Fix multimodal gen CI (#22879)

This commit is contained in:
Makcum888e
2026-04-17 04:09:44 +03:00
committed by GitHub
parent ba850d3a9d
commit e353630b57
11 changed files with 956 additions and 644 deletions
@@ -20,10 +20,12 @@ from pathlib import Path
import tabulate
from sglang.multimodal_gen.runtime.utils.logging_utils import init_logger
from sglang.multimodal_gen.test.server.testcase_configs import (
BASELINE_CONFIG,
from sglang.multimodal_gen.test.server.gpu_cases import (
ONE_GPU_CASES,
TWO_GPU_CASES,
)
from sglang.multimodal_gen.test.server.testcase_configs import (
BASELINE_CONFIG,
DiffusionTestCase,
)
@@ -67,13 +69,6 @@ FILE_SUITES = {
],
}
suites_ascend = {
"1-npu": ["ascend/test_server_1_npu.py"],
"2-npu": ["ascend/test_server_2_npu.py"],
"8-npu": ["ascend/test_server_8_npu.py"],
}
FILE_SUITES.update(suites_ascend)
PARAMETRIZED_CASE_GROUPS = {
"1-gpu": [
("test_server_1_gpu.py", ONE_GPU_CASES),
@@ -0,0 +1,299 @@
"""
Test runner for multimodal_gen that manages test suites and parallel execution.
Usage:
python3 run_suite_npu.py --suite <suite_name> --partition-id <id> --total-partitions <num>
Example:
python3 run_suite_npu.py --suite 1-npu --partition-id 0 --total-partitions 4
"""
import argparse
import os
import subprocess
import sys
from pathlib import Path
import tabulate
from sglang.multimodal_gen.runtime.utils.logging_utils import init_logger
logger = init_logger(__name__)
SUITES = {
"1-npu": [
"ascend/test_server_1_npu.py",
# add new 1-npu test files here
],
"2-npu": [
"ascend/test_server_2_npu.py",
# add new 2-npu test files here
],
"8-npu": [
"ascend/test_server_8_npu.py",
# add new 8-npu test files here
],
}
def parse_args():
parser = argparse.ArgumentParser(description="Run multimodal_gen test suite")
parser.add_argument(
"--suite",
type=str,
required=True,
choices=list(SUITES.keys()),
help="The test suite to run (valid names are defined in SUITES)",
)
parser.add_argument(
"--partition-id",
type=int,
default=0,
help="Index of the current partition (for parallel execution)",
)
parser.add_argument(
"--total-partitions",
type=int,
default=1,
help="Total number of partitions",
)
parser.add_argument(
"--base-dir",
type=str,
default="server",
help="Base directory for tests relative to this script's parent",
)
parser.add_argument(
"-k",
"--filter",
type=str,
default=None,
help="Pytest filter expression (passed to pytest -k)",
)
parser.add_argument(
"--continue-on-error",
action="store_true",
default=False,
help="Continue running remaining tests even if one fails (for CI consistency; pytest already continues by default)",
)
return parser.parse_args()
def collect_test_items(files, filter_expr=None):
"""Collect test item node IDs from the given files using pytest --collect-only."""
cmd = [sys.executable, "-m", "pytest", "--collect-only", "-q"]
if filter_expr:
cmd.extend(["-k", filter_expr])
cmd.extend(files)
print(f"Collecting tests with command: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True)
# Check for collection errors
# pytest exit codes:
# 0: success
# 1: tests collected but some had errors during collection
# 2: test execution interrupted
# 3: internal error
# 4: command line usage error
# 5: no tests collected (may be expected with filters)
if result.returncode not in (0, 5):
error_msg = (
f"pytest --collect-only failed with exit code {result.returncode}\n"
f"Command: {' '.join(cmd)}\n"
)
if result.stderr:
error_msg += f"stderr:\n{result.stderr}\n"
if result.stdout:
error_msg += f"stdout:\n{result.stdout}\n"
logger.error(error_msg)
raise RuntimeError(error_msg)
if result.returncode == 5:
print(
"No tests were collected (exit code 5). This may be expected with filters."
)
# Parse the output to extract test node IDs
# pytest -q outputs lines like: test_file.py::TestClass::test_method[param]
test_items = []
for line in result.stdout.strip().split("\n"):
line = line.strip()
# Skip empty lines and summary lines
if line and "::" in line and not line.startswith(("=", "-", " ")):
# Handle lines that might have extra info after the test ID
test_id = line.split()[0] if " " in line else line
if "::" in test_id:
test_items.append(test_id)
print(f"Collected {len(test_items)} test items")
return test_items
def run_pytest(files, filter_expr=None, exitfirst=False):
if not files:
print("No files to run.")
return 0
base_cmd = [sys.executable, "-m", "pytest", "-s", "-v"]
if exitfirst:
base_cmd.append("-x")
# Add pytest -k filter if provided
if filter_expr:
base_cmd.extend(["-k", filter_expr])
max_retries = 6
# retry if the perf assertion failed, for {max_retries} times
for i in range(max_retries + 1):
cmd = list(base_cmd)
if i > 0:
cmd.append("--last-failed")
# Always include files to constrain test discovery scope
# This prevents pytest from scanning the entire rootdir and
# discovering unrelated tests that may have missing dependencies
cmd.extend(files)
if i > 0:
print(
f"Performance assertion failed. Retrying ({i}/{max_retries}) with --last-failed..."
)
print(f"Running command: {' '.join(cmd)}")
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
bufsize=0,
)
output_bytes = bytearray()
while True:
chunk = process.stdout.read(4096)
if not chunk:
break
sys.stdout.buffer.write(chunk)
sys.stdout.buffer.flush()
output_bytes.extend(chunk)
process.wait()
returncode = process.returncode
if returncode == 0:
return 0
# Exit code 5 means no tests were collected/selected - treat as success
# when using filters, since some partitions may have all tests filtered out
if returncode == 5:
print(
"No tests collected (exit code 5). This is expected when filters "
"deselect all tests in a partition. Treating as success."
)
return 0
# check if the failure is due to an assertion in test_server_utils.py
full_output = output_bytes.decode("utf-8", errors="replace")
is_perf_assertion = (
"multimodal_gen/test/server/test_server_utils.py" in full_output
and "AssertionError" in full_output
)
is_flaky_ci_assertion = (
"SafetensorError" in full_output
or "FileNotFoundError" in full_output
or "TimeoutError" in full_output
)
is_oom_error = (
"out of memory" in full_output.lower()
or "oom killer" in full_output.lower()
)
if not (is_perf_assertion or is_flaky_ci_assertion or is_oom_error):
return returncode
print(f"Max retry exceeded")
return returncode
def main():
args = parse_args()
# 1. resolve base path
current_file_path = Path(__file__).resolve()
test_root_dir = current_file_path.parent
target_dir = test_root_dir / args.base_dir
if not target_dir.exists():
print(f"Error: Target directory {target_dir} does not exist.")
sys.exit(1)
# 2. get files from suite
suite_files_rel = SUITES[args.suite]
suite_files_abs = []
for f_rel in suite_files_rel:
f_abs = target_dir / f_rel
if not f_abs.exists():
msg = f"Test file {f_rel} not found in {target_dir}."
print(f"Warning: {msg} Skipping.")
continue
suite_files_abs.append(str(f_abs))
if not suite_files_abs:
print(f"No valid test files found for suite '{args.suite}'.")
sys.exit(0)
# 3. collect all test items and partition by items (not files)
all_test_items = collect_test_items(suite_files_abs, filter_expr=args.filter)
if not all_test_items:
print(f"No test items found for suite '{args.suite}'.")
sys.exit(0)
# Partition by test items
my_items = [
item
for i, item in enumerate(all_test_items)
if i % args.total_partitions == args.partition_id
]
# Print test info at beginning (similar to test/run_suite.py pretty_print_tests)
partition_info = f"{args.partition_id + 1}/{args.total_partitions} (0-based id={args.partition_id})"
headers = ["Suite", "Partition"]
rows = [[args.suite, partition_info]]
msg = tabulate.tabulate(rows, headers=headers, tablefmt="psql") + "\n"
msg += f"✅ Enabled {len(my_items)} test(s):\n"
for item in my_items:
msg += f" - {item}\n"
print(msg, flush=True)
print(
f"Suite: {args.suite} | Partition: {args.partition_id}/{args.total_partitions}"
)
print(f"Selected {len(suite_files_abs)} files:")
for f in suite_files_abs:
print(f" - {os.path.basename(f)}")
if not my_items:
print("No items assigned to this partition. Exiting success.")
sys.exit(0)
print(f"Running {len(my_items)} items in this shard: {', '.join(my_items)}")
# 4. execute with the specific test items
# Fast-fail: stop on first failure unless --continue-on-error is set
exit_code = run_pytest(my_items, exitfirst=not args.continue_on_error)
# Print tests again at the end for visibility
msg = "\n" + tabulate.tabulate(rows, headers=headers, tablefmt="psql") + "\n"
msg += f"✅ Executed {len(my_items)} test(s):\n"
for item in my_items:
msg += f" - {item}\n"
print(msg, flush=True)
sys.exit(exit_code)
if __name__ == "__main__":
main()
@@ -1,10 +1,10 @@
from __future__ import annotations
from sglang.multimodal_gen.test.server.testcase_configs import (
from sglang.multimodal_gen.test.server.gpu_cases import (
ONE_GPU_CASES,
TWO_GPU_CASES,
DiffusionTestCase,
)
from sglang.multimodal_gen.test.server.testcase_configs import DiffusionTestCase
def _select_accuracy_cases(
@@ -12,7 +12,7 @@
"TimestepPreparationStage": 53.52,
"LatentPreparationStage": 0.39,
"DenoisingStage": 19423.39,
"DecodingStage": 40.14
"DecodingStage": 196.62
},
"denoise_step_ms": {
"0": 123.16,
@@ -265,7 +265,7 @@
"LatentPreparationStage": 0.69,
"TimestepPreparationStage": 35.29,
"DenoisingStage": 30529.83,
"DecodingStage": 74.25
"DecodingStage": 428.21
},
"denoise_step_ms": {
"0": 477.43,
@@ -63,6 +63,7 @@ EIGHT_NPU_CASES: list[DiffusionTestCase] = [
model_path="/root/.cache/modelscope/hub/models/Eco-Tech/Wan2.2-T2V-A14B-Diffusers-w8a8",
num_gpus=8,
tp_size=4,
ulysses_degree=2,
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
@@ -0,0 +1,639 @@
from sglang.multimodal_gen.runtime.platforms import current_platform
from sglang.multimodal_gen.test.server.testcase_configs import (
MODELOPT_FLUX1_FP8_TRANSFORMER,
MODELOPT_FLUX1_NVFP4_TRANSFORMER,
MODELOPT_FLUX2_FP8_TRANSFORMER,
MODELOPT_FLUX2_NVFP4_MODEL,
MODELOPT_NVFP4_B200_ENV_VARS,
MODELOPT_WAN22_FP8_TRANSFORMER,
MODELOPT_WAN22_NVFP4_TRANSFORMER,
T2V_PROMPT,
DiffusionSamplingParams,
DiffusionServerArgs,
DiffusionTestCase,
HUNYUAN3D_SHAPE_sampling_params,
MODELOPT_T2I_CI_sampling_params,
MODELOPT_T2V_CI_sampling_params,
MULTI_FRAME_I2I_sampling_params,
MULTI_IMAGE_TI2I_sampling_params,
MULTI_IMAGE_TI2I_UPLOAD_sampling_params,
T2I_sampling_params,
T2V_sampling_params,
TI2I_sampling_params,
TI2V_sampling_params,
_make_modelopt_ci_case,
_with_default_num_gpus,
)
from sglang.multimodal_gen.test.test_utils import (
DEFAULT_FLUX_1_DEV_MODEL_NAME_FOR_TEST,
DEFAULT_FLUX_2_DEV_MODEL_NAME_FOR_TEST,
DEFAULT_FLUX_2_KLEIN_4B_MODEL_NAME_FOR_TEST,
DEFAULT_MOVA_360P_MODEL_NAME_FOR_TEST,
DEFAULT_QWEN_IMAGE_EDIT_2509_MODEL_NAME_FOR_TEST,
DEFAULT_QWEN_IMAGE_EDIT_2511_MODEL_NAME_FOR_TEST,
DEFAULT_QWEN_IMAGE_EDIT_MODEL_NAME_FOR_TEST,
DEFAULT_QWEN_IMAGE_LAYERED_MODEL_NAME_FOR_TEST,
DEFAULT_QWEN_IMAGE_MODEL_NAME_FOR_TEST,
DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_1_I2V_14B_480P_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_1_I2V_14B_720P_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_1_T2V_1_3B_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_1_T2V_14B_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_2_I2V_A14B_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_2_T2V_A14B_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_2_TI2V_5B_MODEL_NAME_FOR_TEST,
)
# All test cases with clean default values
# To test different models, simply add more DiffusionCase entries
ONE_GPU_CASES_A: list[DiffusionTestCase] = [
# === Text to Image (T2I) ===
DiffusionTestCase(
"qwen_image_t2i",
DiffusionServerArgs(
model_path=DEFAULT_QWEN_IMAGE_MODEL_NAME_FOR_TEST,
),
T2I_sampling_params,
),
DiffusionTestCase(
"qwen_image_t2i_cache_dit_enabled",
DiffusionServerArgs(
model_path=DEFAULT_QWEN_IMAGE_MODEL_NAME_FOR_TEST,
enable_cache_dit=True,
),
T2I_sampling_params,
),
DiffusionTestCase(
"flux_image_t2i",
DiffusionServerArgs(model_path=DEFAULT_FLUX_1_DEV_MODEL_NAME_FOR_TEST),
T2I_sampling_params,
),
# TODO: modeling of flux different from official flux, so weights can't be loaded
# consider opting for a different quantized hf-repo
# DiffusionTestCase(
# "flux_image_t2i_override_transformer_weights_path_fp8",
# DiffusionServerArgs(
# model_path="black-forest-labs/FLUX.1-dev",
# extras=["--transformer-weights-path black-forest-labs/FLUX.1-dev-FP8"]
# ),
# T2I_sampling_params,
# ),
DiffusionTestCase(
"flux_2_image_t2i",
DiffusionServerArgs(model_path=DEFAULT_FLUX_2_DEV_MODEL_NAME_FOR_TEST),
T2I_sampling_params,
),
DiffusionTestCase(
"flux_2_klein_image_t2i",
DiffusionServerArgs(
model_path=DEFAULT_FLUX_2_KLEIN_4B_MODEL_NAME_FOR_TEST,
),
T2I_sampling_params,
),
# TODO: replace with a faster model to test the --dit-layerwise-offload
# TODO: currently, we don't support sending more than one request in test, and setting `num_outputs_per_prompt` to 2 doesn't guarantee the denoising be executed twice,
# so we do one warmup and send one request instead
DiffusionTestCase(
"layerwise_offload",
DiffusionServerArgs(
model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
dit_layerwise_offload=True,
dit_offload_prefetch_size=2,
),
T2I_sampling_params,
),
DiffusionTestCase(
"zimage_image_t2i",
DiffusionServerArgs(model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST),
T2I_sampling_params,
),
DiffusionTestCase(
"zimage_image_t2i_fp8",
DiffusionServerArgs(
model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
extras=["--transformer-path MickJ/Z-Image-Turbo-fp8"],
),
T2I_sampling_params,
),
# Multi-LoRA test case for Z-Image-Turbo
DiffusionTestCase(
"zimage_image_t2i_multi_lora",
DiffusionServerArgs(
model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
lora_path="reverentelusarca/elusarca-anime-style-lora-z-image-turbo",
second_lora_path="tarn59/pixel_art_style_lora_z_image_turbo",
),
T2I_sampling_params,
run_lora_basic_api_check=True,
run_lora_dynamic_switch_check=True,
run_multi_lora_api_check=True,
),
# === Text and Image to Image (TI2I) ===
DiffusionTestCase(
"qwen_image_edit_ti2i",
DiffusionServerArgs(model_path=DEFAULT_QWEN_IMAGE_EDIT_MODEL_NAME_FOR_TEST),
TI2I_sampling_params,
),
DiffusionTestCase(
"qwen_image_edit_2509_ti2i",
DiffusionServerArgs(
model_path=DEFAULT_QWEN_IMAGE_EDIT_2509_MODEL_NAME_FOR_TEST,
),
MULTI_IMAGE_TI2I_sampling_params,
),
DiffusionTestCase(
"qwen_image_edit_2511_ti2i",
DiffusionServerArgs(
model_path=DEFAULT_QWEN_IMAGE_EDIT_2511_MODEL_NAME_FOR_TEST,
),
TI2I_sampling_params,
),
DiffusionTestCase(
"qwen_image_layered_i2i",
DiffusionServerArgs(
model_path=DEFAULT_QWEN_IMAGE_LAYERED_MODEL_NAME_FOR_TEST,
),
MULTI_FRAME_I2I_sampling_params,
),
# Upscaling (Real-ESRGAN 4×) for T2I
DiffusionTestCase(
"flux_2_image_t2i_upscaling_4x",
DiffusionServerArgs(
model_path="black-forest-labs/FLUX.2-dev",
),
DiffusionSamplingParams(
prompt="Doraemon is eating dorayaki",
output_size="1024x1024",
extras={"enable_upscaling": True, "upscaling_scale": 4},
),
),
]
ONE_GPU_CASES_B: list[DiffusionTestCase] = [
# === Text to Video (T2V) ===
DiffusionTestCase(
"wan2_1_t2v_1.3b",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_T2V_1_3B_MODEL_NAME_FOR_TEST,
),
T2V_sampling_params,
),
DiffusionTestCase(
"wan2_1_t2v_1.3b_text_encoder_cpu_offload",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_T2V_1_3B_MODEL_NAME_FOR_TEST,
text_encoder_cpu_offload=True,
),
T2V_sampling_params,
),
# TeaCache acceleration test for Wan video model
DiffusionTestCase(
"wan2_1_t2v_1.3b_teacache_enabled",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_T2V_1_3B_MODEL_NAME_FOR_TEST,
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
extras={"enable_teacache": True},
),
),
# Frame interpolation (2× / exp=1)
# Uses the same 1.3B model already in the suite;
DiffusionTestCase(
"wan2_1_t2v_1.3b_frame_interp_2x",
DiffusionServerArgs(
model_path="Wan-AI/Wan2.1-T2V-1.3B-Diffusers",
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
extras={"enable_frame_interpolation": True, "frame_interpolation_exp": 1},
),
),
# Upscaling (Real-ESRGAN 4×)
# Uses the same 1.3B model already in the suite;
DiffusionTestCase(
"wan2_1_t2v_1.3b_upscaling_4x",
DiffusionServerArgs(
model_path="Wan-AI/Wan2.1-T2V-1.3B-Diffusers",
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
extras={"enable_upscaling": True, "upscaling_scale": 4},
),
),
# Combined: Frame interpolation (2×) + Upscaling (4×)
# Verifies that both post-processing steps compose correctly.
DiffusionTestCase(
"wan2_1_t2v_1.3b_frame_interp_2x_upscaling_4x",
DiffusionServerArgs(
model_path="Wan-AI/Wan2.1-T2V-1.3B-Diffusers",
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
extras={
"enable_frame_interpolation": True,
"frame_interpolation_exp": 1,
"enable_upscaling": True,
"upscaling_scale": 4,
},
),
),
# LoRA test case for single transformer + merge/unmerge API test
# Note: Uses dynamic_lora_path instead of lora_path to test LayerwiseOffload + set_lora interaction
# Server starts WITHOUT LoRA, then set_lora is called after startup (Wan models auto-enable layerwise offload)
DiffusionTestCase(
"wan2_1_t2v_1_3b_lora_1gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_T2V_1_3B_MODEL_NAME_FOR_TEST,
num_gpus=1,
dynamic_lora_path="Cseti/Wan-LoRA-Arcane-Jinx-v1",
),
DiffusionSamplingParams(
prompt="csetiarcane Nfj1nx with blue hair, a woman walking in a cyberpunk city at night",
),
run_lora_basic_api_check=True,
run_lora_dynamic_load_check=True,
),
# NOTE(mick): flaky
# DiffusionTestCase(
# "hunyuan_video",
# DiffusionServerArgs(
# model_path="hunyuanvideo-community/HunyuanVideo",
# ),
# DiffusionSamplingParams(
# prompt=T2V_PROMPT,
# ),
# ),
DiffusionTestCase(
"flux_2_ti2i",
DiffusionServerArgs(model_path=DEFAULT_FLUX_2_DEV_MODEL_NAME_FOR_TEST),
TI2I_sampling_params,
),
DiffusionTestCase(
"flux_2_t2i_customized_vae_path",
DiffusionServerArgs(
model_path=DEFAULT_FLUX_2_DEV_MODEL_NAME_FOR_TEST,
extras=["--vae-path=fal/FLUX.2-Tiny-AutoEncoder"],
),
T2I_sampling_params,
run_perf_check=False,
),
DiffusionTestCase(
"fast_hunyuan_video",
DiffusionServerArgs(
model_path="FastVideo/FastHunyuan-diffusers",
),
T2V_sampling_params,
),
# === Text and Image to Video (TI2V) ===
DiffusionTestCase(
"wan2_2_ti2v_5b",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_2_TI2V_5B_MODEL_NAME_FOR_TEST,
),
TI2V_sampling_params,
),
DiffusionTestCase(
"fastwan2_2_ti2v_5b",
DiffusionServerArgs(
model_path="FastVideo/FastWan2.2-TI2V-5B-FullAttn-Diffusers",
),
TI2V_sampling_params,
),
# flaky
# === Helios T2V ===
# DiffusionTestCase(
# "helios_base_t2v",
# DiffusionServerArgs(
# model_path="BestWishYsh/Helios-Base",
# ),
# DiffusionSamplingParams(
# prompt=T2V_PROMPT,
# output_size="640x384",
# num_frames=33,
# ),
# ),
# DiffusionTestCase(
# "helios_mid_t2v",
# DiffusionServerArgs(
# model_path="BestWishYsh/Helios-Mid",
# ),
# DiffusionSamplingParams(
# prompt=T2V_PROMPT,
# output_size="640x384",
# num_frames=33,
# ),
# ),
# DiffusionTestCase(
# "helios_distilled_t2v",
# DiffusionServerArgs(
# model_path="BestWishYsh/Helios-Distilled",
# ),
# DiffusionSamplingParams(
# prompt=T2V_PROMPT,
# output_size="640x384",
# num_frames=33,
# ),
# ),
]
# Skip hunyuan3d on AMD: marching_cubes surface extraction produces invalid SDF on ROCm.
if not current_platform.is_hip():
ONE_GPU_CASES_B.append(
DiffusionTestCase(
"hunyuan3d_shape_gen",
DiffusionServerArgs(
model_path="tencent/Hunyuan3D-2",
enable_warmup=False,
),
HUNYUAN3D_SHAPE_sampling_params,
run_consistency_check=False,
),
)
# Skip turbowan on AMD: Triton requires 81920 shared memory, but AMD only has 65536.
if not current_platform.is_hip():
ONE_GPU_CASES_B.append(
DiffusionTestCase(
"turbo_wan2_1_t2v_1.3b",
DiffusionServerArgs(
model_path="IPostYellow/TurboWan2.1-T2V-1.3B-Diffusers",
),
T2V_sampling_params,
)
)
ONE_GPU_CASES_C = [
_make_modelopt_ci_case(
"flux1_modelopt_fp8_t2i",
model_path=DEFAULT_FLUX_1_DEV_MODEL_NAME_FOR_TEST,
modality="image",
sampling_params=MODELOPT_T2I_CI_sampling_params,
extras=["--transformer-path", MODELOPT_FLUX1_FP8_TRANSFORMER],
),
_make_modelopt_ci_case(
"flux2_modelopt_fp8_t2i",
model_path=DEFAULT_FLUX_2_DEV_MODEL_NAME_FOR_TEST,
modality="image",
sampling_params=MODELOPT_T2I_CI_sampling_params,
extras=["--transformer-path", MODELOPT_FLUX2_FP8_TRANSFORMER],
),
_make_modelopt_ci_case(
"wan22_modelopt_fp8_t2v",
model_path=DEFAULT_WAN_2_2_T2V_A14B_MODEL_NAME_FOR_TEST,
modality="video",
sampling_params=MODELOPT_T2V_CI_sampling_params,
extras=["--transformer-path", MODELOPT_WAN22_FP8_TRANSFORMER],
),
_make_modelopt_ci_case(
"flux1_modelopt_nvfp4_t2i",
model_path=DEFAULT_FLUX_1_DEV_MODEL_NAME_FOR_TEST,
modality="image",
sampling_params=MODELOPT_T2I_CI_sampling_params,
extras=["--transformer-path", MODELOPT_FLUX1_NVFP4_TRANSFORMER],
env_vars=MODELOPT_NVFP4_B200_ENV_VARS,
),
_make_modelopt_ci_case(
"flux2_modelopt_nvfp4_t2i",
model_path=MODELOPT_FLUX2_NVFP4_MODEL,
modality="image",
sampling_params=MODELOPT_T2I_CI_sampling_params,
extras=[],
env_vars=MODELOPT_NVFP4_B200_ENV_VARS,
),
_make_modelopt_ci_case(
"wan22_modelopt_nvfp4_t2v",
model_path=DEFAULT_WAN_2_2_T2V_A14B_MODEL_NAME_FOR_TEST,
modality="video",
sampling_params=MODELOPT_T2V_CI_sampling_params,
extras=["--transformer-path", MODELOPT_WAN22_NVFP4_TRANSFORMER],
env_vars=MODELOPT_NVFP4_B200_ENV_VARS,
),
]
TWO_GPU_CASES_A = [
DiffusionTestCase(
"wan2_2_i2v_a14b_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_2_I2V_A14B_MODEL_NAME_FOR_TEST,
),
TI2V_sampling_params,
),
DiffusionTestCase(
"wan2_2_t2v_a14b_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_2_T2V_A14B_MODEL_NAME_FOR_TEST,
extras=["--ulysses-degree=2"],
),
T2V_sampling_params,
),
# TeaCache bring-up test for Wan2.2 T2V A14B — verifies enable_teacache=True
# doesn't crash. Perf check disabled because Wan2.2-specific TeaCache
# coefficients are not yet calibrated (teacache_params=None, so no speedup).
DiffusionTestCase(
"wan2_2_t2v_a14b_teacache_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_2_T2V_A14B_MODEL_NAME_FOR_TEST,
extras=["--ulysses-degree=2"],
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
extras={"enable_teacache": True},
),
run_perf_check=False,
),
# LoRA test case for transformer_2 support
DiffusionTestCase(
"wan2_2_t2v_a14b_lora_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_2_T2V_A14B_MODEL_NAME_FOR_TEST,
lora_path="Cseti/wan2.2-14B-Arcane_Jinx-lora-v1",
extras=[
"--lora-weight-name",
"985347-wan22_14B-low-Nfj1nx-e65.safetensors",
],
),
DiffusionSamplingParams(
prompt="Nfj1nx with blue hair, a woman walking in a cyberpunk city at night",
),
run_lora_basic_api_check=True,
),
DiffusionTestCase(
"wan2_1_t2v_14b_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_T2V_14B_MODEL_NAME_FOR_TEST,
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
output_size="832x480",
),
),
DiffusionTestCase(
"wan2_1_t2v_1.3b_cfg_parallel",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_T2V_1_3B_MODEL_NAME_FOR_TEST,
cfg_parallel=True,
),
T2V_sampling_params,
),
DiffusionTestCase(
"fsdp-inference",
DiffusionServerArgs(
model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
extras=["--use-fsdp-inference"],
),
T2I_sampling_params,
),
DiffusionTestCase(
"mova_360p_tp2",
DiffusionServerArgs(
model_path=DEFAULT_MOVA_360P_MODEL_NAME_FOR_TEST,
tp_size=2,
dit_layerwise_offload=True,
),
TI2V_sampling_params,
run_perf_check=False,
),
DiffusionTestCase(
"mova_360p_ring1_uly2",
DiffusionServerArgs(
model_path=DEFAULT_MOVA_360P_MODEL_NAME_FOR_TEST,
ring_degree=1,
ulysses_degree=2,
dit_layerwise_offload=True,
),
TI2V_sampling_params,
run_perf_check=False,
),
DiffusionTestCase(
"ltx_2_two_stage_t2v",
DiffusionServerArgs(
model_path="Lightricks/LTX-2",
ulysses_degree=2,
dit_layerwise_offload=True,
extras=["--pipeline-class-name LTX2TwoStagePipeline"],
),
T2V_sampling_params,
),
DiffusionTestCase(
"ltx_2_3_two_stage_ti2v_2gpus",
DiffusionServerArgs(
model_path="Lightricks/LTX-2.3",
extras=["--pipeline-class-name LTX2TwoStagePipeline"],
),
TI2V_sampling_params,
),
]
TWO_GPU_CASES_B = [
DiffusionTestCase(
"wan2_1_i2v_14b_480P_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_I2V_14B_480P_MODEL_NAME_FOR_TEST,
extras=["--ulysses-degree=2"],
),
TI2V_sampling_params,
),
DiffusionTestCase(
"ltx_2.3_two_stage_t2v_2gpus",
DiffusionServerArgs(
model_path="Lightricks/LTX-2.3",
extras=["--pipeline-class-name LTX2TwoStagePipeline"],
),
T2V_sampling_params,
),
# I2V LoRA test case
DiffusionTestCase(
"wan2_1_i2v_14b_lora_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_I2V_14B_720P_MODEL_NAME_FOR_TEST,
lora_path="starsfriday/Wan2.1-Divine-Power-LoRA",
extras=["--ulysses-degree=2"],
),
TI2V_sampling_params,
run_lora_basic_api_check=True,
),
DiffusionTestCase(
"wan2_1_i2v_14b_720P_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_I2V_14B_720P_MODEL_NAME_FOR_TEST,
extras=["--ulysses-degree=2"],
),
TI2V_sampling_params,
),
DiffusionTestCase(
"qwen_image_t2i_2_gpus",
DiffusionServerArgs(
model_path=DEFAULT_QWEN_IMAGE_MODEL_NAME_FOR_TEST,
# test ring attn
ulysses_degree=1,
ring_degree=2,
),
T2I_sampling_params,
),
DiffusionTestCase(
"zimage_image_t2i_2_gpus",
DiffusionServerArgs(
model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
ulysses_degree=2,
),
T2I_sampling_params,
),
DiffusionTestCase(
"zimage_image_t2i_2_gpus_non_square",
DiffusionServerArgs(
model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
ulysses_degree=2,
),
DiffusionSamplingParams(
prompt=T2I_sampling_params.prompt,
output_size="1280x720",
),
run_perf_check=False,
),
DiffusionTestCase(
"flux_image_t2i_2_gpus",
DiffusionServerArgs(
model_path=DEFAULT_FLUX_1_DEV_MODEL_NAME_FOR_TEST,
),
T2I_sampling_params,
),
DiffusionTestCase(
"flux_2_image_t2i_2_gpus",
DiffusionServerArgs(
model_path=DEFAULT_FLUX_2_DEV_MODEL_NAME_FOR_TEST,
tp_size=2,
),
T2I_sampling_params,
),
DiffusionTestCase(
"flux_2_klein_ti2i_2_gpus",
DiffusionServerArgs(
model_path="black-forest-labs/FLUX.2-klein-4B",
),
TI2I_sampling_params,
),
DiffusionTestCase(
"ltx_2.3_one_stage_ti2v",
DiffusionServerArgs(
model_path="Lightricks/LTX-2.3",
),
TI2V_sampling_params,
),
]
if not current_platform.is_hip():
# Flux2 multi-image edit with cache-dit, regression test
ONE_GPU_CASES_B.append(
DiffusionTestCase(
"flux_2_ti2i_multi_image_cache_dit",
DiffusionServerArgs(
model_path="black-forest-labs/FLUX.2-dev",
enable_cache_dit=True,
),
MULTI_IMAGE_TI2I_UPLOAD_sampling_params,
)
)
ONE_GPU_CASES = [*ONE_GPU_CASES_A, *ONE_GPU_CASES_B, *ONE_GPU_CASES_C]
TWO_GPU_CASES_A = _with_default_num_gpus(TWO_GPU_CASES_A, 2)
TWO_GPU_CASES_B = _with_default_num_gpus(TWO_GPU_CASES_B, 2)
TWO_GPU_CASES = [*TWO_GPU_CASES_A, *TWO_GPU_CASES_B]
@@ -10,14 +10,12 @@ from __future__ import annotations
import pytest
from sglang.multimodal_gen.runtime.utils.logging_utils import init_logger
from sglang.multimodal_gen.test.server.gpu_cases import ONE_GPU_CASES
from sglang.multimodal_gen.test.server.test_server_common import ( # noqa: F401
DiffusionServerBase,
diffusion_server,
)
from sglang.multimodal_gen.test.server.testcase_configs import (
ONE_GPU_CASES,
DiffusionTestCase,
)
from sglang.multimodal_gen.test.server.testcase_configs import DiffusionTestCase
logger = init_logger(__name__)
@@ -6,14 +6,12 @@ from __future__ import annotations
import pytest
from sglang.multimodal_gen.test.server.gpu_cases import TWO_GPU_CASES
from sglang.multimodal_gen.test.server.test_server_common import ( # noqa: F401
DiffusionServerBase,
diffusion_server,
)
from sglang.multimodal_gen.test.server.testcase_configs import (
TWO_GPU_CASES,
DiffusionTestCase,
)
from sglang.multimodal_gen.test.server.testcase_configs import DiffusionTestCase
class TestDiffusionServerTwoGpu(DiffusionServerBase):
@@ -7,14 +7,12 @@ from __future__ import annotations
import pytest
from sglang.multimodal_gen.runtime.utils.logging_utils import init_logger
from sglang.multimodal_gen.test.server.gpu_cases import ONE_GPU_CASES_C
from sglang.multimodal_gen.test.server.test_server_common import ( # noqa: F401
DiffusionServerBase,
diffusion_server,
)
from sglang.multimodal_gen.test.server.testcase_configs import (
ONE_GPU_CASES_C,
DiffusionTestCase,
)
from sglang.multimodal_gen.test.server.testcase_configs import DiffusionTestCase
logger = init_logger(__name__)
@@ -29,27 +29,7 @@ from typing import Sequence
from sglang.multimodal_gen.configs.pipeline_configs.base import ModelTaskType
from sglang.multimodal_gen.registry import get_model_info
from sglang.multimodal_gen.runtime.platforms import current_platform
from sglang.multimodal_gen.runtime.utils.perf_logger import RequestPerfRecord
from sglang.multimodal_gen.test.test_utils import (
DEFAULT_FLUX_1_DEV_MODEL_NAME_FOR_TEST,
DEFAULT_FLUX_2_DEV_MODEL_NAME_FOR_TEST,
DEFAULT_FLUX_2_KLEIN_4B_MODEL_NAME_FOR_TEST,
DEFAULT_MOVA_360P_MODEL_NAME_FOR_TEST,
DEFAULT_QWEN_IMAGE_EDIT_2509_MODEL_NAME_FOR_TEST,
DEFAULT_QWEN_IMAGE_EDIT_2511_MODEL_NAME_FOR_TEST,
DEFAULT_QWEN_IMAGE_EDIT_MODEL_NAME_FOR_TEST,
DEFAULT_QWEN_IMAGE_LAYERED_MODEL_NAME_FOR_TEST,
DEFAULT_QWEN_IMAGE_MODEL_NAME_FOR_TEST,
DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_1_I2V_14B_480P_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_1_I2V_14B_720P_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_1_T2V_1_3B_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_1_T2V_14B_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_2_I2V_A14B_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_2_T2V_A14B_MODEL_NAME_FOR_TEST,
DEFAULT_WAN_2_2_TI2V_5B_MODEL_NAME_FOR_TEST,
)
@dataclass
@@ -445,329 +425,11 @@ TURBOWAN_I2V_sampling_params = DiffusionSamplingParams(
fps=4,
)
# All test cases with clean default values
# To test different models, simply add more DiffusionCase entries
ONE_GPU_CASES_A: list[DiffusionTestCase] = [
# === Text to Image (T2I) ===
DiffusionTestCase(
"qwen_image_t2i",
DiffusionServerArgs(
model_path=DEFAULT_QWEN_IMAGE_MODEL_NAME_FOR_TEST,
),
T2I_sampling_params,
),
DiffusionTestCase(
"qwen_image_t2i_cache_dit_enabled",
DiffusionServerArgs(
model_path=DEFAULT_QWEN_IMAGE_MODEL_NAME_FOR_TEST,
enable_cache_dit=True,
),
T2I_sampling_params,
),
DiffusionTestCase(
"flux_image_t2i",
DiffusionServerArgs(model_path=DEFAULT_FLUX_1_DEV_MODEL_NAME_FOR_TEST),
T2I_sampling_params,
),
# TODO: modeling of flux different from official flux, so weights can't be loaded
# consider opting for a different quantized hf-repo
# DiffusionTestCase(
# "flux_image_t2i_override_transformer_weights_path_fp8",
# DiffusionServerArgs(
# model_path="black-forest-labs/FLUX.1-dev",
# extras=["--transformer-weights-path black-forest-labs/FLUX.1-dev-FP8"]
# ),
# T2I_sampling_params,
# ),
DiffusionTestCase(
"flux_2_image_t2i",
DiffusionServerArgs(model_path=DEFAULT_FLUX_2_DEV_MODEL_NAME_FOR_TEST),
T2I_sampling_params,
),
DiffusionTestCase(
"flux_2_klein_image_t2i",
DiffusionServerArgs(
model_path=DEFAULT_FLUX_2_KLEIN_4B_MODEL_NAME_FOR_TEST,
),
T2I_sampling_params,
),
# TODO: replace with a faster model to test the --dit-layerwise-offload
# TODO: currently, we don't support sending more than one request in test, and setting `num_outputs_per_prompt` to 2 doesn't guarantee the denoising be executed twice,
# so we do one warmup and send one request instead
DiffusionTestCase(
"layerwise_offload",
DiffusionServerArgs(
model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
dit_layerwise_offload=True,
dit_offload_prefetch_size=2,
),
T2I_sampling_params,
),
DiffusionTestCase(
"zimage_image_t2i",
DiffusionServerArgs(model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST),
T2I_sampling_params,
),
DiffusionTestCase(
"zimage_image_t2i_fp8",
DiffusionServerArgs(
model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
extras=["--transformer-path MickJ/Z-Image-Turbo-fp8"],
),
T2I_sampling_params,
),
# Multi-LoRA test case for Z-Image-Turbo
DiffusionTestCase(
"zimage_image_t2i_multi_lora",
DiffusionServerArgs(
model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
lora_path="reverentelusarca/elusarca-anime-style-lora-z-image-turbo",
second_lora_path="tarn59/pixel_art_style_lora_z_image_turbo",
),
T2I_sampling_params,
run_lora_basic_api_check=True,
run_lora_dynamic_switch_check=True,
run_multi_lora_api_check=True,
),
# === Text and Image to Image (TI2I) ===
DiffusionTestCase(
"qwen_image_edit_ti2i",
DiffusionServerArgs(model_path=DEFAULT_QWEN_IMAGE_EDIT_MODEL_NAME_FOR_TEST),
TI2I_sampling_params,
),
DiffusionTestCase(
"qwen_image_edit_2509_ti2i",
DiffusionServerArgs(
model_path=DEFAULT_QWEN_IMAGE_EDIT_2509_MODEL_NAME_FOR_TEST,
),
MULTI_IMAGE_TI2I_sampling_params,
),
DiffusionTestCase(
"qwen_image_edit_2511_ti2i",
DiffusionServerArgs(
model_path=DEFAULT_QWEN_IMAGE_EDIT_2511_MODEL_NAME_FOR_TEST,
),
TI2I_sampling_params,
),
DiffusionTestCase(
"qwen_image_layered_i2i",
DiffusionServerArgs(
model_path=DEFAULT_QWEN_IMAGE_LAYERED_MODEL_NAME_FOR_TEST,
),
MULTI_FRAME_I2I_sampling_params,
),
# Upscaling (Real-ESRGAN 4×) for T2I
DiffusionTestCase(
"flux_2_image_t2i_upscaling_4x",
DiffusionServerArgs(
model_path="black-forest-labs/FLUX.2-dev",
),
DiffusionSamplingParams(
prompt="Doraemon is eating dorayaki",
output_size="1024x1024",
extras={"enable_upscaling": True, "upscaling_scale": 4},
),
),
]
HUNYUAN3D_SHAPE_sampling_params = DiffusionSamplingParams(
prompt="",
image_path="https://raw.githubusercontent.com/sgl-project/sgl-test-files/main/diffusion-ci/consistency_gt/1-gpu/hunyuan3d_2_0/hunyuan3d.png",
)
ONE_GPU_CASES_B: list[DiffusionTestCase] = [
# === Text to Video (T2V) ===
DiffusionTestCase(
"wan2_1_t2v_1.3b",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_T2V_1_3B_MODEL_NAME_FOR_TEST,
),
T2V_sampling_params,
),
DiffusionTestCase(
"wan2_1_t2v_1.3b_text_encoder_cpu_offload",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_T2V_1_3B_MODEL_NAME_FOR_TEST,
text_encoder_cpu_offload=True,
),
T2V_sampling_params,
),
# TeaCache acceleration test for Wan video model
DiffusionTestCase(
"wan2_1_t2v_1.3b_teacache_enabled",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_T2V_1_3B_MODEL_NAME_FOR_TEST,
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
extras={"enable_teacache": True},
),
),
# Frame interpolation (2× / exp=1)
# Uses the same 1.3B model already in the suite;
DiffusionTestCase(
"wan2_1_t2v_1.3b_frame_interp_2x",
DiffusionServerArgs(
model_path="Wan-AI/Wan2.1-T2V-1.3B-Diffusers",
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
extras={"enable_frame_interpolation": True, "frame_interpolation_exp": 1},
),
),
# Upscaling (Real-ESRGAN 4×)
# Uses the same 1.3B model already in the suite;
DiffusionTestCase(
"wan2_1_t2v_1.3b_upscaling_4x",
DiffusionServerArgs(
model_path="Wan-AI/Wan2.1-T2V-1.3B-Diffusers",
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
extras={"enable_upscaling": True, "upscaling_scale": 4},
),
),
# Combined: Frame interpolation (2×) + Upscaling (4×)
# Verifies that both post-processing steps compose correctly.
DiffusionTestCase(
"wan2_1_t2v_1.3b_frame_interp_2x_upscaling_4x",
DiffusionServerArgs(
model_path="Wan-AI/Wan2.1-T2V-1.3B-Diffusers",
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
extras={
"enable_frame_interpolation": True,
"frame_interpolation_exp": 1,
"enable_upscaling": True,
"upscaling_scale": 4,
},
),
),
# LoRA test case for single transformer + merge/unmerge API test
# Note: Uses dynamic_lora_path instead of lora_path to test LayerwiseOffload + set_lora interaction
# Server starts WITHOUT LoRA, then set_lora is called after startup (Wan models auto-enable layerwise offload)
DiffusionTestCase(
"wan2_1_t2v_1_3b_lora_1gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_T2V_1_3B_MODEL_NAME_FOR_TEST,
num_gpus=1,
dynamic_lora_path="Cseti/Wan-LoRA-Arcane-Jinx-v1",
),
DiffusionSamplingParams(
prompt="csetiarcane Nfj1nx with blue hair, a woman walking in a cyberpunk city at night",
),
run_lora_basic_api_check=True,
run_lora_dynamic_load_check=True,
),
# NOTE(mick): flaky
# DiffusionTestCase(
# "hunyuan_video",
# DiffusionServerArgs(
# model_path="hunyuanvideo-community/HunyuanVideo",
# ),
# DiffusionSamplingParams(
# prompt=T2V_PROMPT,
# ),
# ),
DiffusionTestCase(
"flux_2_ti2i",
DiffusionServerArgs(model_path=DEFAULT_FLUX_2_DEV_MODEL_NAME_FOR_TEST),
TI2I_sampling_params,
),
DiffusionTestCase(
"flux_2_t2i_customized_vae_path",
DiffusionServerArgs(
model_path=DEFAULT_FLUX_2_DEV_MODEL_NAME_FOR_TEST,
extras=["--vae-path=fal/FLUX.2-Tiny-AutoEncoder"],
),
T2I_sampling_params,
run_perf_check=False,
),
DiffusionTestCase(
"fast_hunyuan_video",
DiffusionServerArgs(
model_path="FastVideo/FastHunyuan-diffusers",
),
T2V_sampling_params,
),
# === Text and Image to Video (TI2V) ===
DiffusionTestCase(
"wan2_2_ti2v_5b",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_2_TI2V_5B_MODEL_NAME_FOR_TEST,
),
TI2V_sampling_params,
),
DiffusionTestCase(
"fastwan2_2_ti2v_5b",
DiffusionServerArgs(
model_path="FastVideo/FastWan2.2-TI2V-5B-FullAttn-Diffusers",
),
TI2V_sampling_params,
),
# flaky
# === Helios T2V ===
# DiffusionTestCase(
# "helios_base_t2v",
# DiffusionServerArgs(
# model_path="BestWishYsh/Helios-Base",
# ),
# DiffusionSamplingParams(
# prompt=T2V_PROMPT,
# output_size="640x384",
# num_frames=33,
# ),
# ),
# DiffusionTestCase(
# "helios_mid_t2v",
# DiffusionServerArgs(
# model_path="BestWishYsh/Helios-Mid",
# ),
# DiffusionSamplingParams(
# prompt=T2V_PROMPT,
# output_size="640x384",
# num_frames=33,
# ),
# ),
# DiffusionTestCase(
# "helios_distilled_t2v",
# DiffusionServerArgs(
# model_path="BestWishYsh/Helios-Distilled",
# ),
# DiffusionSamplingParams(
# prompt=T2V_PROMPT,
# output_size="640x384",
# num_frames=33,
# ),
# ),
]
# Skip hunyuan3d on AMD: marching_cubes surface extraction produces invalid SDF on ROCm.
if not current_platform.is_hip():
ONE_GPU_CASES_B.append(
DiffusionTestCase(
"hunyuan3d_shape_gen",
DiffusionServerArgs(
model_path="tencent/Hunyuan3D-2",
enable_warmup=False,
),
HUNYUAN3D_SHAPE_sampling_params,
run_consistency_check=False,
),
)
# Skip turbowan on AMD: Triton requires 81920 shared memory, but AMD only has 65536.
if not current_platform.is_hip():
ONE_GPU_CASES_B.append(
DiffusionTestCase(
"turbo_wan2_1_t2v_1.3b",
DiffusionServerArgs(
model_path="IPostYellow/TurboWan2.1-T2V-1.3B-Diffusers",
),
T2V_sampling_params,
)
)
MODELOPT_FLUX1_FP8_TRANSFORMER = "BBuf/flux1-dev-modelopt-fp8-sglang-transformer"
MODELOPT_FLUX2_FP8_TRANSFORMER = "BBuf/flux2-dev-modelopt-fp8-sglang-transformer"
MODELOPT_WAN22_FP8_TRANSFORMER = "BBuf/wan22-t2v-a14b-modelopt-fp8-sglang-transformer"
@@ -803,279 +465,6 @@ def _make_modelopt_ci_case(
)
ONE_GPU_CASES_C = [
_make_modelopt_ci_case(
"flux1_modelopt_fp8_t2i",
model_path=DEFAULT_FLUX_1_DEV_MODEL_NAME_FOR_TEST,
modality="image",
sampling_params=MODELOPT_T2I_CI_sampling_params,
extras=["--transformer-path", MODELOPT_FLUX1_FP8_TRANSFORMER],
),
_make_modelopt_ci_case(
"flux2_modelopt_fp8_t2i",
model_path=DEFAULT_FLUX_2_DEV_MODEL_NAME_FOR_TEST,
modality="image",
sampling_params=MODELOPT_T2I_CI_sampling_params,
extras=["--transformer-path", MODELOPT_FLUX2_FP8_TRANSFORMER],
),
_make_modelopt_ci_case(
"wan22_modelopt_fp8_t2v",
model_path=DEFAULT_WAN_2_2_T2V_A14B_MODEL_NAME_FOR_TEST,
modality="video",
sampling_params=MODELOPT_T2V_CI_sampling_params,
extras=["--transformer-path", MODELOPT_WAN22_FP8_TRANSFORMER],
),
_make_modelopt_ci_case(
"flux1_modelopt_nvfp4_t2i",
model_path=DEFAULT_FLUX_1_DEV_MODEL_NAME_FOR_TEST,
modality="image",
sampling_params=MODELOPT_T2I_CI_sampling_params,
extras=["--transformer-path", MODELOPT_FLUX1_NVFP4_TRANSFORMER],
env_vars=MODELOPT_NVFP4_B200_ENV_VARS,
),
_make_modelopt_ci_case(
"flux2_modelopt_nvfp4_t2i",
model_path=MODELOPT_FLUX2_NVFP4_MODEL,
modality="image",
sampling_params=MODELOPT_T2I_CI_sampling_params,
extras=[],
env_vars=MODELOPT_NVFP4_B200_ENV_VARS,
),
_make_modelopt_ci_case(
"wan22_modelopt_nvfp4_t2v",
model_path=DEFAULT_WAN_2_2_T2V_A14B_MODEL_NAME_FOR_TEST,
modality="video",
sampling_params=MODELOPT_T2V_CI_sampling_params,
extras=["--transformer-path", MODELOPT_WAN22_NVFP4_TRANSFORMER],
env_vars=MODELOPT_NVFP4_B200_ENV_VARS,
),
]
TWO_GPU_CASES_A = [
DiffusionTestCase(
"wan2_2_i2v_a14b_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_2_I2V_A14B_MODEL_NAME_FOR_TEST,
),
TI2V_sampling_params,
),
DiffusionTestCase(
"wan2_2_t2v_a14b_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_2_T2V_A14B_MODEL_NAME_FOR_TEST,
extras=["--ulysses-degree=2"],
),
T2V_sampling_params,
),
# TeaCache bring-up test for Wan2.2 T2V A14B — verifies enable_teacache=True
# doesn't crash. Perf check disabled because Wan2.2-specific TeaCache
# coefficients are not yet calibrated (teacache_params=None, so no speedup).
DiffusionTestCase(
"wan2_2_t2v_a14b_teacache_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_2_T2V_A14B_MODEL_NAME_FOR_TEST,
extras=["--ulysses-degree=2"],
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
extras={"enable_teacache": True},
),
run_perf_check=False,
),
# LoRA test case for transformer_2 support
DiffusionTestCase(
"wan2_2_t2v_a14b_lora_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_2_T2V_A14B_MODEL_NAME_FOR_TEST,
lora_path="Cseti/wan2.2-14B-Arcane_Jinx-lora-v1",
extras=[
"--lora-weight-name",
"985347-wan22_14B-low-Nfj1nx-e65.safetensors",
],
),
DiffusionSamplingParams(
prompt="Nfj1nx with blue hair, a woman walking in a cyberpunk city at night",
),
run_lora_basic_api_check=True,
),
DiffusionTestCase(
"wan2_1_t2v_14b_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_T2V_14B_MODEL_NAME_FOR_TEST,
),
DiffusionSamplingParams(
prompt=T2V_PROMPT,
output_size="832x480",
),
),
DiffusionTestCase(
"wan2_1_t2v_1.3b_cfg_parallel",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_T2V_1_3B_MODEL_NAME_FOR_TEST,
cfg_parallel=True,
),
T2V_sampling_params,
),
DiffusionTestCase(
"fsdp-inference",
DiffusionServerArgs(
model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
extras=["--use-fsdp-inference"],
),
T2I_sampling_params,
),
DiffusionTestCase(
"mova_360p_tp2",
DiffusionServerArgs(
model_path=DEFAULT_MOVA_360P_MODEL_NAME_FOR_TEST,
tp_size=2,
dit_layerwise_offload=True,
),
TI2V_sampling_params,
run_perf_check=False,
),
DiffusionTestCase(
"mova_360p_ring1_uly2",
DiffusionServerArgs(
model_path=DEFAULT_MOVA_360P_MODEL_NAME_FOR_TEST,
ring_degree=1,
ulysses_degree=2,
dit_layerwise_offload=True,
),
TI2V_sampling_params,
run_perf_check=False,
),
DiffusionTestCase(
"ltx_2_two_stage_t2v",
DiffusionServerArgs(
model_path="Lightricks/LTX-2",
ulysses_degree=2,
dit_layerwise_offload=True,
extras=["--pipeline-class-name LTX2TwoStagePipeline"],
),
T2V_sampling_params,
),
DiffusionTestCase(
"ltx_2_3_two_stage_ti2v_2gpus",
DiffusionServerArgs(
model_path="Lightricks/LTX-2.3",
extras=["--pipeline-class-name LTX2TwoStagePipeline"],
),
TI2V_sampling_params,
),
]
TWO_GPU_CASES_B = [
DiffusionTestCase(
"wan2_1_i2v_14b_480P_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_I2V_14B_480P_MODEL_NAME_FOR_TEST,
extras=["--ulysses-degree=2"],
),
TI2V_sampling_params,
),
DiffusionTestCase(
"ltx_2.3_two_stage_t2v_2gpus",
DiffusionServerArgs(
model_path="Lightricks/LTX-2.3",
extras=["--pipeline-class-name LTX2TwoStagePipeline"],
),
T2V_sampling_params,
),
# I2V LoRA test case
DiffusionTestCase(
"wan2_1_i2v_14b_lora_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_I2V_14B_720P_MODEL_NAME_FOR_TEST,
lora_path="starsfriday/Wan2.1-Divine-Power-LoRA",
extras=["--ulysses-degree=2"],
),
TI2V_sampling_params,
run_lora_basic_api_check=True,
),
DiffusionTestCase(
"wan2_1_i2v_14b_720P_2gpu",
DiffusionServerArgs(
model_path=DEFAULT_WAN_2_1_I2V_14B_720P_MODEL_NAME_FOR_TEST,
extras=["--ulysses-degree=2"],
),
TI2V_sampling_params,
),
DiffusionTestCase(
"qwen_image_t2i_2_gpus",
DiffusionServerArgs(
model_path=DEFAULT_QWEN_IMAGE_MODEL_NAME_FOR_TEST,
# test ring attn
ulysses_degree=1,
ring_degree=2,
),
T2I_sampling_params,
),
DiffusionTestCase(
"zimage_image_t2i_2_gpus",
DiffusionServerArgs(
model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
ulysses_degree=2,
),
T2I_sampling_params,
),
DiffusionTestCase(
"zimage_image_t2i_2_gpus_non_square",
DiffusionServerArgs(
model_path=DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
ulysses_degree=2,
),
DiffusionSamplingParams(
prompt=T2I_sampling_params.prompt,
output_size="1280x720",
),
run_perf_check=False,
),
DiffusionTestCase(
"flux_image_t2i_2_gpus",
DiffusionServerArgs(
model_path=DEFAULT_FLUX_1_DEV_MODEL_NAME_FOR_TEST,
),
T2I_sampling_params,
),
DiffusionTestCase(
"flux_2_image_t2i_2_gpus",
DiffusionServerArgs(
model_path=DEFAULT_FLUX_2_DEV_MODEL_NAME_FOR_TEST,
tp_size=2,
),
T2I_sampling_params,
),
DiffusionTestCase(
"flux_2_klein_ti2i_2_gpus",
DiffusionServerArgs(
model_path="black-forest-labs/FLUX.2-klein-4B",
),
TI2I_sampling_params,
),
DiffusionTestCase(
"ltx_2.3_one_stage_ti2v",
DiffusionServerArgs(
model_path="Lightricks/LTX-2.3",
),
TI2V_sampling_params,
),
]
if not current_platform.is_hip():
# Flux2 multi-image edit with cache-dit, regression test
ONE_GPU_CASES_B.append(
DiffusionTestCase(
"flux_2_ti2i_multi_image_cache_dit",
DiffusionServerArgs(
model_path="black-forest-labs/FLUX.2-dev",
enable_cache_dit=True,
),
MULTI_IMAGE_TI2I_UPLOAD_sampling_params,
)
)
def _with_default_num_gpus(
cases: list[DiffusionTestCase], num_gpus: int
) -> list[DiffusionTestCase]:
@@ -1085,11 +474,6 @@ def _with_default_num_gpus(
]
ONE_GPU_CASES = [*ONE_GPU_CASES_A, *ONE_GPU_CASES_B, *ONE_GPU_CASES_C]
TWO_GPU_CASES_A = _with_default_num_gpus(TWO_GPU_CASES_A, 2)
TWO_GPU_CASES_B = _with_default_num_gpus(TWO_GPU_CASES_B, 2)
TWO_GPU_CASES = [*TWO_GPU_CASES_A, *TWO_GPU_CASES_B]
# Load global configuration
BASELINE_CONFIG = BaselineConfig.load(
Path(__file__).with_name("perf_baselines.json")