Skip to content

[TRTLLM-12491][feat] Align VisualGen serve request schema with VisualGenParams#14733

Merged
zhenhuaw-me merged 2 commits into
NVIDIA:mainfrom
zhenhuaw-me:serve-parity
Jun 10, 2026
Merged

[TRTLLM-12491][feat] Align VisualGen serve request schema with VisualGenParams#14733
zhenhuaw-me merged 2 commits into
NVIDIA:mainfrom
zhenhuaw-me:serve-parity

Conversation

@zhenhuaw-me

@zhenhuaw-me zhenhuaw-me commented May 29, 2026

Copy link
Copy Markdown
Member

Description

Aligns the trtllm-serve visual-generation routes (image / sync video / async video / image-edit) with the public VisualGenParams Python API, and tightens the Python API surface around parameter validation, error propagation, output saving, and seed handling.

  • VisualGenParams (under tensorrt_llm/visual_gen/params.py) is now the single source of truth for per-request generation parameters. Universal fields default to None ("use the loaded pipeline's default"); model-specific knobs live in extra_params (LTX-2 exposes image_cond_strength / output_type / guidance_rescale / stg_* / modality_scale / rescale_scale / guidance_skip_step / enhance_prompt; Wan 2.2 A14B exposes guidance_scale_2 / boundary_ratio; Wan I2V exposes last_image).
  • validate_visual_gen_params runs synchronously at VisualGen.generate_async entry — checking VisualGenParams against the loaded pipeline's default_generation_params and extra_param_specs (cached on the executor from the worker's READY signal). Bad-request failures raise ValueError in the caller's process; engine-side failures raise RuntimeError when the result is awaited. Matches the tensorrt_llm.LLM convention and how vllm-omni / SGLang multimodal_gen behave.
  • The OpenAI request schemas (ImageGenerationRequest, VideoGenerationRequest) map 1:1 to VisualGenParams. Unknown top-level fields return HTTP 422 via extra="forbid"; per-request denoise controls (seed / num_inference_steps / guidance_scale / max_sequence_length / negative_prompt); model-specific knobs flow through extra_params and are validated against the loaded pipeline's specs. The /v1/images/edits route stays registered but returns HTTP 501 (no in-tree pipeline implements editing) and no longer parses a typed request body.
  • format is a Literal covering image/video encoders plus tensor formats "safetensors" / "pt". The tensor formats carry every populated modality (image / video / audio) plus scalar metadata in one payload (tensorrt_llm/media/tensor_payload.py) so consumers get a single file per logical output. Routes catch ValueError from validation and pipeline.infer() and render the LLM error envelope at HTTP 400; RuntimeError becomes HTTP 500.
  • Pipeline forward signatures (flux / flux2 / wan / wan_i2v / ltx2 / ltx2_two_stages / cosmos3) take seed: int as the 2nd positional parameter (after prompt, or after image for WanImageToVideoPipeline). Engine fallback materializes a fresh seed via secrets.randbits(63) on the coordinator rank before torch.distributed.broadcast_object_list, so every rank sees the same resolved seed and determinism survives multi-rank runs.
  • VisualGenOutput.save(path) writes one logical output: unbatched and batch == 1 tensors save as-is; batch > 1 paired with a single path raises ValueError (matching diffusers' caller-iterates contract and vllm-omni's codec-layer rule). Callers who want N files pass a list of N paths; callers who want one item out of a batch use output.save_bytes(format=..., batch_index=i). The legacy implicit-slice-to-first behavior in save_image / save_video / tensor save is removed.
  • The async video tensor-format path writes batched outputs as {video_id}_{i}.{fmt}; get_video_content's recovery probe accepts both the bare and batch-indexed filename shapes.

One open thread on the PR is deferred to a follow-up (TRTLLM-13143): the media-transport contract for response_format (raw bytes vs. b64) when paired with tensor formats.

Test Coverage

  • ~290 focused VisualGen unit tests in tests/unittest/_torch/visual_gen/ cover the public API (params validation, output transport, save dispatch, default merging), the route-level rendering (image / sync video / async video / image-edit / get-content / delete), schema 1:1 mapping with VisualGenParams, and tensor payload roundtrip (safetensors and pt, batched and unbatched, with metadata overrides).
  • Verified on GB200 with a clean Release build (sm_100 aarch64).

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

Summary by CodeRabbit

  • New Features

    • Added tensor output format support (safetensors, pt) for image and video generation.
    • Added new format parameter for specifying output encoding across generation requests.
    • Added image content retrieval endpoint for serving generated images.
  • Bug Fixes

    • Improved request validation with structured error messages for better debugging.
  • Documentation

    • Updated Visual Generation API documentation with detailed request schemas and parameter specifications.

<!-- review_stack_entry_start -->

[!Review Change Stack](https://app.coderabbit.ai/change-stack/NVIDIA/TensorRT-LLM/pull/14733?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@zhenhuaw-me
zhenhuaw-me requested review from a team as code owners May 29, 2026 06:01
@zhenhuaw-me
zhenhuaw-me marked this pull request as draft May 29, 2026 06:03
@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR adds comprehensive tensor payload serialization support to TensorRT-LLM's visual generation service, enabling .safetensors and PyTorch format outputs. It introduces structured validation error transport with reason/param/details fields, implements coordinator-side seed resolution when unset, refactors request parameter parsing with extra_params merging and OpenAI-shape field warnings, and extends OpenAI-compatible server routes to serve tensor-formatted images and videos via URLs or base64 encoding.

Changes

Visual Generation Request Validation, Tensor Support, and Parameter Handling

Layer / File(s) Summary
Structured validation errors with transport metadata
tensorrt_llm/_torch/visual_gen/executor.py, tensorrt_llm/visual_gen/visual_gen.py, tests/unittest/_torch/visual_gen/test_visual_gen_params.py
VisualGenValidationError carries reason, param, details fields. DiffusionResponse gains error_reason, error_param, error_details. New validate_visual_gen_params() validates unknown extra_params, unsupported universal fields, and type/range mismatches, aggregating and reporting deterministically.
Coordinator-side seed materialization when unset
tensorrt_llm/_torch/visual_gen/executor.py, tensorrt_llm/visual_gen/params.py, tensorrt_llm/visual_gen/visual_gen.py, tests/unittest/_torch/visual_gen/test_visual_gen_params.py
_resolve_seed() materializes random 63-bit seed before broadcast when params.seed is None. VisualGenParams.seed changes from int=42 to Optional[int]=None with fresh-seed-at-dispatch semantics. Seeds drawn on coordinator rank before all-ranks broadcast.
Tensor payload serialization for safetensors and PyTorch formats
tensorrt_llm/media/tensor_payload.py, tests/unittest/_torch/visual_gen/test_tensor_payload.py
New module provides serialize_visual_gen_output(), save_visual_gen_output_payload(), infer_batch_size(), and metadata collection. Handles .safetensors (with stringified metadata) and .pt (torch.save) formats, batch slicing, frame-rate/sample-rate overrides, and per-item fanout.
OpenAI protocol schema updates for tensor formats and structured parameters
tensorrt_llm/serve/openai_protocol.py
ImageGenerationRequest: adds format (tensor+encoder), width/height with pairing validation, extra_params, OpenAI-shape ignored fields. VideoGenerationRequest: adds format, width/height, frame budget (num_frames/seconds/frame_rate), extra_params. VideoJob changes fps to float, adds response_format.
Refactored request parameter parsing with extra_params merging and OpenAI-shape warnings
tensorrt_llm/serve/visual_gen_utils.py, tests/unittest/_torch/visual_gen/test_visual_gen_utils.py
parse_visual_gen_params centralizes overlay logic. New _warn_if_set_with_no_semantic emits warnings for unsupported OpenAI fields. _merge_extra_params merges request extras with known-key null handling and unknown-key pass-through. Video frame budget prefers num_frames, else derives from seconds*frame_rate. New _parse_image_edit_request for edit workflows.
VisualGenOutput tensor format saving and error metadata
tensorrt_llm/visual_gen/output.py, tensorrt_llm/_torch/visual_gen/output.py, tests/unittest/_torch/visual_gen/test_tensor_payload.py
Extends VisualGenOutput with error_reason, error_param, error_details fields. New save_bytes() serializes tensors to memory with batch selection. Suffix-to-format inference routes .safetensors/.pt to tensor path. Error metadata propagated from executor through output layer.
Image generation endpoint with tensor format support and content serving
tensorrt_llm/serve/openai_server.py, tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py
openai_image_generation detects is_tensor_format() and saves tensor outputs or encodes to PIL formats. Per-batch ImageObject entries populated with base64 bytes (b64_json) or fetchable URLs. New GET /v1/images/{image_id}/content endpoint. Visual-Gen validation errors return HTTP 422 LLM-envelope with extra_forbidden guidance.
Video generation endpoint with tensor format support and encoder format normalization
tensorrt_llm/serve/openai_video_routes.py, tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py
Synchronous and async video handlers branch on is_tensor_format(): tensor outputs saved/returned as bytes or URLs; non-tensor outputs encoded with resolved encoder format. Multipart parsing refactored to support uploaded input_reference and JSON extra_params. Async pre-flight validation added. Content download probes expanded suffix list with correct media types.
Pipeline models updated to require keyword-only seed
tensorrt_llm/_torch/visual_gen/models/flux/pipeline_flux.py, tensorrt_llm/_torch/visual_gen/models/flux/pipeline_flux2.py, tensorrt_llm/_torch/visual_gen/models/ltx2/pipeline_ltx2.py, tensorrt_llm/_torch/visual_gen/models/ltx2/pipeline_ltx2_two_stages.py, tensorrt_llm/_torch/visual_gen/models/wan/pipeline_wan.py, tensorrt_llm/_torch/visual_gen/models/wan/pipeline_wan_i2v.py, tensorrt_llm/_torch/visual_gen/models/wan/defaults.py, tests/unittest/_torch/visual_gen/test_visual_gen_params.py
All pipeline forward methods now require seed as keyword-only argument (no default). Wan.get_default_params no longer conditionally exposes image_cond_strength. Caller must provide deterministic seed or rely on coordinator-side resolution.
Example scripts and documentation updated for tensor formats and new parameter names
examples/visual_gen/serve/sync_image_gen.py, examples/visual_gen/serve/sync_video_gen.py, examples/visual_gen/serve/async_video_gen.py, examples/visual_gen/serve/README.md, docs/source/models/visual-generation.md
CLI scripts add --format argument with tensor+encoder choices. File extension logic branches on tensor vs content-type. Documentation expands to cover field mappings, sizing constraints, unknown-field rejection (422), tensor transport, and model-specific options via extra_params. Includes extra_param_specs inspection example.
Integration tests and comprehensive test coverage for new functionality
tests/unittest/_torch/visual_gen/test_tensor_payload.py, tests/unittest/_torch/visual_gen/test_visual_gen_params.py, tests/unittest/_torch/visual_gen/test_visual_gen_utils.py, tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py, tests/unittest/_torch/visual_gen/test_trtllm_serve_e2e.py, tests/unittest/_torch/visual_gen/test_utils.py, tests/unittest/_torch/visual_gen/test_visual_gen_args.py
New tensor payload tests verify serialization, batch semantics, and metadata handling. New validation error tests check structured fields and transport. New parameter parsing tests cover default overlay, warnings, frame budget derivation. Endpoint tests expanded with validation error envelopes, tensor route coverage, multipart flows, and async pre-flight. E2E tests updated with format_ renaming.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • NVIDIA/TensorRT-LLM#12922: Introduces foundational per-model DEFAULT_GENERATION_PARAMS and EXTRA_PARAM_SPECS merging that this PR builds upon in validate_visual_gen_params and _merge_extra_params.
  • NVIDIA/TensorRT-LLM#13985: Implements fused RMSNorm+RoPE kernels and pre-sharded positional embeddings that support the LTX-2 model updates coordinated in this PR's seed/parameter handling flow.
  • NVIDIA/TensorRT-LLM#13313: Establishes the embedded req.params: VisualGenParams execution flow that this PR extends with seed resolution and structured validation-error transport.

Suggested labels

VisualGen, feature, API, tests

Suggested reviewers

  • chang-l
  • QiJune
  • syuoni
  • dpitman-nvda
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 47.48% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title is clear and directly related to the main objective of the changeset, which aligns VisualGen serve request schema with VisualGenParams.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description comprehensively explains objectives, changes, and test coverage for the visual generation alignment.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tensorrt_llm/serve/visual_gen_utils.py (1)

163-165: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reject malformed base64 at the request boundary.

Both decode paths call base64.b64decode() with its default behavior, so malformed payloads can slip through as garbage bytes and fail much later in the pipeline. Decode with validate=True and translate binascii.Error into a ValueError here instead.

🛡️ Proposed fix
+import binascii
 import base64
 import os
 import shutil
@@
+def _decode_base64_payload(value: str, field_name: str) -> bytes:
+    try:
+        return base64.b64decode(value, validate=True)
+    except binascii.Error as exc:
+        raise ValueError(
+            f"{field_name} must be valid base64-encoded data"
+        ) from exc
+
+
 def parse_visual_gen_params(
@@
             ref_path = os.path.join(media_storage_path, f"{request_id}_reference.png")
             if isinstance(request.input_reference, str):
                 with open(ref_path, "wb") as f:
-                    f.write(base64.b64decode(request.input_reference))
+                    f.write(
+                        _decode_base64_payload(
+                            request.input_reference, "input_reference"
+                        )
+                    )
@@
     if request.image is not None:
         if isinstance(request.image, list):
-            params.image = [base64.b64decode(image) for image in request.image]
+            params.image = [
+                _decode_base64_payload(image, "image")
+                for image in request.image
+            ]
         else:
-            params.image = [base64.b64decode(request.image)]
+            params.image = [_decode_base64_payload(request.image, "image")]

Run this to confirm the current call sites are relying on the stdlib default and are not passing validate=True:

#!/bin/bash
set -euo pipefail
python - <<'PY'
import base64
import inspect
print(inspect.signature(base64.b64decode))
PY
rg -n 'b64decode\(' tensorrt_llm/serve/visual_gen_utils.py

Also applies to: 200-203

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/serve/visual_gen_utils.py` around lines 163 - 165, The base64
decoding of request.input_reference in visual_gen_utils.py should reject
malformed input: change the call to base64.b64decode(request.input_reference,
validate=True) and wrap it in a try/except that catches binascii.Error and
raises a ValueError (with a clear message) before writing to ref_path; apply the
same change to the other decode site handling request.input_reference (around
the decode at lines ~200-203) so both decode paths validate input and surface a
ValueError at the request boundary.
🧹 Nitpick comments (3)
tests/unittest/_torch/visual_gen/test_visual_gen_params.py (1)

1189-1274: ⚡ Quick win

Coverage is still insufficient for the public validation path.

These additions stop at DiffusionResponse. The two new API contracts in tensorrt_llm/visual_gen/visual_gen.pyVisualGen.validate_request_params() and single-prompt VisualGenResult re-raising VisualGenValidationError—still need direct coverage. Please add cases in tests/unittest/_torch/visual_gen/test_visual_gen_params.py or a neighboring tests/unittest/_torch/visual_gen/test_visual_gen.py. As per coding guidelines tests/**: Act as a QA engineer reviewing test changes and coverage for TensorRT-LLM.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/_torch/visual_gen/test_visual_gen_params.py` around lines 1189
- 1274, Add unit tests that directly exercise the public validation API: call
VisualGen.validate_request_params(...) with params that trigger a validation
failure and assert it raises VisualGenValidationError containing structured
fields (error_reason, error_param, error_details including pipeline name). Also
add a test that runs the single-prompt code path which constructs/returns a
VisualGenResult that should re-raise VisualGenValidationError for invalid params
and verify the exception propagates and carries the same structured fields;
reference the VisualGen.validate_request_params, VisualGenResult, and
VisualGenValidationError symbols when locating where to add these cases.
tensorrt_llm/serve/openai_server.py (1)

2060-2066: ⚡ Quick win

Narrow the terminal catch in this endpoint.

Catching every Exception here will turn unrelated bugs in the new tensor/image serialization path into generic 500 payloads, which makes regressions much harder to spot. Catch the expected storage/encoding failures explicitly and let the rest propagate through FastAPI's normal error handling.
As per coding guidelines, "Avoid broad exception handling — catch specific exceptions, not bare except:" and "When using try-except blocks, limit the except clause to the smallest set of errors possible."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/serve/openai_server.py` around lines 2060 - 2066, The current
broad except Exception in the endpoint should be narrowed to only the expected
storage/encoding-related errors so unrelated bugs bubble up; replace "except
Exception as e:" with an explicit tuple of expected exceptions (e.g.
UnicodeEncodeError, ValueError, TypeError, OSError and any project-specific
errors like ImageSerializationError or StorageError if those exist) and keep the
logger.error(...) + return self.create_error_response(...) inside that narrowed
except, but for all other exceptions simply re-raise (use "raise") so FastAPI
handles them normally.
tests/unittest/_torch/visual_gen/test_visual_gen_utils.py (1)

229-255: ⚡ Quick win

Add malformed-base64 coverage for the new decode paths.

tests/unittest/_torch/visual_gen/test_visual_gen_utils.py covers happy-path materialization and missing media_storage_path, but it still misses the case that would catch malformed input_reference / ImageEditRequest.image payloads early. Please add direct ValueError assertions for those two request shapes once the request-boundary validation is tightened.

As per coding guidelines "Act as a QA engineer reviewing test changes and coverage for TensorRT-LLM. Keep feedback actionable: suggest concrete list file names and whether coverage is sufficient, insufficient, or needs follow-up outside the PR."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/_torch/visual_gen/test_visual_gen_utils.py` around lines 229 -
255, Add tests that assert malformed base64 payloads raise ValueError: create
two new test cases in the TestInputReferenceMaterialization class that call
parse_visual_gen_params with (a) a VideoGenerationRequest whose input_reference
is an invalid base64 string and (b) an ImageEditRequest (or equivalent request
shape) whose image field is invalid base64; pass a valid media_storage_path
(tmp_path) and assert pytest.raises(ValueError, match="input_reference" or
"image" respectively) to ensure parse_visual_gen_params rejects malformed
payloads early. Use the existing _StubVisualGen generator and the same
invocation pattern as the other tests so the new tests mirror
test_base64_reference_written_to_disk and
test_missing_media_storage_path_raises.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/visual_gen/serve/async_video_gen.py`:
- Around line 36-37: Rename the parameter and local variable named format in
test_async_video_generation to format_ to avoid builtin shadowing (Ruff A002);
update the function signature to use format_, replace local references ("if
format in ...", "actual_ext = f'.{format}'", and the dict entry "format":
format) to use format_, and update any callers (e.g., pass format_=args.format)
while keeping the outgoing JSON/request payload key as "format" (so the dict
remains "format": format_).

In `@examples/visual_gen/serve/sync_image_gen.py`:
- Around line 31-33: Rename the function parameter `format` in
`test_image_generation` to avoid shadowing the builtin (e.g., `format_`) and
update all references accordingly: change the `format` parameter declaration,
replace uses like `extra_body={"format": format}` with `extra_body={"format":
format_}`, replace `ext_map[format]` with `ext_map[format_]`, and update the
caller site that passes this argument (e.g., replace `format=args.format` with
`format_=args.format`) so all forwards and lookups use `format_`.

In `@examples/visual_gen/serve/sync_video_gen.py`:
- Around line 35-36: The function parameter named format should be renamed to
format_ to avoid shadowing the built-in format() (change the parameter in the
function signature and all references inside the function), update all places
that construct request payloads to keep the JSON key "format" but use the new
variable (e.g., "format": format_), and update the call site(s) including
test_sync_video_generation to pass format_ (or the same literal) accordingly;
search for references to format in this function and replace them with format_
(including the payloads at the lines noted) and ensure imports/other symbols are
unchanged.

In `@tensorrt_llm/_torch/visual_gen/executor.py`:
- Around line 199-203: The error message appended to messages incorrectly says
the parameter "will be silently ignored" even though the branch raises
VisualGenValidationError; update the message in the messages.append call to
state that the field (field_name) is rejected for the given pipeline
(pipeline_name) because it is not in default_generation_params and will cause a
VisualGenValidationError, so callers are not misled about silent ignoring.
Ensure the new text references field_name, pipeline_name and
default_generation_params to make intent clear.

In `@tensorrt_llm/media/tensor_payload.py`:
- Around line 233-235: The code accesses TENSOR_FORMAT_EXTENSIONS[fmt] before
validating fmt, which raises KeyError when path has no suffix; update the logic
in the function containing this snippet (the block using variables target, fmt
and TENSOR_FORMAT_EXTENSIONS, and called by serialize_visual_gen_output) to
first validate fmt is a supported key (e.g., if fmt not in
TENSOR_FORMAT_EXTENSIONS) and raise the same ValueError used by
serialize_visual_gen_output for invalid formats, then only call
TENSOR_FORMAT_EXTENSIONS[fmt] to normalize the suffix and proceed to
target.parent.mkdir(...).

In `@tensorrt_llm/serve/openai_server.py`:
- Around line 613-641: The current _create_visual_gen_validation_error_response
in openai_server.py flattens VisualGenValidationError to a simple message and
loses structured metadata like reason/param/details; replace the generic
create_error_response call with a dedicated renderer (e.g.,
render_visual_gen_validation_error or VisualGenValidationErrorRenderer) that
detects instances of VisualGenValidationError, serializes and preserves its
fields (message, reason, param, details) into the JSON envelope, and returns the
correct HTTP status (use the intended 400/422 per spec). Update
_create_visual_gen_validation_error_response to call that renderer instead of
create_error_response, and apply the same renderer invocation in the video
routes handlers that currently rely on the generic path so the structured
validation transport is preserved end-to-end.

In `@tensorrt_llm/serve/openai_video_routes.py`:
- Around line 500-510: The fallback video lookup in the GET handler sets
video_path using job.output_path or by probing _KNOWN_VIDEO_OUTPUT_SUFFIXES for
"{video_id}{ext}", but it fails to probe the batch-indexed name
"{video_id}_0{ext}" used for non-tensor async jobs; as a result video_path
remains None and requests can 404 even when the first output exists. Update the
probe loop in the method that sets video_path (the block referencing video_path,
job.output_path and _KNOWN_VIDEO_OUTPUT_SUFFIXES) to also check for a candidate
with f"{video_id}_0{ext}" (same approach as delete_video()), picking that path
if it exists so the GET /v1/videos/{id}/content handler can recover stale or
missing job.output_path entries.

In `@tensorrt_llm/serve/visual_gen_utils.py`:
- Around line 92-97: The parameter named `id` in the function
`parse_visual_gen_params` shadows a Python builtin and should be renamed (e.g.,
to `request_id`) to satisfy Ruff A002; update the function signature from `id:
str` to `request_id: str`, replace every reference to `id` inside
`parse_visual_gen_params` (including where `VisualGenParams` is constructed) to
use `request_id`, and make the same rename for the other occurrence(s)
referenced around lines 162-163 so all local uses and internal variable
references match the new `request_id` name.

In `@tensorrt_llm/visual_gen/output.py`:
- Around line 289-319: The linter flags the parameter name format (Ruff A002) in
VisualGenOutput.save and VisualGenOutput.save_bytes but renaming it would be an
API break; update both method signatures to suppress the specific lint rule by
appending a targeted "# noqa: A002" to the format parameter declaration (i.e.,
the parameter named format in the def save(...) and def save_bytes(...)
signatures) so the name is preserved while silencing the Ruff warning.

In `@tensorrt_llm/visual_gen/visual_gen.py`:
- Around line 812-817: The code uses type(self).__name__ when calling
validate_visual_gen_params which always yields "VisualGen" and causes mismatched
pipeline identity; change the pipeline_name argument to use the resolved
identity on the instance (e.g. self.executor.pipeline_name) and fall back to an
instance field if needed: supply pipeline_name=getattr(self.executor,
"pipeline_name", getattr(self, "pipeline_name", type(self).__name__)); update
the validate_visual_gen_params call to use that expression so coordinator- and
worker-side validation share the same pipeline name.

In `@tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py`:
- Around line 1838-1840: The test uses a hardcoded fallback "/tmp/_vg" when
reading video_client.app.state.__dict__.get("media_storage_path", "/tmp/_vg"),
which triggers Ruff S108; update the test to use the tmp_path fixture instead
and set the environment/config value TRTLLM_MEDIA_STORAGE_PATH from tmp_path (or
assign tmp_path.as_posix()) before creating/initializing video_client so
video_client.app.state.__dict__.get("media_storage_path", ...) resolves to the
fixture-backed temp directory rather than the hardcoded "/tmp/_vg".

In `@tests/unittest/_torch/visual_gen/test_visual_gen_params.py`:
- Around line 763-764: The pytest.raises calls in test_visual_gen_params.py use
non-raw string regex patterns (e.g. match="image_cond_strength.*not use it")
which triggers RUF043; update those match= arguments to raw string literals
(prefix with r) for the pytest.raises invocations that call
self._validate(executor, req) so the regex metacharacters are treated literally
(e.g. change match="..." to match=r"...") for both occurrences around the
_validate test cases.

---

Outside diff comments:
In `@tensorrt_llm/serve/visual_gen_utils.py`:
- Around line 163-165: The base64 decoding of request.input_reference in
visual_gen_utils.py should reject malformed input: change the call to
base64.b64decode(request.input_reference, validate=True) and wrap it in a
try/except that catches binascii.Error and raises a ValueError (with a clear
message) before writing to ref_path; apply the same change to the other decode
site handling request.input_reference (around the decode at lines ~200-203) so
both decode paths validate input and surface a ValueError at the request
boundary.

---

Nitpick comments:
In `@tensorrt_llm/serve/openai_server.py`:
- Around line 2060-2066: The current broad except Exception in the endpoint
should be narrowed to only the expected storage/encoding-related errors so
unrelated bugs bubble up; replace "except Exception as e:" with an explicit
tuple of expected exceptions (e.g. UnicodeEncodeError, ValueError, TypeError,
OSError and any project-specific errors like ImageSerializationError or
StorageError if those exist) and keep the logger.error(...) + return
self.create_error_response(...) inside that narrowed except, but for all other
exceptions simply re-raise (use "raise") so FastAPI handles them normally.

In `@tests/unittest/_torch/visual_gen/test_visual_gen_params.py`:
- Around line 1189-1274: Add unit tests that directly exercise the public
validation API: call VisualGen.validate_request_params(...) with params that
trigger a validation failure and assert it raises VisualGenValidationError
containing structured fields (error_reason, error_param, error_details including
pipeline name). Also add a test that runs the single-prompt code path which
constructs/returns a VisualGenResult that should re-raise
VisualGenValidationError for invalid params and verify the exception propagates
and carries the same structured fields; reference the
VisualGen.validate_request_params, VisualGenResult, and VisualGenValidationError
symbols when locating where to add these cases.

In `@tests/unittest/_torch/visual_gen/test_visual_gen_utils.py`:
- Around line 229-255: Add tests that assert malformed base64 payloads raise
ValueError: create two new test cases in the TestInputReferenceMaterialization
class that call parse_visual_gen_params with (a) a VideoGenerationRequest whose
input_reference is an invalid base64 string and (b) an ImageEditRequest (or
equivalent request shape) whose image field is invalid base64; pass a valid
media_storage_path (tmp_path) and assert pytest.raises(ValueError,
match="input_reference" or "image" respectively) to ensure
parse_visual_gen_params rejects malformed payloads early. Use the existing
_StubVisualGen generator and the same invocation pattern as the other tests so
the new tests mirror test_base64_reference_written_to_disk and
test_missing_media_storage_path_raises.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d6af8a09-d290-45ed-9379-01a686b461c6

📥 Commits

Reviewing files that changed from the base of the PR and between 7bdd835 and 3d60ad0.

📒 Files selected for processing (29)
  • docs/source/models/visual-generation.md
  • examples/visual_gen/serve/README.md
  • examples/visual_gen/serve/async_video_gen.py
  • examples/visual_gen/serve/sync_image_gen.py
  • examples/visual_gen/serve/sync_video_gen.py
  • tensorrt_llm/_torch/visual_gen/executor.py
  • tensorrt_llm/_torch/visual_gen/models/flux/pipeline_flux.py
  • tensorrt_llm/_torch/visual_gen/models/flux/pipeline_flux2.py
  • tensorrt_llm/_torch/visual_gen/models/ltx2/pipeline_ltx2.py
  • tensorrt_llm/_torch/visual_gen/models/ltx2/pipeline_ltx2_two_stages.py
  • tensorrt_llm/_torch/visual_gen/models/wan/defaults.py
  • tensorrt_llm/_torch/visual_gen/models/wan/pipeline_wan.py
  • tensorrt_llm/_torch/visual_gen/models/wan/pipeline_wan_i2v.py
  • tensorrt_llm/_torch/visual_gen/output.py
  • tensorrt_llm/media/tensor_payload.py
  • tensorrt_llm/serve/openai_protocol.py
  • tensorrt_llm/serve/openai_server.py
  • tensorrt_llm/serve/openai_video_routes.py
  • tensorrt_llm/serve/visual_gen_utils.py
  • tensorrt_llm/visual_gen/output.py
  • tensorrt_llm/visual_gen/params.py
  • tensorrt_llm/visual_gen/visual_gen.py
  • tests/unittest/_torch/visual_gen/test_tensor_payload.py
  • tests/unittest/_torch/visual_gen/test_trtllm_serve_e2e.py
  • tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py
  • tests/unittest/_torch/visual_gen/test_utils.py
  • tests/unittest/_torch/visual_gen/test_visual_gen_args.py
  • tests/unittest/_torch/visual_gen/test_visual_gen_params.py
  • tests/unittest/_torch/visual_gen/test_visual_gen_utils.py

zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request May 29, 2026
…sor-format dispatch, drop 'renamed from' wording

Address self-review notes from PR NVIDIA#14733: keep the diff focused, drop
over-engineered single-use dicts, and remove historical-narration
wording from a public README.

Doc and wording cleanup:
- Revert all edits to docs/source/models/visual-generation.md
  (separate doc refactor planned, out of scope here).
- Drop the "(renamed from `output_format`)" phrasing on the serve
  example README; the diff and git log are the migration history.

Tensor-format dispatch simplification:
- Remove `TENSOR_FORMAT_EXTENSIONS` and `TENSOR_FORMAT_MEDIA_TYPES`
  module-level dicts in `tensorrt_llm/media/tensor_payload.py`.
  Both are 2-entry single-use lookups; `f".{fmt}"` and a literal
  `"application/octet-stream"` are clearer at the four call sites
  in openai_server.py and openai_video_routes.py.
- Inline `_TENSOR_SUFFIX_TO_FORMAT` in
  `tensorrt_llm/visual_gen/output.py::_infer_format_from_path` as
  a one-line `_suffix_format` helper that recognizes the two known
  tensor suffixes directly.
- Trim the "where the format is handled" sentence from
  `VisualGenOutput.save`'s `path:` docstring — the internal routing
  between `tensorrt_llm.media.encoding` and
  `tensorrt_llm.media.tensor_payload` is an implementation detail
  callers don't need.

Verified on GB200: full visual_gen unit subsystem 359 passed / 0
failed in 60.33s.

Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request May 29, 2026
… use stock ValueError

Per self-review feedback on PR NVIDIA#14733: no custom exception layer on top
of Python's standard error types. Validation failures now raise plain
``ValueError`` with the same multi-line message; the structured
``reason`` / ``param`` / ``details`` fields are removed.

Core changes
- Remove ``VisualGenValidationError`` class and the ``Literal`` /
  ``field`` imports it required.
- Replace ``DiffusionResponse.error_reason`` / ``error_param`` /
  ``error_details`` with a single ``is_validation_error: bool``
  discriminator. Same on ``VisualGenOutput``. The coordinator-side
  awaiter uses it to re-raise as ``ValueError`` (-> HTTP 400) vs
  ``RuntimeError`` (-> HTTP 500); routes catch the standard types
  directly and no longer import the custom class.
- ``validate_visual_gen_params`` raises ``ValueError`` with the
  multi-line per-violation message. The per-category accumulator
  lists feeding into ``details`` are gone; the flat ``messages``
  list builds the same human-readable content. Fix the
  "silently ignored" wording on the universal-field branch since
  that branch does raise.
- READY signal now propagates ``pipeline_name`` so coordinator-side
  pre-validation uses the actual loaded pipeline's class name
  (was always "VisualGen"). Closes the worker/coordinator parity
  gap that CodeRabbit #10 flagged.

Cascade (all driven by the drop)
- Remove ``VisualGen.validate_request_params`` method. Async video
  route calls module-level ``validate_visual_gen_params`` directly
  with the propagated executor metadata.
- ``VisualGenResult._resolved_value`` dispatches on
  ``out.is_validation_error`` (ValueError vs RuntimeError).
- Sync image, sync video, and async video routes drop their
  ``except VisualGenValidationError`` arm; the existing
  ``except ValueError`` arm handles validation failures the same
  way (HTTP 400 + message).

Tests
- ``TestVisualGenValidationErrorStructured`` ->
  ``TestValidateVisualGenParamsMessages``: assert ``ValueError`` with
  expected substrings instead of structured fields.
- ``TestValidationErrorTransport`` switches to asserting
  ``is_validation_error``.
- ``TestRouteVisualGenValidationError`` -> ``TestRouteEngineValidationError``:
  sync routes inject a stock ``ValueError`` on the mock; async route
  triggers a real validator rejection by sending an unknown
  extra_params key against the mock's executor metadata.
- ``MockVisualGen`` gains an ``executor`` ``SimpleNamespace`` with
  ``pipeline_name`` / ``default_generation_params`` /
  ``extra_param_specs`` so the async pre-flight call works
  end-to-end.

Verified on GB200: full visual_gen unit subsystem 357 passed / 0
failed in 60.67s.

Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request May 29, 2026
…sor-format dispatch, drop 'renamed from' wording

Address self-review notes from PR NVIDIA#14733: keep the diff focused, drop
over-engineered single-use dicts, and remove historical-narration
wording from a public README.

Doc and wording cleanup:
- Revert all edits to docs/source/models/visual-generation.md
  (separate doc refactor planned, out of scope here).
- Drop the "(renamed from `output_format`)" phrasing on the serve
  example README; the diff and git log are the migration history.

Tensor-format dispatch simplification:
- Remove `TENSOR_FORMAT_EXTENSIONS` and `TENSOR_FORMAT_MEDIA_TYPES`
  module-level dicts in `tensorrt_llm/media/tensor_payload.py`.
  Both are 2-entry single-use lookups; `f".{fmt}"` and a literal
  `"application/octet-stream"` are clearer at the four call sites
  in openai_server.py and openai_video_routes.py.
- Inline `_TENSOR_SUFFIX_TO_FORMAT` in
  `tensorrt_llm/visual_gen/output.py::_infer_format_from_path` as
  a one-line `_suffix_format` helper that recognizes the two known
  tensor suffixes directly.
- Trim the "where the format is handled" sentence from
  `VisualGenOutput.save`'s `path:` docstring — the internal routing
  between `tensorrt_llm.media.encoding` and
  `tensorrt_llm.media.tensor_payload` is an implementation detail
  callers don't need.

Verified on GB200: full visual_gen unit subsystem 359 passed / 0
failed in 60.33s.

Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request May 29, 2026
… use stock ValueError

Per self-review feedback on PR NVIDIA#14733: no custom exception layer on top
of Python's standard error types. Validation failures now raise plain
``ValueError`` with the same multi-line message; the structured
``reason`` / ``param`` / ``details`` fields are removed.

Core changes
- Remove ``VisualGenValidationError`` class and the ``Literal`` /
  ``field`` imports it required.
- Replace ``DiffusionResponse.error_reason`` / ``error_param`` /
  ``error_details`` with a single ``is_validation_error: bool``
  discriminator. Same on ``VisualGenOutput``. The coordinator-side
  awaiter uses it to re-raise as ``ValueError`` (-> HTTP 400) vs
  ``RuntimeError`` (-> HTTP 500); routes catch the standard types
  directly and no longer import the custom class.
- ``validate_visual_gen_params`` raises ``ValueError`` with the
  multi-line per-violation message. The per-category accumulator
  lists feeding into ``details`` are gone; the flat ``messages``
  list builds the same human-readable content. Fix the
  "silently ignored" wording on the universal-field branch since
  that branch does raise.
- READY signal now propagates ``pipeline_name`` so coordinator-side
  pre-validation uses the actual loaded pipeline's class name
  (was always "VisualGen"). Closes the worker/coordinator parity
  gap that CodeRabbit #10 flagged.

Cascade (all driven by the drop)
- Remove ``VisualGen.validate_request_params`` method. Async video
  route calls module-level ``validate_visual_gen_params`` directly
  with the propagated executor metadata.
- ``VisualGenResult._resolved_value`` dispatches on
  ``out.is_validation_error`` (ValueError vs RuntimeError).
- Sync image, sync video, and async video routes drop their
  ``except VisualGenValidationError`` arm; the existing
  ``except ValueError`` arm handles validation failures the same
  way (HTTP 400 + message).

Tests
- ``TestVisualGenValidationErrorStructured`` ->
  ``TestValidateVisualGenParamsMessages``: assert ``ValueError`` with
  expected substrings instead of structured fields.
- ``TestValidationErrorTransport`` switches to asserting
  ``is_validation_error``.
- ``TestRouteVisualGenValidationError`` -> ``TestRouteEngineValidationError``:
  sync routes inject a stock ``ValueError`` on the mock; async route
  triggers a real validator rejection by sending an unknown
  extra_params key against the mock's executor metadata.
- ``MockVisualGen`` gains an ``executor`` ``SimpleNamespace`` with
  ``pipeline_name`` / ``default_generation_params`` /
  ``extra_param_specs`` so the async pre-flight call works
  end-to-end.

Verified on GB200: full visual_gen unit subsystem 357 passed / 0
failed in 60.67s.

Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request May 29, 2026
…d_strength to extra_params, clamp seed

Third round of self-review feedback on PR NVIDIA#14733. Three code-fix
threads + one CodeRabbit follow-up; conflict-resolution merge done
in this round too.

Pipeline forward() signature reorder
- Moved `seed: int` to the second positional argument (right after
  `prompt`, or after `image` for `WanImageToVideoPipeline`) across
  flux / flux2 / wan / wan_i2v / ltx2 / ltx2_two_stages, and dropped
  the bare `*,` keyword-only marker. Callers (`infer()` and
  `_run_warmup`) already used kwargs only, so this is a mechanical
  internal-API change.
- Aligned `Cosmos3OmniMoTPipeline.forward` with the same convention —
  it still carried `seed: int = 42` as a stale default.

image_cond_strength moved to per-pipeline extra_params
- Cross-framework check confirmed that diffusers, vllm-omni, and
  SGLang Diffusion all treat conditioning-strength knobs as
  pipeline-specific (diffusers exposes them only on
  `LTXConditionPipeline` / SD img2img / SVD; vllm-omni and SGLang
  route them through generic `diffusers_kwargs` bags). None treats
  `image_cond_strength` as a first-class request field.
- Dropped `image_cond_strength` from `VisualGenParams`, from
  `VideoGenerationRequest`, from the `visual_gen_utils` translation,
  from `_GENERATION_CONFIG_FIELDS`, and from the Wan-defaults
  carve-out (which let `get_wan_default_params` lose the
  `include_i2v` argument entirely).
- Added the field to `LTX2Pipeline.extra_param_specs` (`default=1.0`);
  both `LTX2Pipeline.infer()` and `LTX2TwoStagesPipeline.infer()` now
  read it from `req.params.extra_params["image_cond_strength"]`. Wan
  pipelines reject the key via the existing unknown-`extra_params`
  path.
- Updated the LTX-2 example script so `--image_cond_strength` flows
  into `extra_params` instead of the dropped top-level field, and
  trimmed the serve README's per-request control list.

Seed clamp + N-image RNG semantics doc
- Introduced `MAX_UINT32_SEED = 2**32 - 1` and applied
  `ge=0, le=MAX_UINT32_SEED` on `VisualGenParams.seed` and on the
  three openai_protocol video / image / edit request schemas.
- Coordinator-rank random seed materialization moved from
  `secrets.randbits(63)` to `secrets.randbits(32)` so engine-drawn
  seeds stay inside the OpenAI DALL-E range that vllm-omni adopts.
- Documented the chosen `num_images_per_prompt > 1` semantics in the
  `VisualGenParams.seed` description: diffusers/vllm-omni style
  (single `torch.Generator(seed=s)` driving N latents from one RNG
  stream), not SGLang's `[s, s+1, …]` per-image expansion.
- Three new unit tests pin the range bounds.

Conflict resolution
- Rebased the three serve-parity commits onto origin/main, resolving
  conflicts in `openai_video_routes.py` against the
  `build_visual_gen_timing_headers` introduction from NVIDIA#14176. Kept
  the upstream cleanup that uses local `generation` / `denoise`
  variables.

Tests
- `test_visual_gen_params.py`: three obsolete top-level
  image_cond_strength tests replaced with two extra_params variants;
  three new tests for seed bounds.

Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request Jun 1, 2026
…nly; tighten params invariant

Fourth round of self-review feedback on PR NVIDIA#14733. Three threads
addressed in this commit; the parallel discussion on the
``is_validation_error`` discriminator (threads on
``DiffusionResponse.is_validation_error`` and
``VisualGenOutput.is_validation_error``) is kept open pending a
separate decision on the attribute's name vs existence.

Seed clamp moved off the Python API
- ``VisualGenParams.seed`` no longer carries ``ge=0, le=MAX_UINT32_SEED``.
  The Python API accepts the full int64 range that
  ``torch.Generator.manual_seed`` supports.
- The UINT32 clamp now lives only on the three OpenAI request schemas
  in ``openai_protocol.py`` (``ImageGenerationRequest``,
  ``VideoGenerationRequest``, ``ImageEditRequest``) — the HTTP boundary
  is where OpenAI DALL-E compatibility matters, matching vllm-omni's
  ``api_server.py``.
- ``MAX_UINT32_SEED`` moved into ``openai_protocol.py`` where it is
  consumed; ``visual_gen.params`` no longer exports it.
- Engine fallback reverted from ``secrets.randbits(32)`` to
  ``secrets.randbits(63)`` — the engine's own seeds don't owe the
  serve-side range.
- Three seed-bounds unit tests moved off ``VisualGenParams`` onto
  ``ImageGenerationRequest`` / ``VideoGenerationRequest`` to match
  where the constraint now lives. The ``VisualGenParams`` side keeps
  one test that exercises the wider int64 acceptance.

``req.params`` invariant tightened
- ``VisualGen.generate_async`` now materializes a fresh
  ``VisualGenParams`` when the caller passes ``params=None``, so
  ``DiffusionRequest.params`` is always a concrete object by the time
  the executor sees it.
- Dropped the ``if req.params is None: ...`` guards from
  ``DiffusionExecutor._resolve_seed`` and ``._merge_defaults``;
  ``None`` at those stages is now a bug, not an expected fallback.
- Updated three tests that previously exercised the defensive
  ``params=None`` path to use ``params=VisualGenParams()`` (matching
  the new contract) and added a positive test that the enqueue site
  materializes the default.

Comment trim on ``DiffusionResponse.is_validation_error``
- Dropped the "→ HTTP 400" / "→ HTTP 500" wording from the docstring
  on ``executor.py``; the comment now describes only the
  Python-level ``ValueError`` vs ``RuntimeError`` dispatch on the
  coordinator-side awaiter. The HTTP mapping is a serve concern and
  does not belong on the internal IPC dataclass.

Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request Jun 1, 2026
…sor-format dispatch, drop 'renamed from' wording

Address self-review notes from PR NVIDIA#14733: keep the diff focused, drop
over-engineered single-use dicts, and remove historical-narration
wording from a public README.

Doc and wording cleanup:
- Revert all edits to docs/source/models/visual-generation.md
  (separate doc refactor planned, out of scope here).
- Drop the "(renamed from `output_format`)" phrasing on the serve
  example README; the diff and git log are the migration history.

Tensor-format dispatch simplification:
- Remove `TENSOR_FORMAT_EXTENSIONS` and `TENSOR_FORMAT_MEDIA_TYPES`
  module-level dicts in `tensorrt_llm/media/tensor_payload.py`.
  Both are 2-entry single-use lookups; `f".{fmt}"` and a literal
  `"application/octet-stream"` are clearer at the four call sites
  in openai_server.py and openai_video_routes.py.
- Inline `_TENSOR_SUFFIX_TO_FORMAT` in
  `tensorrt_llm/visual_gen/output.py::_infer_format_from_path` as
  a one-line `_suffix_format` helper that recognizes the two known
  tensor suffixes directly.
- Trim the "where the format is handled" sentence from
  `VisualGenOutput.save`'s `path:` docstring — the internal routing
  between `tensorrt_llm.media.encoding` and
  `tensorrt_llm.media.tensor_payload` is an implementation detail
  callers don't need.

Verified on GB200: full visual_gen unit subsystem 359 passed / 0
failed in 60.33s.

Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request Jun 1, 2026
… use stock ValueError

Per self-review feedback on PR NVIDIA#14733: no custom exception layer on top
of Python's standard error types. Validation failures now raise plain
``ValueError`` with the same multi-line message; the structured
``reason`` / ``param`` / ``details`` fields are removed.

Core changes
- Remove ``VisualGenValidationError`` class and the ``Literal`` /
  ``field`` imports it required.
- Replace ``DiffusionResponse.error_reason`` / ``error_param`` /
  ``error_details`` with a single ``is_validation_error: bool``
  discriminator. Same on ``VisualGenOutput``. The coordinator-side
  awaiter uses it to re-raise as ``ValueError`` (-> HTTP 400) vs
  ``RuntimeError`` (-> HTTP 500); routes catch the standard types
  directly and no longer import the custom class.
- ``validate_visual_gen_params`` raises ``ValueError`` with the
  multi-line per-violation message. The per-category accumulator
  lists feeding into ``details`` are gone; the flat ``messages``
  list builds the same human-readable content. Fix the
  "silently ignored" wording on the universal-field branch since
  that branch does raise.
- READY signal now propagates ``pipeline_name`` so coordinator-side
  pre-validation uses the actual loaded pipeline's class name
  (was always "VisualGen"). Closes the worker/coordinator parity
  gap that CodeRabbit #10 flagged.

Cascade (all driven by the drop)
- Remove ``VisualGen.validate_request_params`` method. Async video
  route calls module-level ``validate_visual_gen_params`` directly
  with the propagated executor metadata.
- ``VisualGenResult._resolved_value`` dispatches on
  ``out.is_validation_error`` (ValueError vs RuntimeError).
- Sync image, sync video, and async video routes drop their
  ``except VisualGenValidationError`` arm; the existing
  ``except ValueError`` arm handles validation failures the same
  way (HTTP 400 + message).

Tests
- ``TestVisualGenValidationErrorStructured`` ->
  ``TestValidateVisualGenParamsMessages``: assert ``ValueError`` with
  expected substrings instead of structured fields.
- ``TestValidationErrorTransport`` switches to asserting
  ``is_validation_error``.
- ``TestRouteVisualGenValidationError`` -> ``TestRouteEngineValidationError``:
  sync routes inject a stock ``ValueError`` on the mock; async route
  triggers a real validator rejection by sending an unknown
  extra_params key against the mock's executor metadata.
- ``MockVisualGen`` gains an ``executor`` ``SimpleNamespace`` with
  ``pipeline_name`` / ``default_generation_params`` /
  ``extra_param_specs`` so the async pre-flight call works
  end-to-end.

Verified on GB200: full visual_gen unit subsystem 357 passed / 0
failed in 60.67s.

Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request Jun 1, 2026
…d_strength to extra_params, clamp seed

Third round of self-review feedback on PR NVIDIA#14733. Three code-fix
threads + one CodeRabbit follow-up; conflict-resolution merge done
in this round too.

Pipeline forward() signature reorder
- Moved `seed: int` to the second positional argument (right after
  `prompt`, or after `image` for `WanImageToVideoPipeline`) across
  flux / flux2 / wan / wan_i2v / ltx2 / ltx2_two_stages, and dropped
  the bare `*,` keyword-only marker. Callers (`infer()` and
  `_run_warmup`) already used kwargs only, so this is a mechanical
  internal-API change.
- Aligned `Cosmos3OmniMoTPipeline.forward` with the same convention —
  it still carried `seed: int = 42` as a stale default.

image_cond_strength moved to per-pipeline extra_params
- Cross-framework check confirmed that diffusers, vllm-omni, and
  SGLang Diffusion all treat conditioning-strength knobs as
  pipeline-specific (diffusers exposes them only on
  `LTXConditionPipeline` / SD img2img / SVD; vllm-omni and SGLang
  route them through generic `diffusers_kwargs` bags). None treats
  `image_cond_strength` as a first-class request field.
- Dropped `image_cond_strength` from `VisualGenParams`, from
  `VideoGenerationRequest`, from the `visual_gen_utils` translation,
  from `_GENERATION_CONFIG_FIELDS`, and from the Wan-defaults
  carve-out (which let `get_wan_default_params` lose the
  `include_i2v` argument entirely).
- Added the field to `LTX2Pipeline.extra_param_specs` (`default=1.0`);
  both `LTX2Pipeline.infer()` and `LTX2TwoStagesPipeline.infer()` now
  read it from `req.params.extra_params["image_cond_strength"]`. Wan
  pipelines reject the key via the existing unknown-`extra_params`
  path.
- Updated the LTX-2 example script so `--image_cond_strength` flows
  into `extra_params` instead of the dropped top-level field, and
  trimmed the serve README's per-request control list.

Seed clamp + N-image RNG semantics doc
- Introduced `MAX_UINT32_SEED = 2**32 - 1` and applied
  `ge=0, le=MAX_UINT32_SEED` on `VisualGenParams.seed` and on the
  three openai_protocol video / image / edit request schemas.
- Coordinator-rank random seed materialization moved from
  `secrets.randbits(63)` to `secrets.randbits(32)` so engine-drawn
  seeds stay inside the OpenAI DALL-E range that vllm-omni adopts.
- Documented the chosen `num_images_per_prompt > 1` semantics in the
  `VisualGenParams.seed` description: diffusers/vllm-omni style
  (single `torch.Generator(seed=s)` driving N latents from one RNG
  stream), not SGLang's `[s, s+1, …]` per-image expansion.
- Three new unit tests pin the range bounds.

Conflict resolution
- Rebased the three serve-parity commits onto origin/main, resolving
  conflicts in `openai_video_routes.py` against the
  `build_visual_gen_timing_headers` introduction from NVIDIA#14176. Kept
  the upstream cleanup that uses local `generation` / `denoise`
  variables.

Tests
- `test_visual_gen_params.py`: three obsolete top-level
  image_cond_strength tests replaced with two extra_params variants;
  three new tests for seed bounds.

Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request Jun 1, 2026
…nly; tighten params invariant

Fourth round of self-review feedback on PR NVIDIA#14733. Three threads
addressed in this commit; the parallel discussion on the
``is_validation_error`` discriminator (threads on
``DiffusionResponse.is_validation_error`` and
``VisualGenOutput.is_validation_error``) is kept open pending a
separate decision on the attribute's name vs existence.

Seed clamp moved off the Python API
- ``VisualGenParams.seed`` no longer carries ``ge=0, le=MAX_UINT32_SEED``.
  The Python API accepts the full int64 range that
  ``torch.Generator.manual_seed`` supports.
- The UINT32 clamp now lives only on the three OpenAI request schemas
  in ``openai_protocol.py`` (``ImageGenerationRequest``,
  ``VideoGenerationRequest``, ``ImageEditRequest``) — the HTTP boundary
  is where OpenAI DALL-E compatibility matters, matching vllm-omni's
  ``api_server.py``.
- ``MAX_UINT32_SEED`` moved into ``openai_protocol.py`` where it is
  consumed; ``visual_gen.params`` no longer exports it.
- Engine fallback reverted from ``secrets.randbits(32)`` to
  ``secrets.randbits(63)`` — the engine's own seeds don't owe the
  serve-side range.
- Three seed-bounds unit tests moved off ``VisualGenParams`` onto
  ``ImageGenerationRequest`` / ``VideoGenerationRequest`` to match
  where the constraint now lives. The ``VisualGenParams`` side keeps
  one test that exercises the wider int64 acceptance.

``req.params`` invariant tightened
- ``VisualGen.generate_async`` now materializes a fresh
  ``VisualGenParams`` when the caller passes ``params=None``, so
  ``DiffusionRequest.params`` is always a concrete object by the time
  the executor sees it.
- Dropped the ``if req.params is None: ...`` guards from
  ``DiffusionExecutor._resolve_seed`` and ``._merge_defaults``;
  ``None`` at those stages is now a bug, not an expected fallback.
- Updated three tests that previously exercised the defensive
  ``params=None`` path to use ``params=VisualGenParams()`` (matching
  the new contract) and added a positive test that the enqueue site
  materializes the default.

Comment trim on ``DiffusionResponse.is_validation_error``
- Dropped the "→ HTTP 400" / "→ HTTP 500" wording from the docstring
  on ``executor.py``; the comment now describes only the
  Python-level ``ValueError`` vs ``RuntimeError`` dispatch on the
  coordinator-side awaiter. The HTTP mapping is a serve concern and
  does not belong on the internal IPC dataclass.

Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request Jun 1, 2026
…nator; drop is_validation_error

Fifth round of self-review feedback on PR NVIDIA#14733. Addresses the two
parallel threads that were held open from round 4 (on
``DiffusionResponse.is_validation_error`` and
``VisualGenOutput.is_validation_error``) by removing the discriminator
entirely and moving validation to the caller's process.

Validation now lives on the coordinator side
- ``VisualGen.generate_async`` calls ``validate_visual_gen_params``
  against the executor's READY-signal-cached
  ``{pipeline_name, default_generation_params, extra_param_specs}``
  before the request crosses the IPC boundary. Raising in the caller's
  process means ``ValueError`` reaches the user as a natural Python
  exception; no cross-process discriminator needed.
- The worker no longer validates request params. ``DiffusionExecutor``
  loses ``_validate_request`` and its invocation in ``_merge_defaults``.
  The async video route still pre-flights validation synchronously so
  malformed requests become HTTP 400 before the job is queued (not
  after the background task fails).

is_validation_error attribute removed
- Dropped from ``DiffusionResponse`` (worker → coordinator IPC type).
- Dropped from ``VisualGenOutput`` (public per-request output).
- Dropped propagation in ``to_visual_gen_output`` /
  ``split_visual_gen_output``.
- ``VisualGenResult._resolved_value`` uniformly re-raises engine
  failures as ``RuntimeError``; any ``ValueError`` the user catches
  comes synchronously from ``generate_async`` validation, matching the
  ``tensorrt_llm.LLM`` convention and how vllm-omni / SGLang's
  multimodal_gen schemas behave (validation at API entry, runtime
  failures encoded on the response).

validate_visual_gen_params moved to its natural home
- Relocated the function and its helpers (``_TYPE_MAP``,
  ``_GENERATION_CONFIG_FIELDS``) from
  ``tensorrt_llm/_torch/visual_gen/executor.py`` (the internal worker
  layer) into ``tensorrt_llm/visual_gen/params.py`` (alongside
  ``VisualGenParams``). The validator no longer has any worker-side
  caller, so its previous location in ``_torch`` was misleading.
- Updated imports in ``VisualGen.generate_async`` and in the async
  video route. The function continues to duck-type
  ``ExtraParamSchema`` via ``spec.type`` / ``spec.range`` so no import
  from the internal layer is needed.

Tests
- Removed ``TestValidationErrorTransport`` (the cross-process
  discriminator no longer exists). Replaced with
  ``TestEngineFailureTransport``, which exercises the engine-failure
  → ``RuntimeError``-flavored ``error_msg`` path.
- ``TestRequestValidation`` / ``TestValidateVisualGenParamsMessages``
  now call ``validate_visual_gen_params`` directly instead of routing
  through the removed ``DiffusionExecutor._validate_request``.
- Dropped the obsolete worker-side process_request validation-error
  test. The route-level synchronous validation tests are unchanged —
  ``MockVisualGen.generate_async`` already raises the same
  ``ValueError`` the real validator produces.

Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
Comment thread tensorrt_llm/serve/openai_protocol.py
zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request Jun 2, 2026
…on default params; dedup format constants

Sixth round of self-review feedback on PR NVIDIA#14733. Five Cat-1 fixes;
the two Cat-3 design questions (batched-tensor save layout, raw-bytes
transport for tensor formats) are answered on the threads with no
code change pending further discussion.

Skip validation when the caller passes no params
- ``VisualGen.generate_async`` now branches on whether ``params`` is
  supplied: with user params it validates + snapshots; with ``None`` it
  builds a fresh ``VisualGenParams`` from ``self.default_params``
  (which already materializes the pipeline's declared defaults +
  extra-param defaults from the executor's READY-signal cache) and
  skips validation, since there's nothing user-supplied to flag.
- Previous behavior built an empty ``VisualGenParams()`` and let the
  worker fill defaults; now the coordinator owns the full default
  materialization on the no-params path, matching the symmetry the
  ``default_params`` property already provides.

Tensor-format constants deduplicated
- ``visual_gen/output.py:_infer_format_from_path`` now derives its
  recognized suffixes from
  ``tensorrt_llm.media.tensor_payload.TENSOR_FORMATS`` instead of an
  inline ``(".safetensors", ".pt")`` tuple. ``TENSOR_FORMATS`` is the
  single source of truth.

OpenAI server format helpers dropped
- Removed ``_IMAGE_FORMAT_TO_PIL`` — Pillow's format name is just the
  upper-case form of our request token, so
  ``pil_format = request.format.upper()`` replaces the dict.
- Removed ``_IMAGE_FORMAT_TO_EXT`` — the on-disk extension matches the
  request token directly. ``.jpeg`` is interchangeable with ``.jpg``
  for Pillow, the OS, and the OpenAI API. ``ext = f".{request.format}"``
  replaces the dict.
- The ``Literal["png", "webp", "jpeg", "safetensors", "pt"]`` on
  ``ImageGenerationRequest.format`` remains the supported-format gate.

Model-mismatch warning rewording
- Dropped the "trtllm-serve is single-model per process and the field
  is informational only" phrasing from the request-vs-loaded-model
  warning. The new message — "the model field is logged but ignored" —
  conveys the observable behavior without the architectural detail.

Verified: 251 / 251 focused VisualGen unit tests pass on GB200.
Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
zhenhuaw-me added a commit to zhenhuaw-me/TensorRT-LLM that referenced this pull request Jun 2, 2026
…ng; raise on batched-save-with-single-path

Seventh round of self-review feedback on PR NVIDIA#14733. Two changes
folded into one commit: drop the ``pipeline_name`` plumbing, and
tighten the implicit-slice behavior of ``save_image`` / ``save_video``
/ tensor save when a batched tensor is paired with a single path.

Drop pipeline_name plumbing
- Removed ``pipeline_name`` parameter from
  ``validate_visual_gen_params(...)``.
- Removed ``pipeline_name`` field from the worker's READY signal
  payload (``DiffusionExecutor._load_pipeline``).
- Removed ``self.pipeline_name`` attribute on ``DiffusionRemoteClient``
  and its READY-handler population in ``_wait_ready``.
- Removed ``pipeline_name=...`` keyword from the two validator call
  sites (``VisualGen.generate_async`` and the async video route).
- Error message:
  ``"Parameter validation failed for {pipeline_name}:\n  - ..."`` →
  ``"Parameter validation failed:\n  - ..."``.
  The per-bullet suffixes drop the pipeline name too, in favor of
  ``"the loaded pipeline"`` where useful.
- Trade-off: validation messages lose the per-pipeline namespace.
  In practice the label was the pipeline class name (LTX2Pipeline,
  WanImageToVideoPipeline, …), which leaked an implementation detail
  without helping the user; trtllm-serve also loads one pipeline per
  process, so the label was a per-process constant.

Single path + batched tensor now raises ValueError
- ``save_image`` and ``save_video`` in ``tensorrt_llm/media/encoding.py``
  used to silently slice ``image[0]`` / ``video[0]`` when handed a
  batched tensor with a single path, dropping the remaining items.
  They now raise ``ValueError`` when ``batch_size > 1`` and accept
  the ``batch_size == 1`` case (unambiguous unwrap).
- ``VisualGenOutput._save_tensor_payload`` mirrors the rule on the
  tensor-format save path.
- Matches the convention in vllm-omni's codec layer
  (``_encode_video_bytes`` raises on batched 5-D tensors) and
  diffusers' ``BaseOutput`` (no ``.save()``; callers iterate
  explicitly).
- Callers that want one file out of a batch can do
  ``output.save_bytes(format=..., batch_index=i)`` and write the
  slice themselves, or pass a list of N paths to write N files.

OpenAI video routes follow the new contract
- Sync and async video tensor-format paths in
  ``openai_video_routes.py`` now build ``[{video_id}_{i}.{fmt}` for i
  in range(batch_size)]`` and call ``output.save(tensor_paths, ...)``,
  matching the encoder-format path. The first saved file is returned
  as the route's primary download (OpenAI sync video API does not
  define a multi-file response yet — TRTLLM-11579); the async route
  records all paths on ``output_paths``.
- ``get_video_content``'s recovery probe now tries both the bare
  ``{vid}{ext}`` and the batch-indexed ``{vid}_0{ext}`` filename
  shapes, matching the convention ``delete_video`` already uses
  (closes the CodeRabbit follow-up deferred in round 3).

Tests
- ``test_tensor_payload.TestSingleSavePath``:
  ``test_batched_image_writes_first_item_only`` →
  ``test_batched_image_single_path_raises``;
  ``test_batched_video_writes_first_item_and_audio`` →
  ``test_batched_video_single_path_raises``. The unbatched and
  ``batch == 1`` save paths still pass through unchanged.
- ``test_visual_gen_params``: dropped ``pipeline_name=...`` kwarg
  from the test helpers; updated two message-content assertions to
  match the label-free error string.
- ``MockVisualGen.executor`` SimpleNamespace no longer carries the
  ``pipeline_name`` attribute; the route preflight only reads
  ``default_generation_params`` / ``extra_param_specs``.
- ``_make_validation_error`` helper builds the new label-free shape.

Verified: 292 / 292 focused VisualGen unit tests pass on GB200.
Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
@NVIDIA NVIDIA deleted a comment from coderabbitai Bot Jun 2, 2026
@NVIDIA NVIDIA deleted a comment from coderabbitai Bot Jun 2, 2026
@NVIDIA NVIDIA deleted a comment from coderabbitai Bot Jun 2, 2026
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52695 [ run ] completed with state ABORTED. Commit: 5df0879

Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52741 [ run ] completed with state SUCCESS. Commit: e01b3eb
/LLM/main/L0_MergeRequest_PR pipeline #42003 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@zhenhuaw-me

Copy link
Copy Markdown
Member Author

/bot run

@zhenhuaw-me

Copy link
Copy Markdown
Member Author

/bot kill

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52899 [ run ] triggered by Bot. Commit: e01b3eb Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52900 [ kill ] triggered by Bot. Commit: e01b3eb Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52899 [ run ] completed with state ABORTED. Commit: e01b3eb

Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #52900 [ kill ] completed with state SUCCESS. Commit: e01b3eb
Successfully killed previous jobs for commit e01b3eb

Link to invocation

…GenParams

Aligns the trtllm-serve visual-generation routes (image / sync video /
async video / image-edit) with the public VisualGenParams Python API,
and tightens the Python API surface around parameter validation, error
propagation, output saving, and seed handling.

VisualGenParams (under tensorrt_llm/visual_gen/params.py) is the single
source of truth for per-request generation parameters. Universal fields
default to None ("use the loaded pipeline's default"); model-specific
knobs live in extra_params; validate_visual_gen_params runs synchronously
at VisualGen.generate_async entry against the loaded pipeline's
default_generation_params and extra_param_specs.

The OpenAI request schemas (ImageGenerationRequest, VideoGenerationRequest)
map 1:1 to VisualGenParams. Unknown top-level fields return HTTP 422 via
extra="forbid"; per-request denoise controls (seed / num_inference_steps /
guidance_scale / max_sequence_length / negative_prompt); model-specific
knobs flow through extra_params. The /v1/images/edits route stays
registered but returns HTTP 501 (no in-tree pipeline implements editing)
and no longer parses a typed body.

format is a Literal covering image/video encoders plus tensor formats
"safetensors" / "pt". The tensor formats carry every populated modality
(image / video / audio) plus scalar metadata in one payload. For
safetensors, scalar metadata is stored both as 0-d tensors (survives
safetensors.torch.load) and in the file header (survives safe_open
metadata access).

Pipeline forward signatures (flux / flux2 / wan / wan_i2v / ltx2 /
ltx2_two_stages / cosmos3) take seed: int as the 2nd positional parameter.
Engine fallback materializes a fresh seed via secrets.randbits(63) on the
coordinator rank before torch.distributed.broadcast_object_list, so every
rank sees the same resolved seed and determinism survives multi-rank runs.

VisualGenOutput.save(path) writes one logical output: unbatched and
batch == 1 tensors save as-is; batch > 1 paired with a single path raises
ValueError (matching diffusers' caller-iterates contract). Callers who
want N files pass a list of N paths.

Round 2 of chang-l review feedback folded in:
- DiffusionRemoteClient moved from tensorrt_llm/visual_gen/visual_gen.py
  to tensorrt_llm/_torch/visual_gen/executor.py, alongside its IPC
  counterpart DiffusionExecutor. Class was already not in __all__ and
  not re-exported from tensorrt_llm.visual_gen; the move makes the
  internal status structural rather than merely conventional.
- VisualGenOutput.save_bytes renamed to _save_bytes — the public output
  API now exposes only save(); in-memory bytes serialization is reserved
  for the b64_json transport in openai_server.
- safetensors metadata hybrid: scalars written both as 0-d tensors and
  in the file header, so safetensors.torch.load(bytes) returns them
  alongside the media tensors instead of dropping them.
- ImageEditRequest schema dropped (route still returns 501). The schema
  carried legacy fields (guidance_rescale, validate_size field-validator,
  required n) inconsistent with the 1:1 VisualGenParams alignment; a
  fresh schema lands when an edit-capable pipeline lands.
- ValueError → HTTP 400 mapping in the image + video sync routes is now
  scoped to the parse + generate region only. Server-side ValueErrors
  from infer_batch_size / output._save_bytes / output.save fall through
  to the outer catch-all and surface as HTTP 500 InternalServerError.
- visual_gen_utils.parse_visual_gen_params raises ValueError when
  request.seconds is set but params.frame_rate cannot be resolved, so the
  duration is no longer silently dropped.

Tests
- tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py:
  added test_image_route_serialization_value_error_returns_500,
  test_image_edit_no_body_returns_not_implemented,
  test_seconds_without_frame_rate_returns_400.
- tests/unittest/_torch/visual_gen/test_tensor_payload.py:
  safetensors-branch metadata asserts now exercise the 0-d tensor path
  in addition to the file header.
- tests/unittest/_torch/visual_gen/multi_gpu/test_visual_gen_multinode.py:
  patch targets repointed at the new module home for DiffusionRemoteClient.
- tests/unittest/media/test_encoding.py: replaced the obsolete
  test_save_image_strips_batch_dim with rejects-B>1 + accepts-B==1
  variants matching save_image's tightened contract.

Signed-off-by: Zhenhua Wang <zhenhuaw@nvidia.com>
@zhenhuaw-me

Copy link
Copy Markdown
Member Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53025 [ run ] triggered by Bot. Commit: cb943a8 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53025 [ run ] completed with state SUCCESS. Commit: cb943a8
/LLM/main/L0_MergeRequest_PR pipeline #42248 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@zhenhuaw-me

Copy link
Copy Markdown
Member Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53051 [ run ] triggered by Bot. Commit: cb943a8 Link to invocation

@zhenhuaw-me
zhenhuaw-me enabled auto-merge (squash) June 9, 2026 14:19
Signed-off-by: Zhenhua Wang <4936589+zhenhuaw-me@users.noreply.github.com>
@zhenhuaw-me

Copy link
Copy Markdown
Member Author

/bot kill

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53205 [ kill ] triggered by Bot. Commit: 3ad427e Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53051 [ run ] completed with state ABORTED. Commit: cb943a8

Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53205 [ kill ] completed with state SUCCESS. Commit: 3ad427e
Successfully killed previous jobs for commit 3ad427e

Link to invocation

@zhenhuaw-me

Copy link
Copy Markdown
Member Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53233 [ run ] triggered by Bot. Commit: 3ad427e Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53233 [ run ] completed with state SUCCESS. Commit: 3ad427e
/LLM/main/L0_MergeRequest_PR pipeline #42428 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@zhenhuaw-me

Copy link
Copy Markdown
Member Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53319 [ run ] triggered by Bot. Commit: 3ad427e Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #53319 [ run ] completed with state SUCCESS. Commit: 3ad427e
/LLM/main/L0_MergeRequest_PR pipeline #42505 completed with status: 'SUCCESS'

CI Report

Link to invocation

@zhenhuaw-me
zhenhuaw-me merged commit 6db3233 into NVIDIA:main Jun 10, 2026
7 checks passed
@zhenhuaw-me
zhenhuaw-me deleted the serve-parity branch June 10, 2026 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants