[Attention] Add trtllm diffusion attention backend with Skip-Softmax (#5283)

Signed-off-by: lishunyang12 <lishunyang03@gmail.com>
Co-authored-by: lishunyang12 <lishunyang03@gmail.com>
This commit is contained in:
SYLARandlishunyang12 authored and GitHub committed 2026-07-27 22:48:11 +08:00
1 parent 4dd1b47f47
commit 7762d664d8
24 files changed
+1512 -52

No files matched your search

+80 -11
View File
@@ -2,6 +2,7 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
import copy
import math
import os
import random
from collections.abc import Callable, Mapping
@@ -1070,6 +1071,19 @@ class OmniDiffusionConfig:
"""
self.tf_model_config = tf_config
self._propagate_quantization_from_tf_config(tf_config)
self._propagate_skip_softmax_calibration(tf_config)
def _propagate_skip_softmax_calibration(self, tf_config: "TransformerConfig") -> None:
cfg = getattr(self, "diffusion_attention_config", None)
if not isinstance(cfg, AttentionConfig):
return
specs = [s for s in (cfg.default, *cfg.per_role.values()) if s is not None]
from vllm_omni.diffusion.attention.backends.trtllm_calibration import (
propagate_skip_softmax_calibration,
)
propagate_skip_softmax_calibration(specs, self.model, tf_config)
def update_multimodal_support(self) -> None:
# Resolve serving-visible multimodal behavior from shared metadata
@@ -1323,23 +1337,78 @@ class DiffusionRequestAbortedError(RuntimeError):
"""Raised when a diffusion request ends via user-visible abort."""
def _in_range(value: Any, name: str, lo: float, hi: float | None) -> float | None:
"""Validate an optional numeric control at config-parse time."""
if value is None:
return None
x = float(value)
if not math.isfinite(x) or x < lo or (hi is not None and x > hi):
rng = f"in [{lo}, {hi}]" if hi is not None else f">= {lo}"
raise ValueError(f"{name} must be finite and {rng}; got {value!r}.")
return x
@dataclass
class SkipSoftmaxSpec:
"""User-facing skip-softmax controls for the TRTLLM_ATTN backend.
``target_sparsity`` uses the checkpoint's calibrated curve (a·exp(b·s)); ``threshold``
is the calibration-free absolute skip threshold. They are mutually exclusive.
"""
target_sparsity: float | None = None
threshold: float | None = None
disabled_until_timestep: float = 0.0
def __post_init__(self) -> None:
self.target_sparsity = _in_range(self.target_sparsity, "skip_softmax.target_sparsity", 0.0, 1.0)
self.threshold = _in_range(self.threshold, "skip_softmax.threshold", 0.0, None)
self.disabled_until_timestep = (
_in_range(self.disabled_until_timestep, "skip_softmax.disabled_until_timestep", 0.0, 1.0) or 0.0
)
if self.target_sparsity is not None and self.threshold is not None:
raise ValueError("skip_softmax: set either target_sparsity or threshold, not both.")
@dataclass
class AttentionSpec:
"""Specifies a backend and its backend-specific parameters for one attention role."""
"""Specifies a backend and its typed backend-specific config for one attention role."""
backend: str # registry name, e.g. "FLASH_ATTN"
extra: dict[str, Any] = field(default_factory=dict) # backend-specific kwargs
backend: str
skip_softmax: SkipSoftmaxSpec | None = None
skip_calibration: dict | None = field(default=None, repr=False)
def __post_init__(self) -> None:
if not isinstance(self.backend, str):
raise TypeError(f"Expected str for AttentionSpec.backend, got {type(self.backend)!r}")
self.skip_softmax = self._coerce_skip_softmax(self.skip_softmax)
if self.skip_softmax is not None and self.backend.upper() != "TRTLLM_ATTN":
raise ValueError(
f"skip_softmax is only supported by the TRTLLM_ATTN backend, but backend={self.backend!r}. "
f"Remove skip_softmax or set backend to TRTLLM_ATTN."
)
if self.extra is None:
self.extra = {}
elif isinstance(self.extra, Mapping):
self.extra = dict(self.extra)
else:
raise TypeError(f"Expected dict for AttentionSpec.extra, got {type(self.extra)!r}")
@staticmethod
def _coerce_skip_softmax(value: Any) -> SkipSoftmaxSpec | None:
if value is None or isinstance(value, SkipSoftmaxSpec):
return value
if isinstance(value, Mapping):
return SkipSoftmaxSpec(**dict(value))
raise TypeError(f"Expected dict or SkipSoftmaxSpec for skip_softmax, got {type(value)!r}")
def backend_kwargs(self) -> dict[str, Any] | None:
"""Serialize typed backend config into the kwargs dict the backend impl consumes."""
if self.skip_softmax is None:
return None
ss = self.skip_softmax
kw: dict[str, Any] = {}
if ss.threshold is not None:
kw["skip_softmax_threshold"] = ss.threshold
if ss.target_sparsity is not None:
kw["target_sparsity"] = ss.target_sparsity
if ss.disabled_until_timestep:
kw["disabled_until_timestep"] = ss.disabled_until_timestep
return kw or None
@dataclass
@@ -1408,13 +1477,13 @@ class AttentionConfig:
normalized[role] = node
return
spec_keys = {"backend", "extra"}
spec_keys = {"backend", "skip_softmax"}
node_dict = dict(node)
node_keys = set(node_dict)
if node_keys & spec_keys:
if not node_keys <= spec_keys:
raise ValueError(
f"Invalid per_role entry for role {role!r}: cannot mix backend/extra with nested role keys."
f"Invalid per_role entry for role {role!r}: cannot mix backend/skip_softmax with nested role keys."
)
normalized[role] = node_dict
return