Skip to content

[Perf][Diffusion][Qwen-Image] Replace per-bucket varlen loop with flat varlen attention for mixfusion - #6711

Open
renyongxing wants to merge 55 commits into
vllm-project:mainfrom
renyongxing:feat/mixfusion-varlen
Open

renyongxing wants to merge 55 commits into
vllm-project:mainfrom
renyongxing:feat/mixfusion-varlen

Conversation

@renyongxing

@renyongxing renyongxing commented Aug 28, 2026 •

Copy link
Copy Markdown

Purpose

Continue the work of #3638 (Efficient Mixed-Resolution Batching Strategy for HunyuanImage-3.0 and Qwen-Image). While fully preserving the original author's changes (standalone commit 43ffa56a9, authored by desenSunUBW), replace Qwen-Image mixfusion's per-bucket equal-length varlen loop with a single flat varlen attention pass to eliminate inter-bucket bubbles and reduce end-to-end latency for mixed-resolution batches.

Scope

Following review feedback that this PR was over the size budget, the non-Qwen-Image work has been split out:

What remains here is the Qwen-Image flat-varlen change plus the shared scheduling/batching infrastructure it requires — 667 non-test added lines across 11 files. No Hunyuan-specific code and no benchmark tooling is left in this PR. The one shared piece both family PRs build on, _apply_mixfusion_shape_relaxation in vllm_omni/diffusion/sched/base_scheduler.py, intentionally stays here rather than being duplicated.

Key changes:

  • vllm_omni/diffusion/attention/backends/abstract.py + flash_attn.py: AttentionMetadata gains varlen fields (is_varlen, q_cu_seqlens, kv_cu_seqlens, max_q_len, max_kv_len, padded_tokens); add _forward_varlen_flat (expects [total_tokens, H, D], calls flash_attn_varlen_func with the same interface as Enable Efficient Mixed-Resolution Batching Strategy for HunyuanImage-3.0 and Qwen-Image #3638).
  • vllm_omni/diffusion/models/qwen_image/qwen_image_transformer.py: forward_mixfusion switches from the per-bucket loop to a single flat varlen pass (cu_seqlens built from real text lengths via mask.sum, text packed with 17-way padding, output unpacked by cu_seqlens).
  • Fixes surfaced by the single-request API migration (see commits 4cde003a0, 28d3c272c): mixfusion benchmarks build one request per prompt + asyncio.gather; state_cache pop key uses request_id; OmniDiffusionRequest.prompts compatibility accessor for scheduler/pipeline req.prompts iteration.

Reference / Acknowledgement

The flat-varlen FlashAttention method used in this PR (varlen AttentionMetadata fields q_cu_seqlens / kv_cu_seqlens / max_q_len / max_kv_len /padded_tokens; flat packed [total_tokens, heads, head_dim] Q/K/V tensors; and the flash_attn_varlen_func-based branch that rejects attention masks and requires padded_tokens=0) is adapted from the approach proposed in PR #4024 — [Diffusion] Enable Qwen-Image dynamic step batching by @asukaqaq-s .

How the application differs:

Note: PR #4024 is not yet merged into main. If it lands first, the overlapping AttentionMetadata varlen fields and the flat varlen branch in flash_attn.py should be reconciled to avoid duplication.

Test Plan

Automated tests

  • Unit (packing/varlen layout): tests/diffusion/models/qwen_image/test_qwen_image_mixfusion_packing.py
    runs under pytest -sv tests/diffusion tests/model_executor -m 'core_model and cpu' (the Simple · Diffusion & Model Executor Test selector).
  • e2e: tests/e2e/online_serving/test_qwen_image.py -m core_model --run-level core_model
    (the Diffusion · Qwen Image Test selector) guards the Qwen-Image path this PR touches.
  • Coverage gap (explicit): no CI e2e case currently passes enable_mixfusion=true; mixfusion itself
    is exercised by the packing unit tests above plus the manual benchmark runs below. The benchmark
    harness (mixfusion_benefit.py) now lives in [Benchmark][Diffusion] MixFusion benchmarks #8117.
  1. Correctness (bitwise): run old (per-bucket) and new (flat varlen) implementations on the same 4 concurrent requests and assert latents are bitwise identical ((a == b).all() == True).
  2. Benchmark matrix (A100, steps=8, iters=3, tp=1/2/4). The harness lives in [Benchmark][Diffusion] MixFusion benchmarks #8117; the command is unchanged apart from --family qwen:
    DIFFUSION_ATTENTION_BACKEND=FLASH_ATTN \
    python benchmarks/diffusion/mixfusion_benefit.py \
      --family qwen \
      --model /data/weight/Qwen-Image \
      --image-sizes 1024x1024,1024x768,768x1024,512x512 \   # caseB (mixed resolution)
      --steps 8 --iters 3 --warmup 1 --max-num-seqs 4 \
      --tensor-parallel-size 1 --no-skip-rejected-mixfusion-cases
  3. Smoke test (caseB, tp1): same benchmark with steps=8, iters=1.

vLLM Version: 0.28.0

**vLLM-Omni Commit:**0.28.0

Test Result

Scenario batched time(Compared to the bucket version) speedup bubble
caseA (same resolution, tp1/2/4) −2.3% ~ −7.3% +0.05 ~ +0.12 —
caseB (mixed resolution, tp1/2/4) −4.6% ~ −5.6% +0.06 ~ +0.15 halved
  • Correctness: 4 requests' latents bitwise identical between old and new implementations.
  • Smoke test (caseB: 1024x1024/1024x768/768x1024/512x512, tp1, steps=8, iters=1, vllm 0.28.0 + vllm-omni 0.28.0 aligned env):
    • mixfusion plan accepted: chunk_size=1024, chunk_count=11
    • serial 10.62s / batched 9.30s → speedup 1.14
    • 4 images emitted in both serial and batched modes, backend FLASH_ATTN
  • Original PR: Enable Efficient Mixed-Resolution Batching Strategy for HunyuanImage-3.0 and Qwen-Image #3638 (not yet merged upstream, kept as a standalone commit with authorship preserved)

The numbers above were produced with the pre-split per-family benchmark script; only the entry point moved, the measured code path is the one in this PR.

How to enable MixFusion

enable_mixfusion is opt-in per request, passed through the diffusion extra_args field:

{"extra_args": {"enable_mixfusion": true}}

It is accepted both at the top level of the request body and nested under
extra_body.extra_args. Two optional tuning knobs live in the same dict:

key default meaning
mixfusion_min_chunk_tokens 256 reject the flat-varlen layout when gcd(token counts) < this
mixfusion_max_chunks 128 reject when the resulting chunk count exceeds this

Online serving:

vllm serve Qwen/Qwen-Image --omni --port 8099

curl -s http://localhost:8099/v1/images/generations \
  -H 'Content-Type: application/json' \
  -d '{"model": "Qwen/Qwen-Image",
       "prompt": "a cat",
       "size": "1024x1024",
       "extra_args": {"enable_mixfusion": true}}'

Default is False, so nothing changes unless you ask for it

The key does not exist on main — it is introduced by this PR, and every read site defaults it to False.A deployment that never passes enable_mixfusion therefore behaves as before.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@renyongxing

Copy link
Copy Markdown
Author

The MFU of the attention operator in this PR has not reached the ideal range, and the cause is still under investigation.

@vllm-omni-review-bot

Copy link
Copy Markdown

This PR appears to be related to model: qwen-image.

Model owners: @NumberWan

@renyongxing, please review your own changes and leave a short self-review comment describing what you checked. PRs without author self-review may not be assigned a reviewer.

Please take a look when you have a chance. If you would like an automated review, mention @vllm-omni-review-bot in a comment.

@tzhouam

tzhouam commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

@vllm-omni-review-bot please review

@hsliuustc0106 hsliuustc0106 added diffusion codes related to diffusion models Kernel optimization Codes related to optimize kernel execution to improve hardware utilization labels Aug 29, 2026
@vllm-omni-review-bot

Copy link
Copy Markdown

Omni ReviewBot: no human activity for 10 days

@renyongxing this pull request has had no human commit, comment or review since 2026-08-29. Per repository policy it may be closed if it stays inactive.

To keep it moving, any one of these is enough: push an update, reply to the open blocker, or post the current plan and timeline.

@renyongxing

Copy link
Copy Markdown
Author

The Rope encoding in mixfusion is optimized by using the fusion operator. It is expected to be submitted and the comparison experiment result will be uploaded this week.

desenSunUBW and others added 6 commits September 10, 2026 09:10
…Image-3.0 and Qwen-Image (vllm-project#3638)

Signed-off-by: renyongxing <renyongxing2@huawei.com>
…en-Image mixfusion

Signed-off-by: renyongxing <renyongxing2@huawei.com>
…ache pop key

- qwen_image_mixfusion_benefit: OmniDiffusionRequest now takes prompt/request_id
  (single), not prompts/request_ids lists; construct per-request and gather.
- hunyuan_image3_real_mixfusion_benefit: same API migration (one request per
  prompt, asyncio.gather for the batched path).
- diffusion_model_runner: state_cache pop key uses state.request_id instead of
  the non-existent state.req_id in the interrupted/denoise_completed path.

Signed-off-by: renyongxing <renyongxing2@huawei.com>
MixFusion scheduling and pipeline code (base_scheduler, qwen/hunyuan
pipelines) still iterates request.prompts after the single-request API
migration. Add a backwards-compatible prompts property returning [self.prompt]
so the mixfusion batch path works on the current single-prompt request API.

Signed-off-by: renyongxing <renyongxing2@huawei.com>
Replace the native apply_rotary_emb_torch path in QwenImageCrossAttention
with the fused Triton rotary_kernel path. MixFusion lays out per-token
(chunk-position, resolution) rotary frequencies in chunk order; flatten the
3D image_freq_chunks to [B*chunk_size, D/2] so every image token carries its
own frequencies and feed them alongside text freqs through the fused kernel.
Also adapt the mixfusion benchmark scripts to the single-request API and
enable torch profiler output for the batched path.

Signed-off-by: renyongxing <renyongxing2@huawei.com>
…ry native forward hooks

has_active_block_hooks() only inspected Omni's HookRegistry, so the
MixFusion packed forward (which calls block.forward_mixfusion directly)
could bypass PyTorch-native forward hooks on the blocks. Under HSDP
(use_hsdp=True, hsdp_shard_size>1) fully_shard registers native forward
pre-hooks for the all-gather of sharded weights; bypassing them runs the
blocks on sharded weights and breaks inference.

Also treat PyTorch-native hooks (block._forward_pre_hooks /
_forward_hooks) as active so has_active_block_hooks() covers both hook
mechanisms; the pipeline then falls back to serial denoising, whose
per-request loops route every block through the hooked module call.
Covered by new CPU unit tests simulating fully_shard's pre-hook.

Signed-off-by: renyongxing <renyongxing2@huawei.com>
@vllm-omni-review-bot

vllm-omni-review-bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Omni ReviewBot triage note

Automated triage of commit dea5597c0800 produced:

  • Priority: high. Prompt maintainer attention is suggested.

These are automated triage suggestions only — the final decision belongs to the maintainers.

@renyongxing

Copy link
Copy Markdown
Author

Hi @hsliuustc0106, thanks for the re-review and for confirming the earlier fixes. Both remaining items are addressed on the current head (0ccca59):

  1. HSDP native-hook bypass — fixed in 0ccca59

has_active_block_hooks() now treats PyTorch-native hooks (block._forward_pre_hooks / block._forward_hooks) as active, in addition to Omni's HookRegistry. The pipeline re-checks this on every denoise step, and when any block carries an active hook it falls back to _denoise_step_serial_ragged, whose per-request loops route every block through the hooked module call — so fully_shard's all-gather pre-hooks run as usual.

We went with the serial fallback rather than register_fsdp_forward_method because the check is mechanism-agnostic: it protects against any native forward hook on the blocks, not just FSDP's, and needs no coupling to the HSDP implementation. The fallback also logs, so a silent packed-path loss is visible in server logs. Covered by new CPU unit tests that simulate fully_shard's pre-hook behavior (tests/diffusion/models/qwen_image/test_qwen_image_mixfusion_hooks.py).

  1. Server-level enablement — ee69278

MixFusion previously required every request to opt in via sampling.extra_args["enable_mixfusion"]. There is now a server-level default in OmniDiffusionConfig (enable_mixfusion, mixfusion_min_chunk_tokens, mixfusion_max_chunks), propagated from the orchestrator CLI through StageDeployConfig. The per-request switch is still there and takes precedence: both the pipeline gate and the scheduler key read extra_args.get("enable_mixfusion", od_config.enable_mixfusion), so an explicit per-request True/False always overrides the server default.

@renyongxing

Copy link
Copy Markdown
Author

@hsliuustc0106 To quantify the advantages of MixFusion in tensor parallelism and be closer to the actual scenario, we use main (step by step) in the case of TP △ {1, 2, 4}. MixFusion off) compared to b-on (Enable MixFusion at the server level). Experiment setup: Qwen-Image, 50 denoising steps, --enforce-eager, run 8 requests each time, and run each configuration for 3 times on average.

Two modes of arrival are reported:

  • **s0 - Simultaneous Burst * *: All 8 requests are submitted simultaneously at t = 0, and the size is (1024²×2, 1024×768×2, 768×1024×2, 512²×2) in adjacent pairs of the same resolution. This is the most advantageous workload for main: requests of the same resolution share the same step-by-step batch key and can be scheduled simultaneously.
  • s1 - Interleaved Heterogeneous Arrivals: One request is submitted every 2.5 seconds, (1024², 1024×768, 768×1024, 512², 1024², 1024×768, 768×1024, 512²) of sizes in mixed order, so requests of different sizes overlap on the fly. This represents real-world heterogeneous traffic.

Result - s0 (simultaneous burst, same size pairing):

TP Main Total Duration (s) MixFusion Total Duration (s) Acceleration Ratio
1 90.96 83.33 1.09×
2 57.38 50.29 1.14 ×
4 40.83 32.42 1.26×

**Results - s1 (staggered arrivals, mixed size order): * *

TP Main Total Duration (s) MixFusion Total Duration (s) Acceleration Ratio
1 95.42 84.73 1.13×
2 66.49 52.03 1.28 ×
4 50.23 35.38 1.42×

**Observations: * *

  1. In all TPs, MixFusion is better than main, and the acceleration ratio increases with the increase of TPs (s0: 1.09× → 1.14× → 1.26×; s1: 1.13× → 1.28× → 1.42×). As TPs increase, each step of computation is spread over more GPUs, and execution is increasingly affected by scheduling/batch behavior, which magnifies the cost of `main' restricted batch processing.
  2. **mainOnly requests with the same sampling parameters can be processed in batches. * * -- Step by step batch keys contain height and width (sched/interface.py). Its queue-head admission logic (base_scheduler.schedule()) blocks all subsequent requests after requests with mismatched keys. In s0 mode, it can still form pairs of the same size (; In s1 mode, the neighbors are all different sizes, so main degenerates to near-serial execution, with a total time that even exceeds the s0 baseline.
  3. MixFusion is insensitive to the arrival sequence and size heterogeneity: It packs requests of different sizes into a single stepped batch and executes them step by step. Therefore, the total time consumed by the two arrival modes is basically the same. The largest difference is precisely where the flow heterogeneity is strongest (s1, TP=4: 1.42×).

**Summary: **The advantage of MixFusion comes from the packaging capability of heterogeneous requests, which cannot be achieved by the main key precise step-by-step batch processing. This advantage persists in tensor parallelism and is further magnified. In actual scenarios, the resolutions requested by users are not uniform, and inference is usually not performed on a single card. Therefore, Mixfusion can bring considerable benefits.

@hsliuustc0106

Copy link
Copy Markdown
Collaborator

Re-reviewed at 0ccca595ed977f7ea765e790531d1847e75af85d against base ee81f33001922f8d91dd09da0a57ee1531a8df82.

[P2] Register the server-level CLI flags — arg_utils.py:627

The new fields exist in OrchestratorArgs, but OmniServeCommand.subparser_init() never registers --enable-mixfusion, --mixfusion-min-chunk-tokens, or --mixfusion-max-chunks. Consequently, vllm serve … --omni --enable-mixfusion fails with an unrecognized-argument error before configuration propagation. Register the three flags, document their defaults, and add parser coverage.

The previous HSDP P1 is fixed: native PyTorch hooks now trigger serial fallback. No new correctness blocker found in the reviewed delta.

The remote head remained unchanged. All five reported checks and diff hygiene pass; no Buildkite result is listed. Validation was static—tests and GPU benchmarks were not independently rerun on the fork head.

The server-level MixFusion knobs added in ee69278 (enable_mixfusion,
mixfusion_min_chunk_tokens, mixfusion_max_chunks) were modeled on
OrchestratorArgs and StageDeployConfig but never registered in
OmniServeCommand.subparser_init(), so
"vllm serve ... --omni --enable-mixfusion" failed with an
unrecognized-arguments error and the server-level defaults could only be
set through the deploy YAML.

Register --enable-mixfusion (BooleanOptionalAction, so
--no-enable-mixfusion can override a YAML-enabled stage),
--mixfusion-min-chunk-tokens and --mixfusion-max-chunks, with defaults
(256/128) documented in the help text. Unset flags stay out of the
explicit kwargs dict, so the deploy YAML's per-stage values remain in
force; explicit flags flow through build_stage_runtime_overrides (the
fields are deploy-schema keys, exempt from the OrchestratorArgs
blacklist) and the diffusion stage CLI field gate into the stage runtime
overrides. Covered by new parser tests including the propagation check.

Signed-off-by: renyongxing <renyongxing2@huawei.com>
…bility

The MixFusion shape relaxation in the schedulers was gated only on the
enable_mixfusion flag, so on any pipeline without ragged-latent support
the scheduler dropped height/width/resolution from the batch key, packed
mixed-resolution requests into one step batch, and the runner crashed
per step in _gather_tensor_rows on the resulting shape mismatch.

Introduce an opt-in pipeline capability and gate every layer on it:

- Pipelines declare `supports_mixfusion: ClassVar[bool] = True`;
  QwenImagePipeline opts in. The attribute is read via getattr and
  documented on SupportsStepExecution only, mirroring
  supports_chunk_step_grouping, so the runtime_checkable protocol keeps
  matching all pipelines.
- registry gains resolve_diffusion_pipeline_cls()/supports_mixfusion()
  to resolve the selected pipeline class (custom pipeline_class,
  Diffusers adapter, or registry lookup) without instantiating it.
- The engine fails fast at startup when server-level enable_mixfusion
  is set on a pipeline without the capability.
- The schedulers resolve the capability in initialize() and pass it
  into _apply_mixfusion_shape_relaxation; on an unsupported pipeline
  the request-level flag degrades to a no-op (resolution keeps
  grouping the batch, per-prompt requests keep their key), which is
  safe because MixFusion is performance-only.

Tests cover capability resolution, both scheduler directions, and the
engine startup check.

Signed-off-by: renyongxing <renyongxing2@huawei.com>
…annotation

Remove the local .bak_* backup ignore rule that leaked into the PR and
correct the denoise_step return annotation: the list branch returns
_denoise_step_mixfusion's list[torch.Tensor].

Signed-off-by: renyongxing <renyongxing2@huawei.com>
…text

wake_events are created in _init_executor while the global start method
is only switched to spawn later in _launch_workers, so mp.Event() would
come from the fork context and then be pickled into spawn-Process args.
Sync primitives must come from the same context as the processes that
consume them; record this at the pin site.

Signed-off-by: renyongxing <renyongxing2@huawei.com>
feature_compatibility.md gains a MixFusion serving section covering the
three flags, the supports_mixfusion capability requirement (server-level
flag fails at startup on unsupported pipelines, request-level flag is a
no-op), and the packed-path constraints (edit fallback, zero_cond_t and
SP>1 errors, hooks/true-CFG serial fallback, NPU dense attention).

diffusion_continuous_batching.md describes the scheduler-side shape
relaxation, the packed dispatch and its fallback chain, threshold
aggregation, and the attention_kwargs limitation.

Signed-off-by: renyongxing <renyongxing2@huawei.com>
Resolve conflict in docs/user_guide/feature_compatibility.md: keep the
MixFusion section alongside the upstream allgather_degree GPU-count
formula and markdown fixes.

Signed-off-by: renyongxing <renyongxing2@huawei.com>
@vllm-omni-review-bot

vllm-omni-review-bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Omni ReviewBot: superseded

The CI failure noted on f216a0589362 refers to an earlier head; the pull request now points at 86369e45af11.

Signed-off-by: renyongxing <renyongxing2@huawei.com>
@renyongxing

Copy link
Copy Markdown
Author

@hsliuustc0106 Thanks for the reviews. A few updates since the last round:

Serve CLI flag registration (P2). Fixed in 5096155: --enable-mixfusion (BooleanOptionalAction, so --no-enable-mixfusion also works), --mixfusion-min-chunk-tokens (default 256), and --mixfusion-max-chunks (default 128) are now registered on the serve subparser and propagate through the stage-CLI override chain. Three parser tests cover registration and propagation.

Pipeline capability gating for MixFusion (new, f4d92ff). In self-review we found that the shape relaxation in _apply_mixfusion_shape_relaxation was gated only on the enable_mixfusion flag, while only QwenImagePipeline sets use_ragged_latents. On any other step-execution pipeline, server-level --enable-mixfusion or a request-level flag would relax height/width/resolution out of the batch key, co-batch mixed resolutions, and crash per step in the dense _prepare_latents path. This is now gated end-to-end on an opt-in pipeline capability:

  • Pipelines declare supports_mixfusion: ClassVar[bool] = True (currently Qwen-Image only). The attribute is read via getattr and documented on SupportsStepExecution like supports_chunk_step_grouping, so the @runtime_checkable protocol keeps matching every pipeline.
  • registry.supports_mixfusion(od_config) resolves the selected pipeline class (custom pipeline_class → Diffusers adapter → registry) without instantiating it, and the engine rejects server-level enable_mixfusion on unsupported pipelines at startup.
  • The schedulers resolve the capability in initialize(). A request-level extra_args={"enable_mixfusion": True} on an unsupported pipeline degrades to a no-op — resolution stays in the batch key, so mixed resolutions keep batching separately. MixFusion is performance-only, so the degradation is safe.
  • Tests cover capability resolution (declared / not declared / unresolvable), both schedulers' degradation paths, and the engine startup check; the affected suites pass 100 tests.

@hsliuustc0106 hsliuustc0106 added the ready label to trigger buildkite CI label Oct 15, 2026
…n config reads

The backwards-compatible `prompts` property on OmniDiffusionRequest shadowed
the ad-hoc attribute pattern used by single-request code paths: joy_image's
preprocess assigns `request.prompts`, which an unsettable property rejects,
and its regression test asserts `not hasattr(request, "prompts")`, which the
property makes impossible. Drop the accessor and express the per-prompt
check in the MixFusion shape relaxation against the single `request.prompt`
API instead.

Also read `od_config` defensively in QwenImage's prepare_encode MixFusion
block: unit tests build the pipeline without __init__, so the attribute may
be absent.

Signed-off-by: renyongxing <renyongxing2@huawei.com>
@vllm-omni-review-bot

vllm-omni-review-bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Omni ReviewBot: superseded

The CI failure noted on 86369e45af11 refers to an earlier head; the pull request now points at 08ce4fcb106a.

Signed-off-by: renyongxing <renyongxing2@huawei.com>

# Conflicts:
#	vllm_omni/diffusion/attention/backends/flash_attn.py
#	vllm_omni/diffusion/models/qwen_image/qwen_image_transformer.py
@vllm-omni-review-bot

vllm-omni-review-bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Omni ReviewBot: superseded

The CI failure noted on 051bff8517ef refers to an earlier head; the pull request now points at 241882deb03d.

Signed-off-by: renyongxing <renyongxing2@huawei.com>
Resolve conflicts: keep mixfusion fields in arg_utils; adopt upstream
StageConfigFactory shim in omni_engine_base (fields flow via OmniDiffusionConfig).

Signed-off-by: renyongxing <renyongxing2@huawei.com>
Signed-off-by: renyongxing <renyongxing2@huawei.com>
@renyongxing

Copy link
Copy Markdown
Author

@hsliuustc0106 I conducted a Buildkite verification locally, and the results are as follows.

Local reproduction of the Buildkite "Simple Test" (cuda/test-ready.yml) — failure analysis and re-trigger request

Setup

Raw numbers

Group PR run (FAILED/ERROR) Baseline run (FAILED)
G1 38 / 7 24
G2 91 / 4 2
G3 162 / 12 8
G4 52 / 45 0

The two runs are not directly comparable: the PR run used HF_HUB_OFFLINE=1 (CI-like) while the baseline run had network access, and the baseline misses several models added upstream between the two revisions.

Failure analysis — all failures are environmental, none traced to the PR

  1. Offline HF cache misses (the vast majority). The PR run could not download models. Examples: MOSS-Image cache absent → FileNotFoundError: ref-encoder.sock (G1); most G2 failures are the same class; test_omni_processing_correctness explicitly fetches from the Hub (huggingface_hub download errors are imported by the test itself), so it cannot pass offline without a pre-warmed cache.
  2. torch teardown crash (G4's 45 ERRORs + UnicodeDecodeError). The crash is in torch/_ops.py::_jit_get_operation from the interpreter-exit weakref teardown of the torch ops cache — it fires after tests complete and pollutes module collection in large combined runs. Reproduced with a standalone run where all 51 tests of tests/helpers/tests/test_assertions.py passed and the crash still occurred at exit. Container torch build issue, unrelated to the PR.
  3. Cross-test interference in the big run. The two largest PR-only clusters — test_arg_utils_shared_fields.py::test_aux_outputs_* (12) and test_diffusers_backend.py::test_adapter_guard_* (9) — were re-run individually on dea5597c0: all pass (12 passed / 10 passed).

Conclusion

No PR-introduced regression was found in the local reproduction; every failure cluster is attributable to the offline environment, a torch teardown bug in the container, or run-to-run interference.

@hsliuustc0106 hsliuustc0106 added ready label to trigger buildkite CI and removed ready label to trigger buildkite CI labels Oct 19, 2026
@renyongxing

Copy link
Copy Markdown
Author

@hsliuustc0106 The last GPU job of build #17585 has been stuck in waiting for 2+ hours with no log output. The GPU agent appears to be online but shows as Unassigned (not attached to any cluster queue), so it never receives the job. Could someone with admin access re-attach the agent to the GPU queue, then retry the job?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

diffusion codes related to diffusion models enhancement New feature or request high priority high priority issue, needs to be done asap Kernel optimization Codes related to optimize kernel execution to improve hardware utilization ready label to trigger buildkite CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants