[CI] Qwen image edit performance benckmark (#2216)

Signed-off-by: Huang, Zeyu <11222265+fhfuih@users.noreply.github.com>
This commit is contained in:
Zeyu Huang | 黃澤宇 authored and GitHub committed 2026-04-14 11:35:56 +08:00
1 parent dd1389173b
commit 8d23549b29
7 files changed
+608 -59

No files matched your search

+152 -18
View File
@@ -27,13 +27,14 @@ import threading
import time
from datetime import datetime
from pathlib import Path
from typing import Any
from typing import Any, cast
import psutil
import pytest
os.environ["VLLM_WORKER_MULTIPROC_METHOD"] = "spawn"
os.environ["VLLM_TEST_CLEAN_GPU_MEMORY"] = "0"
os.environ.setdefault("DIFFUSION_ATTENTION_BACKEND", "FLASH_ATTN")
# ---------------------------------------------------------------------------
# Paths
@@ -50,6 +51,7 @@ BENCHMARK_SCRIPT = str(
# Populated lazily after CONFIG_FILE_PATH is resolved.
_SESSION_TIMESTAMP = datetime.now().strftime("%Y%m%d-%H%M%S")
_RESULT_LOCK = threading.Lock()
_BRANCHPOINT_COMMIT_SHA: str | None = None
def _get_config_file_from_argv() -> str | None:
@@ -110,7 +112,7 @@ def load_configs(config_path: str) -> list[dict[str, Any]]:
BENCHMARK_CONFIGS = load_configs(CONFIG_FILE_PATH)
_config_stem = Path(CONFIG_FILE_PATH).stem # e.g. "test_qwen_image_vllm_omni"
AGGREGATED_RESULT_FILE = BENCHMARK_RESULT_DIR / f"benchmark_results_{_config_stem}_{_SESSION_TIMESTAMP}.json"
AGGREGATED_RESULT_FILE = BENCHMARK_RESULT_DIR / f"diffusion_result_{_config_stem}_{_SESSION_TIMESTAMP}.json"
def _append_to_aggregated_file(record: dict[str, Any]) -> None:
@@ -232,13 +234,13 @@ class DiffusionServer:
def __init__(
self,
model: str,
serve_args: list[str],
server_cfg: dict[str, Any],
*,
port: int | None = None,
) -> None:
self.model = model
self.serve_args = serve_args
self.server_cfg: dict[str, Any] = server_cfg
self.model = server_cfg["model"]
self.serve_args = server_cfg["serve_args"]
self.host = "127.0.0.1"
self.port = port if port is not None else _get_open_port()
self.proc: subprocess.Popen | None = None
@@ -299,6 +301,95 @@ def _build_serve_args(serve_args_dict: dict[str, Any]) -> list[str]:
return args
def _get_branchpoint_commit_sha() -> str:
"""Return the branch-point commit SHA against main.
Uses git command: ``git merge-base HEAD origin/main``.
"""
global _BRANCHPOINT_COMMIT_SHA
if _BRANCHPOINT_COMMIT_SHA is not None:
return _BRANCHPOINT_COMMIT_SHA
repo_root = Path(__file__).parent.parent.parent.parent
try:
sha = (
subprocess.check_output(
["git", "merge-base", "HEAD", "origin/main"],
cwd=str(repo_root),
stderr=subprocess.STDOUT,
text=True,
)
.strip()
.splitlines()[0]
)
_BRANCHPOINT_COMMIT_SHA = sha
except Exception as e:
print(f"Warning: failed to get branch-point commit SHA: {e}")
_BRANCHPOINT_COMMIT_SHA = ""
return _BRANCHPOINT_COMMIT_SHA
def _to_resolution_string(params: dict[str, Any]) -> str:
width = params.get("width", "unknown width")
height = params.get("height", "unknown height")
return f"{width}x{height}"
def _to_parallelism_string(framework: str, serve_args_dict: dict[str, Any]) -> str:
parts: list[str] = []
if framework == "vllm-omni":
keys = [
"num-gpus",
"usp",
"ulysses-degree",
"ring",
"ring-degree",
"cfg-parallel-size",
"vae-patch-parallel-size",
"vae-use-tiling",
"tensor-parallel-size",
]
for key in keys:
if key in serve_args_dict:
parts.append(f"{key}={serve_args_dict[key]}")
return ",".join(parts) if parts else "none"
def _to_cache_string(framework: str, serve_args_dict: dict[str, Any]) -> str:
if framework == "vllm-omni":
if "cache-backend" in serve_args_dict:
return str(serve_args_dict["cache-backend"])
return "disabled"
def _to_offload_string(framework: str, serve_args_dict: dict[str, Any]) -> str:
selected: list[str] = []
if framework == "vllm-omni":
offload_keys = [
"enable-cpu-offload",
"enable-layerwise-offload",
]
for key in offload_keys:
if key in serve_args_dict:
selected.append(key)
return f"enabled({';'.join(selected)})" if selected else "disabled"
def _to_compile_value(framework: str, serve_args_dict: dict[str, Any]) -> str:
if framework == "vllm-omni":
if "enforce-eager" in serve_args_dict:
return "disabled"
return "enabled"
return "disabled"
def _to_quantization_value(framework: str, serve_args_dict: dict[str, Any]) -> str:
if framework == "vllm-omni":
quant = serve_args_dict.get("quantization")
return str(quant) if quant else "disabled"
return "disabled"
def _unique_server_params(configs: list[dict[str, Any]]) -> list[dict[str, Any]]:
"""Return one server-config dict per unique test_name."""
seen: set[str] = set()
@@ -310,12 +401,14 @@ def _unique_server_params(configs: list[dict[str, Any]]) -> list[dict[str, Any]]
seen.add(test_name)
if cfg.get("server_type", "vllm-omni") != "vllm-omni":
raise ValueError(f"Unsupported server_type in config: {cfg.get('server_type')}")
serve_args_dict = cfg["server_params"].get("serve_args", {})
result.append(
{
"test_name": test_name,
"server_type": "vllm-omni",
"model": cfg["server_params"]["model"],
"serve_args": _build_serve_args(cfg["server_params"].get("serve_args", {})),
"serve_args_dict": serve_args_dict,
"serve_args": _build_serve_args(serve_args_dict),
"benchmark_backend": "vllm-omni",
"server_params": cfg["server_params"],
}
@@ -334,9 +427,7 @@ def _test_param_mapping(configs: list[dict[str, Any]]) -> dict[str, list[dict]]:
def _make_server(server_cfg: dict[str, Any]) -> DiffusionServer:
"""Factory: return a vLLM-Omni diffusion server instance for the config."""
model = server_cfg["model"]
serve_args = server_cfg["serve_args"]
return DiffusionServer(model=model, serve_args=serve_args)
return DiffusionServer(server_cfg=server_cfg)
# ---------------------------------------------------------------------------
@@ -364,7 +455,6 @@ def diffusion_server(request):
print(f"\nStarting {server_type} server for test: {test_name}")
with _make_server(server_cfg) as server:
server.test_name = test_name
server.server_params = server_cfg["server_params"]
print(f"{server_type} server started successfully")
yield server
print(f"{server_type} server stopping…")
@@ -402,16 +492,18 @@ def run_benchmark(
params: dict[str, Any],
test_name: str,
backend: str = "vllm-omni",
server_params: dict[str, Any] | None = None,
server_cfg: dict[str, Any] | None = None,
source_file: str = "",
) -> dict[str, Any]:
"""Run diffusion_benchmark_serving.py as a subprocess and return parsed metrics.
The raw metrics are written to a temporary file by the subprocess. After
the run completes the metrics are merged with full metadata (test_name,
backend, benchmark_params, timestamp) and appended to the session-wide
aggregated JSON file (AGGREGATED_RESULT_FILE). The temporary file is
removed afterwards. Subprocess stdout/stderr are tee'd to a .log file
under BENCHMARK_RESULT_DIR/logs/; its path is stored in the record.
backend, benchmark_params, timestamp, flat reporting fields) and appended
to the session-wide aggregated JSON file (AGGREGATED_RESULT_FILE). The
temporary file is removed afterwards. Subprocess stdout/stderr are tee'd
to a .log file under BENCHMARK_RESULT_DIR/logs/; its path is stored in
the record.
"""
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
@@ -495,14 +587,55 @@ def run_benchmark(
finally:
tmp_result_file.unlink(missing_ok=True)
server_cfg = server_cfg or {}
serve_args_dict = server_cfg.get("serve_args_dict", {})
if not isinstance(serve_args_dict, dict):
serve_args_dict = {}
completed = metrics.get("completed_requests", metrics.get("completed", 0))
failed = metrics.get("failed_requests", metrics.get("failed", 0))
record: dict[str, Any] = {
"test_name": test_name,
"backend": backend,
"timestamp": timestamp,
"server_params": server_params,
"server_params": server_cfg.get("server_params"),
"benchmark_params": params,
"result": metrics,
"log_file": str(log_file),
"Model": model,
"Framework": backend,
"Hardware": "",
"Deployment": "",
"Task": params.get("task", "t2i"),
"Dataset": params.get("dataset", "random"),
"resolution": _to_resolution_string(params),
"Parallelism": _to_parallelism_string(backend, serve_args_dict),
"max_concurrency": params.get("max-concurrency", ""),
"Cache": _to_cache_string(backend, serve_args_dict),
"Quantization": _to_quantization_value(backend, serve_args_dict),
"offload": _to_offload_string(backend, serve_args_dict),
"compile": _to_compile_value(backend, serve_args_dict),
"Attn_backend": os.environ.get("DIFFUSION_ATTENTION_BACKEND", ""),
"num_inference_steps": params.get("num-inference-steps", ""),
"completed": completed,
"failed": failed,
"throughput_qps": metrics.get("throughput_qps"),
"latency_mean": metrics.get("latency_mean"),
"latency_median": metrics.get("latency_median"),
"latency_p99": metrics.get("latency_p99"),
"latency_p95": metrics.get("latency_p95"),
"latency_p50": metrics.get("latency_p50"),
"peak_memory_mb_max": metrics.get("peak_memory_mb_max"),
"peak_memory_mb_mean": metrics.get("peak_memory_mb_mean"),
"peak_memory_mb_median": metrics.get("peak_memory_mb_median"),
"stage_durations_mean": metrics.get("stage_durations_mean"),
"stage_durations_p50": metrics.get("stage_durations_p50"),
"stage_durations_p99": metrics.get("stage_durations_p99"),
"commit_sha": _get_branchpoint_commit_sha(),
"build_id": os.environ.get("BUILDKITE_BUILD_ID", ""),
"build_url": os.environ.get("BUILDKITE_BUILD_URL", ""),
"source_file": source_file,
}
_append_to_aggregated_file(record)
print(f"\n Result appended to: {AGGREGATED_RESULT_FILE}")
@@ -565,7 +698,8 @@ def test_diffusion_performance_benchmark(diffusion_server, benchmark_params):
params=params,
test_name=test_name,
backend=backend,
server_params=diffusion_server.server_params,
server_cfg=getattr(diffusion_server, "server_cfg", {}),
source_file=cast(str, CONFIG_FILE_PATH),
)
print(f"\n{'=' * 60}")