Repository navigation
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
405ecd3 to
eb391d7
Compare
|
@ZJY0516 PTAL |
| attn_metadata = self._with_per_forward_state(attn_metadata, query) | ||
|
|
||
| # 2. Kernel Execution (Computation) | ||
| if self.use_ring and strategy is not self._no_parallel_strategy: |
There was a problem hiding this comment.
This bypasses the selected SPARSE_ATTN backend when ring_degree > 1: RingParallelAttention only runs its own SDPA/flash-style kernels, so a configured sparse plugin is silently ignored. Please either fail fast for sparse plugins with ring SP or route the ring path through the plugin, with a regression test.
| query, key, value, attn_metadata, ctx = strategy.pre_attention(query, key, value, attn_metadata) | ||
|
|
||
| attn_metadata = self._with_kv_cache_dtype(attn_metadata) | ||
| attn_metadata = self._with_per_forward_state(attn_metadata, query) |
There was a problem hiding this comment.
This now builds per-forward tensors for every attention layer whenever step/geometry exists, even for dense backends that ignore per_forward. Wan sets this state unconditionally, so default inference can pick up many extra GPU allocations per denoise step. Please gate this to backends that consume it, cache the state per forward, or include before/after latency evidence showing the default path is unaffected.
b3066d5 to
462a1f6
Compare
…e for DiT Add a plugin-based sparse-attention path for diffusion (DiT) models on top of the per-role attention config (vllm-project#2681), plus a generic per-forward state channel that step-aware attention backends can read. Implements RFC vllm-project#3715: a dedicated SPARSE_ATTN slot (Proposal A, alpha) and Proposal B's param-merge semantics. Per-forward state (generic, no sparse code): - ForwardContext.total_denoise_steps + setter; the Wan2.2 pipelines set it once before the denoise loop (alongside the existing denoise_step_idx). - PerForwardState: a frozen dataclass carried by composition on AttentionMetadata.per_forward, with per-sample [num_samples] tensor fields denoise_step_idx and total_denoise_steps. A source-isolated bridge in the Attention layer fills it from ForwardContext (device-agnostic), so any backend can read step state without reaching into global context. Sparse attention dispatcher: - SPARSE_ATTN member in DiffusionAttentionBackendEnum; SparseAttentionBackend(AttentionBackend) + _SparseAttentionImpl(AttentionImpl) inherit the conservative ABC defaults. - Resolves an external vllm_omni.sparse_attn callable plugin fn(query, key, value, params, is_causal, softmax_scale) -> Tensor; a missing or broken plugin fails loudly at model init, never a silent fall back to dense. - Per-role config with a shorthand so backend=<plugin> routes to the dispatcher; built-in dense names are excluded. Cross-attention stays dense by role. - The dispatcher merges params in three tiers (static < per-forward < extra, None dropped) into the plugin's flat params dict. Per-forward video geometry: - Extend the per-forward state with optional video grid geometry so structure-aware sparse kernels (e.g. windowed / keyframe attention like LVSA) can map the flat token sequence back to (frame, patch) coordinates instead of relying on env-var or call-counting heuristics. - ForwardContext: total_latent_frames / patches_per_frame fields + set_forward_context_geometry() setter. - PerForwardState: matching per-sample [num_samples] tensor fields, carried and flattened through the existing to_dict() path (so kernels read params["total_latent_frames"] / params["patches_per_frame"]). - Attention bridge: fills the geometry tensors from ForwardContext alongside the step state. - Wan2.2 and HunyuanVideo transformers publish their patch grid once per forward (before attention), reusing the post-patch grid they already compute. - Geometry is optional; backends ignore fields they don't use. seq_len == total_latent_frames * patches_per_frame. Gated attention metadata: - Forward the correctness-critical AttentionMetadata fields attn_mask (padding / validity) and full_attn_spans (mixed causal/full topology) into params, only when set, so a kernel that needs them is not silently starved of them. - A plugin advertises which it consumes via an optional capabilities dict on the callable (read once at resolution, malformed -> empty). When such a field is present but unadvertised, the dispatcher raises instead of letting the kernel ignore it. The dispatcher forward runs under torch.compile, so the gating uses direct attribute access with capability flags precomputed in __init__. Includes CPU-runnable tests for the per-forward state and the dispatcher (param merge, capability self-check, malformed capabilities) plus a GPU-gated on-CUDA dispatch test, and a user-guide section documenting the plugin contract. Co-authored-by: Zhen Zhang <zhen.zhang.fr@huawei.com> Signed-off-by: Harenome Ranaivoarivony-Razanajato <harenome.razanajato1@huawei.com> Signed-off-by: Zhen Zhang <zhen.zhang.fr@huawei.com>
462a1f6 to
1151ff2
Compare
…ia a transformer pre-hook Per-forward video geometry was published per-model: every video DiT had to call set_forward_context_geometry(...) inside its forward (Wan2.2, HunyuanVideo) — an O(models) cost coupling core model code to the sparse-attention feature. Replace it with a framework-registered transformer forward pre-hook that reads the (B,C,T,H,W) latent shape plus the model's patch config and publishes RAW, model-agnostic primitives (latent_shape, patch_size) onto ForwardContext. The SPARSE_ATTN dispatcher's default resolver derives total_latent_frames / patches_per_frame from them; a plugin geometry_fn may override. New video DiTs need no geometry edits. - NEW video_geometry.py: _resolve_patch_size (handles Wan 3-tuple + Hunyuan scalar/patch_size_t), best-effort _video_geometry_pre_hook (no-op on non-5D input / no patch size / no active context), idempotent register_video_geometry_hooks. - forward_context: ForwardContext carries raw latent_shape/patch_size; setter renamed set_forward_context_geometry -> set_forward_context_video_geometry. - diffusion_model_runner: register hooks at end of load_model (after compile/offload). - attention/layer bridge: surface raw primitives as per-sample [n,3] tensors. - abstract PerForwardState: add raw latent_shape/patch_size; derived fields kept for back-compat, now resolver-filled, not bridge-filled. - sparse_attn: _apply_default_geometry resolver + optional plugin geometry_fn. - Remove per-model geometry blocks from wan2_2 / hunyuan_video_15 transformers (post_patch_* locals retained for RoPE/unpatchify). Address review feedback: - Gate per_forward construction to backends that consume it (AttentionImpl .consumes_per_forward; only the SPARSE_ATTN dispatcher opts in), so the default dense path builds no per-layer/per-step step/geometry tensors. - Fail fast when SPARSE_ATTN is combined with ring sequence parallelism: ring routes through RingParallelAttention's dense kernels and would silently bypass the sparse plugin (Attention._assert_ring_backend_supported). - Tests: new test_video_geometry.py; update test_per_forward_state, test_sparse_attn. Docs: attention_backends.md. Signed-off-by: Zhen Zhang <zhen.zhang.fr@huawei.com>
1151ff2 to
5b7f5f2
Compare
|
@harenome Please resolve conlicts. Thanks |
Omni ReviewBot: no human activity for 10 days@harenome 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. |
Omni ReviewBot: no human activity for 25 days@harenome this pull request has had no human commit, comment or review since 2026-08-29. Please consider marking this PR as draft until work can resume. The author or a maintainer decides whether to change the PR state. 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. |
Omni ReviewBot routing recordAssigned Strict on cursor (cursor-grok-4.6-high) under experiment |
Omni ReviewBot attempt recordReview attempt ended as timeout (Strict attempt outlived its budget; falling back to direct/cursor/auto). |
3 similar comments
Omni ReviewBot attempt recordReview attempt ended as timeout (Strict attempt outlived its budget; falling back to direct/cursor/auto). |
Omni ReviewBot attempt recordReview attempt ended as timeout (Strict attempt outlived its budget; falling back to direct/cursor/auto). |
Omni ReviewBot attempt recordReview attempt ended as timeout (Strict attempt outlived its budget; falling back to direct/cursor/auto). |
|
Can not further work on this at the moment. |
Purpose
Refactors and supersedes (#2231).
Implements a light plugin mechanism for sparse attention as proposed in RFCs #2233 and #3715.
It includes two parts:
This mechanism reuses and extends the ideas of per-role attention config (#2681) and
ForwardContext.denoise_step_idx(#2640).The dispatcher is built to make shipping a third-party sparse kernel as simple as possible. A plugin only has to expose one callable in its entry point and there is no base class to subclass or boilerplate: a minimal plugin can be just a function. Optional additional capabilities are advertised in a simple
capabilitiesdict.Design
Per-forward state (generic)
New field
AttentionMetadata.per_forwardholds aPerForwardStateobject for per-forward metadata.It holds common metadata such as framework state or geometry.
Framework state (such as denoising steps) is read from
ForwardContextbyAttentionlayers.Geometry is model-specific and set by the transformer forward of supported models.
Sparse attention dispatcher
The sparse attention dispatcher lives in
SparseAttentionBackendand selected viaDiffusionAttentionBackendEnum.SPARSE_ATTN.Plugins register a callable under the
vllm_omni.sparse_attnentry-point group.A minimal plugin can be as simple as the following snippet (on top of setting the entry-point):
It is enabled on per role with a short form: for instance,
per_role.self.backend=<plugin>orper_role.cross.backend=<plugin>will be routed to the dispatcher automatically.Multiple sparse plugins can coexist.
Built-in backends (other
DiffusionAttentionBackendEnumvalues) have priority over third-party plugins.The callable signature is
fn(query, key, value, params, is_causal, softmax_scale) -> Tensor, with q/k/v in BSND layout[batch, seq, heads, head_dim].paramsis a flat dict (RFC #3715, Proposal B), merged from three sources in increasing priority:extra.params;PerForwardState— the per-forward fields the framework fills (step, geometry);AttentionMetadata.extra— dynamic per-forward values.On a key collision the later source wins, and
Nonevalues are dropped, so a kernel can rely onparams.get(key, default).Most
paramsentries are optional and may be silently ignored by kernels.Entries that can not be ignored, if present, are guarded by capabilities.
Currently, two entries must be handled if provided:
attn_mask(for padding/validity, capability name:supports_attention_mask)full_attn_spans(for mixed causal/full attention, capability name:supports_full_attn_spans).Additional capabilities can be advertised by setting an additional attribute
capabilitiesto the callable.Ready for future evolutions
attn_maskandfull_attn_spansareNone.The plugin mechanism is already ready for models and usecases that require it.
paramsas new usecases emerge and new entries will not break compatibility with older pluginsPerForwardStateuses per-sample tensors for denoising steps: ready for future work such asRFC [RFC]: Refactor engine/runner/pipeline to support step-wise and continuos batching #874 and feat: Support dynamic batching for heterogeneous diffusion requests #4024.
Tests and docs
tests/diffusion/attention/test_per_forward_state.py: the state dataclass and the layer helper (with a mocked SDPA backend).tests/diffusion/sparse_attn/test_sparse_attn.py: plugin lookup (mocked entry points), the three-layer merge order andNone-drop, capability checks, and the short-form routing.User docs:
docs/user_guide/diffusion/attention_backends.md(the Sparse attention (plugin) section: the contract,params, capabilities, and a small example plugin).Demo
Two external plugins exercise the dispatcher end-to-end, each a standalone package with no dependency on vllm-omni:
spargeattn(SpargeAttn) andlvsa_sparse(LVSA, with SDPA or FlashInfer kernels). See vllm-omni-plugin-demo for setup and run commands.