[diffusion] feat: support lightweight e2e warmup for benchmarking (#16213)

This commit is contained in:
Mick
2026-01-02 20:10:27 +08:00
committed by GitHub
parent 698629d1f2
commit 5062537b67
15 changed files with 205 additions and 135 deletions
@@ -24,19 +24,13 @@ logger = init_logger(__name__)
class TestResult:
name: str
key: str
duration: Optional[float]
succeed: bool
@property
def duration_str(self):
return f"{self.duration:.4f}" if self.duration else "NA"
def run_command(command) -> Optional[float]:
"""Runs a command and returns the execution time and status."""
print(f"Running command: {shlex.join(command)}")
duration = None
with subprocess.Popen(
command,
stdout=subprocess.PIPE,
@@ -46,15 +40,11 @@ def run_command(command) -> Optional[float]:
) as process:
for line in process.stdout:
sys.stdout.write(line)
if "Pixel data generated" in line:
words = line.split(" ")
duration = float(words[-2])
if process.returncode == 0:
return duration
else:
process.wait()
if process.returncode == 0:
return True
print(f"Command failed with exit code {process.returncode}")
return None
return False
class CLIBase(unittest.TestCase):
@@ -80,13 +70,7 @@ class CLIBase(unittest.TestCase):
f"--output-path={self.output_path}",
]
results = []
@classmethod
def setUpClass(cls):
cls.results = []
def _run_command(self, name: str, model_path: str, test_key: str = "", args=[]):
def _run_command(self, name: str, model_path: str, args=[]):
command = (
self.get_base_command()
+ [f"--model-path={model_path}"]
@@ -94,28 +78,21 @@ class CLIBase(unittest.TestCase):
+ ["--output-file-name", f"{name}"]
+ self.extra_args
)
duration = run_command(command)
status = "Success" if duration else "Failed"
succeed = duration is not None
succeed = run_command(command)
status = "Success" if succeed else "Failed"
duration = float(duration) if succeed else None
self.results.append(TestResult(name, test_key, duration, succeed))
return name, duration, status
return name, status
def _run_test(self, name: str, args, model_path: str, test_key: str):
name, duration, status = self._run_command(
name, args=args, model_path=model_path, test_key=test_key
)
self.verify(status, name, duration)
name, status = self._run_command(name, args=args, model_path=model_path)
self.verify(status, name)
def verify(self, status, name, duration):
def verify(self, status, name):
print("-" * 80)
print("\n" * 3)
# test task status
self.assertEqual(status, "Success", f"{name} command failed")
self.assertIsNotNone(duration, f"Could not parse duration for {name}")
# test output file
path = os.path.join(
@@ -125,7 +102,6 @@ class CLIBase(unittest.TestCase):
if self.data_type == DataType.IMAGE:
with Image.open(path) as image:
check_image_size(self, image, self.width, self.height)
logger.info(f"{name} passed in {duration:.4f}s")
def model_name(self):
return self.model_path.split("/")[-1]
@@ -198,7 +198,9 @@ def run_pytest(files, filter_expr=None):
and "AssertionError" in full_output
)
is_flaky_ci_assertion = "SafetensorError" in full_output
is_flaky_ci_assertion = (
"SafetensorError" in full_output or "FileNotFoundError" in full_output
)
is_oom_error = (
"out of memory" in full_output.lower()
@@ -529,6 +529,31 @@
"expected_avg_denoise_ms": 94.15,
"expected_median_denoise_ms": 102.03
},
"zimage_image_t2i_warmup": {
"stages_ms": {
"InputValidationStage": 0.02,
"TextEncodingStage": 100.65,
"ConditioningStage": 0.01,
"TimestepPreparationStage": 0.98,
"LatentPreparationStage": 0.06,
"DenoisingStage": 889.42,
"DecodingStage": 37.81
},
"denoise_step_ms": {
"0": 16.49,
"1": 94.63,
"2": 109.65,
"3": 110.05,
"4": 109.39,
"5": 110.58,
"6": 109.52,
"7": 110.54,
"8": 115.24
},
"expected_e2e_ms": 1029.96,
"expected_avg_denoise_ms": 98.46,
"expected_median_denoise_ms": 109.65
},
"qwen_image_edit_ti2i": {
"stages_ms": {
"InputValidationStage": 38.62,
@@ -83,6 +83,9 @@ def diffusion_server(case: DiffusionTestCase) -> ServerContext:
if server_args.lora_path:
extra_args += f" --lora-path {server_args.lora_path}"
if server_args.enable_warmup:
extra_args += f" --enable-warmup"
# Build custom environment variables
env_vars = {}
if server_args.enable_cache_dit:
@@ -151,6 +151,8 @@ class DiffusionServerArgs:
ring_degree: int | None = None
# LoRA
lora_path: str | None = None # LoRA adapter path (HF repo or local path)
# misc
enable_warmup: bool = False
dit_layerwise_offload: bool = False
enable_cache_dit: bool = False
@@ -359,6 +361,13 @@ ONE_GPU_CASES_A: list[DiffusionTestCase] = [
),
T2I_sampling_params,
),
DiffusionTestCase(
"zimage_image_t2i_warmup",
DiffusionServerArgs(
model_path="Tongyi-MAI/Z-Image-Turbo", modality="image", enable_warmup=True
),
T2I_sampling_params,
),
# === Text and Image to Image (TI2I) ===
DiffusionTestCase(
"qwen_image_edit_ti2i",