Skip to content

Commit a0545b7

Browse files
[None][fix] Fix Qwen image CUDA graph with CFG (NVIDIA#16391)
Signed-off-by: Yibin Li <109242046+yibinl-nvidia@users.noreply.github.com> Signed-off-by: Yibin-Li <109242046+yibinl-nvidia@users.noreply.github.com>
1 parent a2595c0 commit a0545b7

3 files changed

Lines changed: 34 additions & 3 deletions

File tree

tensorrt_llm/_torch/visual_gen/models/qwen_image/pipeline_qwen_image.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,8 @@ def forward(
486486
# Denoise loop.
487487
timer.mark_denoise_start()
488488
logger.info("Denoising (%d steps)...", len(timesteps))
489+
pipeline_config = getattr(self, "pipeline_config", None)
490+
cuda_graph_enabled = getattr(getattr(pipeline_config, "cuda_graph", None), "enable", False)
489491
for i, t in enumerate(timesteps):
490492
timestep = t.expand(latents.shape[0]).to(latents.dtype)
491493
noise_pred = self.transformer(
@@ -497,6 +499,11 @@ def forward(
497499
return_dict=False,
498500
)[0]
499501

502+
if do_true_cfg and cuda_graph_enabled:
503+
# CUDA graph outputs are graph-owned buffers; the negative CFG
504+
# replay may reuse the same pool before guidance consumes this one.
505+
noise_pred = noise_pred.clone()
506+
500507
if do_true_cfg:
501508
neg_noise_pred = self.transformer(
502509
hidden_states=latents,

tests/integration/defs/examples/visual_gen/test_visual_gen.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -811,17 +811,18 @@ def wan22_bf16_video_path(_visual_gen_deps, llm_venv):
811811
return output_path
812812

813813

814-
def _generate_qwenimage_lpips_image(model_path, output_path):
815-
"""Generate the QwenImage text-to-image LPIPS sample (default setting, compile-off)."""
814+
def _generate_qwenimage_lpips_image(model_path, output_path, *, enable_cuda_graph=False):
815+
"""Generate the QwenImage text-to-image LPIPS sample."""
816816
from tensorrt_llm._torch.visual_gen.pipeline_loader import PipelineLoader
817817
from tensorrt_llm.media.encoding import save_image
818-
from tensorrt_llm.visual_gen.args import TorchCompileConfig, VisualGenArgs
818+
from tensorrt_llm.visual_gen.args import CudaGraphConfig, TorchCompileConfig, VisualGenArgs
819819

820820
_skip_if_missing(model_path, "QwenImage checkpoint", is_dir=True)
821821
_disable_inductor_compile_worker_quiesce()
822822
args = VisualGenArgs(
823823
model=model_path,
824824
torch_compile_config=TorchCompileConfig(enable=False),
825+
cuda_graph_config=CudaGraphConfig(enable=enable_cuda_graph),
825826
)
826827
pipeline = PipelineLoader(args).load(skip_warmup=True)
827828
try:
@@ -1082,6 +1083,28 @@ def test_qwenimage_lpips_against_golden(tmp_path):
10821083
_assert_lpips_below_threshold(score, QWENIMAGE_LPIPS_THRESHOLD)
10831084

10841085

1086+
@pytest.mark.skipif(not torch.cuda.is_available(), reason="CUDA not available")
1087+
def test_qwenimage_cuda_graph_lpips_against_golden(tmp_path):
1088+
generated_path = tmp_path / "qwenimage_cuda_graph_generated.png"
1089+
golden_path = _golden_media_path(
1090+
tmp_path, "qwenimage_lpips_golden.png", "QwenImage LPIPS golden image"
1091+
)
1092+
_generate_qwenimage_lpips_image(
1093+
_lpips_model_path(QWENIMAGE_MODEL_SUBPATH),
1094+
generated_path,
1095+
enable_cuda_graph=True,
1096+
)
1097+
score = _run_lpips_eval(
1098+
tmp_path,
1099+
"qwenimage_cuda_graph",
1100+
"image",
1101+
QWENIMAGE_LPIPS_PROMPT,
1102+
golden_path,
1103+
generated_path,
1104+
)
1105+
_assert_lpips_below_threshold(score, QWENIMAGE_LPIPS_THRESHOLD)
1106+
1107+
10851108
@pytest.mark.skipif(not torch.cuda.is_available(), reason="CUDA not available")
10861109
def test_cosmos3_nano_t2v_lpips_against_golden(_visual_gen_deps, tmp_path):
10871110
generated_path = tmp_path / "cosmos3_nano_t2v_generated.mp4"

tests/integration/test_lists/test-db/l0_b200.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ l0_b200:
367367
# Measured on B200 with TRT-LLM commit 85665f5f from the staging main image:
368368
# QwenImage ~5 min, Cosmos3-Nano T2I ~3 min, and T2V ~5 min.
369369
- examples/visual_gen/test_visual_gen.py::test_qwenimage_lpips_against_golden TIMEOUT (10)
370+
- examples/visual_gen/test_visual_gen.py::test_qwenimage_cuda_graph_lpips_against_golden TIMEOUT (10)
370371
- examples/visual_gen/test_visual_gen.py::test_cosmos3_nano_t2i_lpips_against_golden TIMEOUT (10)
371372
- examples/visual_gen/test_visual_gen.py::test_cosmos3_nano_t2v_lpips_against_golden TIMEOUT (15)
372373
- visual_gen/test_visual_gen_benchmark.py::test_offline_benchmark

0 commit comments

Comments
 (0)