hpcaitech/Open-Sora · error · ValueError

`fuse_qkv_projections()` is not supported for models having

Error message

`fuse_qkv_projections()` is not supported for models having added KV projections.

What it means

fuse_qkv_projections merges each Attention module's query/key/value projections into a single fused matrix for faster inference. This optimization is impossible when any attention processor is an 'Added-KV' variant (extra key/value projections), so the method scans self.attn_processors and aborts if any class name contains 'Added'.

Source

Thrown at opensora/models/hunyuan_vae/autoencoder_kl_causal_3d.py:590

        return (dec, posterior, z)

    # Copied from diffusers.models.unet_2d_condition.UNet2DConditionModel.fuse_qkv_projections
    def fuse_qkv_projections(self):
        """
        Enables fused QKV projections. For self-attention modules, all projection matrices (i.e., query,
        key, value) are fused. For cross-attention modules, key and value projection matrices are fused.

        <Tip warning={true}>

        This API is 🧪 experimental.

        </Tip>
        """
        self.original_attn_processors = None

        for _, attn_processor in self.attn_processors.items():
            if "Added" in str(attn_processor.__class__.__name__):
                raise ValueError("`fuse_qkv_projections()` is not supported for models having added KV projections.")

        self.original_attn_processors = self.attn_processors

        for module in self.modules():
            if isinstance(module, Attention):
                module.fuse_projections(fuse=True)

    # Copied from diffusers.models.unet_2d_condition.UNet2DConditionModel.unfuse_qkv_projections
    def unfuse_qkv_projections(self):
        """Disables the fused QKV projection if enabled.

        <Tip warning={true}>

        This API is 🧪 experimental.

        </Tip>

        """

View on GitHub (pinned to 7ad6a96a13)

Solutions

  1. Skip fuse_qkv_projections for this model variant — it is not supported by design
  2. If added-KV processors were set by mistake, reset to standard processors via set_attn_processor(AttnProcessor()) then fuse
  3. Gate the call: if 'Added' not in str(processor) checks pass for all processors

Example fix

# before
model.fuse_qkv_projections()
# after
has_added_kv = any('Added' in str(p.__class__.__name__) for p in model.attn_processors.values())
if not has_added_kv:
    model.fuse_qkv_projections()
Defensive patterns

Strategy: type-guard

Validate before calling

def can_fuse_qkv(model) -> bool:
    return not any("Added" in str(p.__class__.__name__) for p in model.attn_processors.values())

Type guard

def can_fuse_qkv(model) -> bool:
    return not any("Added" in str(p.__class__.__name__) for p in model.attn_processors.values())

Try / catch

try:
    model.fuse_qkv_projections()
except ValueError as e:
    if "added KV" in str(e):
        pass  # unsupported for this variant; skip fusion
    else:
        raise

Prevention

When it happens

Trigger: Calling model.fuse_qkv_projections() on an autoencoder whose attention layers use AttnAddedKVProcessor (or any processor class with 'Added' in the name), e.g. after set_attn_processor(AttnAddedKVProcessor()).

Common situations: Applying a standard diffusers inference-acceleration snippet (fuse_qkv + torch.compile) to a model variant that uses added-KV attention; fusing after loading a checkpoint with added-KV processors baked in.

Related errors


AI-assisted analysis of hpcaitech/Open-Sora@7ad6a96a13 (2026-08-28). Data as JSON: /api/errors/6434624650a6e26b. Report an issue: GitHub.