Skip to content

Commit 3bb0565

Browse files
committed
small updates, mostly documentation
Signed-off-by: Olivia Stoner <245287810+o-stoner@users.noreply.github.com>
1 parent 3548b56 commit 3bb0565

7 files changed

Lines changed: 47 additions & 62 deletions

File tree

tensorrt_llm/_torch/visual_gen/attention_backend/cute_dsl.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515
"""
16-
CuTe DSL Backend for Visual Generation Models
16+
CuTe DSL (NVIDIA kernels) Backend for Visual Generation Models
1717
1818
CuTeDSLAttention runs the VSA sparse path when sparse_attention_config is set,
1919
otherwise the dense cubin path (with optional QK16PV8 quantization).
@@ -47,6 +47,17 @@
4747
cute_dsl = None
4848
_cute_dsl_import_error = e
4949

50+
_vsa_import_error = None
51+
try:
52+
from tensorrt_llm._torch.visual_gen.cute_dsl_kernels.blackwell.video_sparse_attention import (
53+
block_sparse_attn_from_indices_cute,
54+
is_cute_supported,
55+
)
56+
except (ImportError, OSError) as e:
57+
block_sparse_attn_from_indices_cute = None
58+
is_cute_supported = None
59+
_vsa_import_error = e
60+
5061

5162
# VSA (Video Sparse Attention) sparse-path helpers
5263

@@ -267,8 +278,9 @@ def __init__(
267278
skip_softmax_threshold_scale: Optional[float] = None,
268279
**kwargs,
269280
):
270-
# Dense path requires head_dim=128 (packaged cubins); the VSA sparse
271-
# path JIT-compiles per shape, so it has no such restriction.
281+
# Dense cubin path is head_dim=128-only (packaged cubins), so enforce it
282+
# here. The VSA path needs no check: it is gated at runtime by
283+
# is_cute_supported and falls back to dense SDPA when head_dim != 128.
272284
if sparse_attention_config is None and head_dim != 128:
273285
raise ValueError(f"CUTEDSL cubins require head_dim=128, got head_dim={head_dim}.")
274286
self.layer_idx = layer_idx
@@ -479,13 +491,6 @@ def _forward_vsa(
479491
Returns:
480492
[B, S, H, D] in the same original token order.
481493
"""
482-
# Lazy import: the VSA kernels package is optional and may not be
483-
# importable in environments without the cute-dsl runtime.
484-
from ..cute_dsl_kernels.blackwell.video_sparse_attention import (
485-
block_sparse_attn_from_indices_cute,
486-
is_cute_supported,
487-
)
488-
489494
if gate_compress is None:
490495
raise ValueError(
491496
"CuTeDSLAttention VSA path requires gate_compress. "
@@ -519,7 +524,9 @@ def _forward_vsa(
519524
attn_probs_c = scores_c.softmax(dim=-1)
520525
o_c = torch.einsum("bhnm,bmhd->bnhd", attn_probs_c, v_c)
521526

522-
use_cute = is_cute_supported(q) and (q.dtype == k.dtype == v.dtype)
527+
use_cute = (
528+
_vsa_import_error is None and is_cute_supported(q) and (q.dtype == k.dtype == v.dtype)
529+
)
523530
topk_indices = attn_probs_c.topk(cur_topk, dim=-1).indices.to(torch.int32)
524531

525532
o_c_tiled = (

tensorrt_llm/_torch/visual_gen/models/flux/pipeline_flux.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ def __init__(self, model_config):
6363
if _sa_cfg is not None and getattr(_sa_cfg, "algorithm", None) == "vsa":
6464
raise ValueError(
6565
"Video Sparse Attention (sparse_attention_config.algorithm='vsa') is "
66-
"only supported by Wan T2V pipelines. Remove sparse_attention_config "
67-
"for FLUX."
66+
"only supported by the Wan 2.1 T2V 14B (720P) pipeline. Remove "
67+
"sparse_attention_config for FLUX."
6868
)
6969

7070
super().__init__(model_config)

tensorrt_llm/_torch/visual_gen/models/flux/pipeline_flux2.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ def __init__(self, model_config):
132132
if _sa_cfg is not None and getattr(_sa_cfg, "algorithm", None) == "vsa":
133133
raise ValueError(
134134
"Video Sparse Attention (sparse_attention_config.algorithm='vsa') is "
135-
"only supported by Wan T2V pipelines. Remove sparse_attention_config "
136-
"for FLUX.2."
135+
"only supported by the Wan 2.1 T2V 14B (720P) pipeline. Remove "
136+
"sparse_attention_config for FLUX.2."
137137
)
138138

139139
super().__init__(model_config)

tensorrt_llm/_torch/visual_gen/models/ltx2/pipeline_ltx2.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -604,8 +604,8 @@ def __init__(self, model_config):
604604
if _sa_cfg is not None and getattr(_sa_cfg, "algorithm", None) == "vsa":
605605
raise ValueError(
606606
"Video Sparse Attention (sparse_attention_config.algorithm='vsa') is "
607-
"only supported by Wan T2V pipelines. Remove sparse_attention_config "
608-
"for LTX-2."
607+
"only supported by the Wan 2.1 T2V 14B (720P) pipeline. Remove "
608+
"sparse_attention_config for LTX-2."
609609
)
610610
super().__init__(model_config)
611611

tensorrt_llm/_torch/visual_gen/models/wan/pipeline_wan_i2v.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def __init__(self, model_config):
105105
if _sa_cfg is not None and getattr(_sa_cfg, "algorithm", None) == "vsa":
106106
raise ValueError(
107107
"Video Sparse Attention (sparse_attention_config.algorithm='vsa') is "
108-
"only supported by Wan T2V pipelines (Wan 2.1 and Wan 2.2). Remove "
108+
"only supported by the Wan 2.1 T2V 14B (720P) pipeline. Remove "
109109
"sparse_attention_config for Wan I2V."
110110
)
111111

tensorrt_llm/_torch/visual_gen/models/wan/transformer_wan.py

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,19 @@ def forward(
246246
return temb, temb_proj, encoder_hidden_states, encoder_hidden_states_image
247247

248248

249+
def _default_vsa_gate(linear: Linear, bias_value: float) -> None:
250+
"""Default a VSA gate Linear absent from the checkpoint: weight=0, bias=bias_value
251+
(G_c=0 / G_f=1, preserving dense behavior at sparsity=0)."""
252+
if not linear._weights_created:
253+
linear.create_weights()
254+
if linear.weight.is_meta:
255+
return
256+
with torch.no_grad():
257+
linear.weight.zero_()
258+
if linear.bias is not None:
259+
linear.bias.fill_(bias_value)
260+
261+
249262
class WanBlock(nn.Module):
250263
def __init__(
251264
self,
@@ -417,32 +430,6 @@ def __init__(
417430
torch.empty(1, 6, hidden_size).normal_(std=hidden_size**-0.5)
418431
)
419432

420-
def init_gate_compress_zero(self) -> None:
421-
"""Zero-initialize to_gate_compress."""
422-
if self.to_gate_compress is None:
423-
return
424-
if not self.to_gate_compress._weights_created:
425-
self.to_gate_compress.create_weights()
426-
if self.to_gate_compress.weight.is_meta:
427-
return
428-
with torch.no_grad():
429-
self.to_gate_compress.weight.zero_()
430-
if self.to_gate_compress.bias is not None:
431-
self.to_gate_compress.bias.zero_()
432-
433-
def init_gate_fine_default(self) -> None:
434-
"""Initialize to_gate_fine to emit constant 1 (weight=0, bias=1)."""
435-
if self.to_gate_fine is None:
436-
return
437-
if not self.to_gate_fine._weights_created:
438-
self.to_gate_fine.create_weights()
439-
if self.to_gate_fine.weight.is_meta:
440-
return
441-
with torch.no_grad():
442-
self.to_gate_fine.weight.zero_()
443-
if self.to_gate_fine.bias is not None:
444-
self.to_gate_fine.bias.fill_(1.0)
445-
446433
def forward(
447434
self,
448435
x,
@@ -839,7 +826,6 @@ def load_weights(self, weights: dict) -> None:
839826
}
840827
loader = DynamicLinearWeightLoader(self.model_config, params_map=params_map)
841828

842-
loaded_linears: set = set()
843829
for name, module in tqdm(self.named_modules(), desc="Loading weights"):
844830
if len(module._parameters) == 0:
845831
continue
@@ -849,7 +835,12 @@ def load_weights(self, weights: dict) -> None:
849835

850836
if weight_dicts:
851837
loader.load_linear_weights(module, name, weight_dicts)
852-
loaded_linears.add(name)
838+
# VSA gates absent from the checkpoint default to G_c=0 / G_f=1
839+
# (dense behavior at sparsity=0).
840+
elif name.endswith(".to_gate_compress"):
841+
_default_vsa_gate(module, 0.0)
842+
elif name.endswith(".to_gate_fine"):
843+
_default_vsa_gate(module, 1.0)
853844
elif "add_k_proj" in name or "add_v_proj" in name:
854845
logger.info(f"[Weight Loading] No weights found for I2V module: {name}")
855846
elif isinstance(module, RMSNormTPAware):
@@ -863,20 +854,6 @@ def load_weights(self, weights: dict) -> None:
863854
module_weights[param_name].to(self.model_config.torch_dtype)
864855
)
865856

866-
# Default any VSA gates not loaded from the checkpoint: G_c=0, G_f=1
867-
# (preserves dense behavior at sparsity=0).
868-
for name, module in self.named_modules():
869-
if not isinstance(module, WanBlock):
870-
continue
871-
if module.to_gate_compress is not None:
872-
gate_path = f"{name}.to_gate_compress" if name else "to_gate_compress"
873-
if gate_path not in loaded_linears:
874-
module.init_gate_compress_zero()
875-
if module.to_gate_fine is not None:
876-
gate_path = f"{name}.to_gate_fine" if name else "to_gate_fine"
877-
if gate_path not in loaded_linears:
878-
module.init_gate_fine_default()
879-
880857
def post_load_weights(self) -> None:
881858
"""Call post_load_weights on all Linear modules and convert embedders to target dtype."""
882859
# Convert condition_embedder components to target dtype

tensorrt_llm/_torch/visual_gen/pipeline_loader.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323

2424
from tensorrt_llm._torch.autotuner import autotune
2525
from tensorrt_llm._torch.models.modeling_utils import MetaInitMode
26+
from tensorrt_llm._torch.visual_gen.cute_dsl_kernels.blackwell.video_sparse_attention import (
27+
CUTE_AVAILABLE,
28+
)
2629
from tensorrt_llm.llmapi.utils import download_hf_model
2730
from tensorrt_llm.logger import logger
2831
from tensorrt_llm.visual_gen.args import VisualGenArgs
@@ -225,8 +228,6 @@ def load(
225228
and _sa_cfg is not None
226229
and getattr(_sa_cfg, "algorithm", None) == "vsa"
227230
):
228-
from .cute_dsl_kernels.blackwell.video_sparse_attention import CUTE_AVAILABLE
229-
230231
kernel_path = "CuTe DSL block-sparse" if CUTE_AVAILABLE else "dense SDPA fallback"
231232
logger.info(
232233
f"Attention backend: CUTEDSL (algorithm=vsa, "

0 commit comments

Comments
 (0)