MiniMax H3: SageAttention FP8 PV kernels produce noise above ~160k tokens on sm_120
- Dominant language
- Python
- Stars
- 133k
- Forks
- 15.7k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 158
Description
> **Edit 2026-08-09.** Read this, the report below is old.
>
> **This works now on ComfyUI 0.31.1.** 1920x1088, 15 s, sage on via the KJNodes node set to `auto`, 54 min against 94 with sage off. Same sage build as when it broke. Two things changed though, ComfyUI and my text encoder, so I'm not calling it fixed yet. [More here.](https://github.com/Comfy-Org/ComfyUI/issues/15263#issuecomment-5233770925)
>
> **If you're on 0.30.1 or older and getting noise on sm_120, update first.**
>
> **Ignore the workaround I put here on 08-08.** I said to use the KJNodes node on `sageattn_qk_int8_pv_fp16_cuda`. It doesn't work on sm_120, it aborts on the first attention call, and `fp16_triton` throws `cudaErrorIllegalAddress`. `auto` is the only mode that runs on that arch, and it isn't any of the entries under it in the dropdown. [Table.](https://github.com/Comfy-Org/ComfyUI/issues/15263#issuecomment-5223860988) Sorry if anyone tried it.
>
> What it looked like on 0.30.1, counting tokens as `ceil(frames/4) * (W/32) * (H/32)`, all on an RTX PRO 6000 with the bf16 models:
>
> | res | duration | frames | tokens | result |
> |---|---|---:|---:|---|
> | 1920x832 | 15 s | 362 | 142k | clean |
> | 1920x1088 | 12 s | 294 | 151k | clean |
> | 1216x704 (2 pass) | 30 s | 736 | 154k | clean |
> | 1920x1088 | 13 s | 328 | 167k | noise |
> | 1920x832 | 18 s | 447 | 175k | noise |
> | 1920x1088 | 15 s | 362 | 186k | noise |
>
> Clean under about 154k, noise from about 167k, nothing in between. The same 186k render with sage off was always fine, so the wall was never in H3.
>
> **Don't merge the one line fix below.** It turns sage off for H3 everywhere, including Ampere where it works fine. @pepikir's [breakdown](https://github.com/Comfy-Org/ComfyUI/issues/15263#issuecomment-5221531597) is still the best account of what's going on.
>
> The rest is the original report. The `smooth_k` theory in it is dead. The audio VAE bit still holds.
---
### Summary
Running MiniMax H3 with `--use-sage-attention` produces **pure noise in both the video and audio streams**. Not degraded output — noise. The H3 DiT's attention call does not pass `low_precision_attention=False`, so it gets routed to `attention_sage` like any other model, and SageAttention's int8 QK path breaks it completely.
Every comparable model in the tree already opts out. H3 (added in #15224, merged as e2ab36d) appears to be the omission.
### Expected vs actual
- **Expected:** either correct output, or (like LTX) an automatic fallback to PyTorch attention.
- **Actual:** 55 minutes of sampling → noise, no warning, no error.
### Root cause
> ⚠️ Superseded, see the edit note at the top. The opt-out is not missing in any meaningful sense; the kernel selected on sm_120 is the actual fault.
`comfy/ldm/modules/attention.py:550` provides the opt-out:
```python
def attention_sage(q, k, v, heads, mask=None, attn_precision=None, skip_reshape=False, skip_output_reshape=False, **kwargs):
if kwargs.get("low_precision_attention", True) is False or (mask is not None and not SAGE_ATTENTION_SUPPORTS_MASK):
return attention_pytorch(q, k, v, heads, mask=mask, skip_reshape=skip_reshape, skip_output_reshape=skip_output_reshape, **kwargs)
```
Models that use it today:
| File | Line |
|---|---|
| `comfy/ldm/lightricks/model.py` | 405 — comment: *"sageattn mask support is unreliable"* |
| `comfy/ldm/audio/dit.py` | 433, 434, 437 |
| `comfy/ldm/audio/vae_sa3.py` | 141, 142, 145 |
| `comfy/ldm/ace/ace_step15.py` | 244 |
| `comfy/ldm/hunyuan3dv2_1/hunyuandit.py` | 346, 416 |
| `comfy/ldm/sam3/{sam,detector,tracker}.py` | several |
| `comfy/image_encoders/dino3.py` | 97 |
| `comfy/ldm/triposplat/model.py` | 106 |
MiniMax H3 does not — `comfy/ldm/minimax/model.py:181`:
```python
out = optimized_attention(q, k, v, self.heads, mask=None, skip_reshape=True, transformer_options=transformer_options)
```
### Proposed fix (one line)
> ⚠️ **Retracted, don't merge this.** It would disable sage for H3 on every GPU and kernel, including the ones where it works. See the edit note at the top.
```python
out = optimized_attention(q, k, v, self.heads, mask=None, skip_reshape=True,
low_precision_attention=False, transformer_options=transformer_options)
```
All attention backends (`attention_basic`, `attention_sub_quad`, `attention_split`, `attention_xformers`, `attention_pytorch`, `attention_sage`, `attention_flash`) declare `**kwargs`, so this is inert for every non-sage path — verified locally, no behavioural change with sage disabled.
I've applied this locally and it resolves the issue. Happy to open a PR if useful.
### Evidence that the fault is in the DiT, not the VAEs
Worth recording, since it rules out a decode-side explanation:
| Decoder | Attention call | Sage-swapped? |
|---|---|---|
| Video VAE `comfy/ldm/minimax/vae.py:239` | `optimized_attention(...)` | yes |
| Audio VAE `comfy/ldm/minimax/audio_vae.py:247` | `comfy.ops.scaled_dot_product_attention(...)` | **no** |
The audio VAE never imports `optimized_attention`, so `--use-sage-attention` cannot have affected it — yet the audio output was still noise. The audio latent was therefore already corrupt leaving the sampler, placing the fault upstream of both decoders in the DiT's attention.
(This part still holds.)
### Possible contributing factor
> ⚠️ Retracted. @pepikir probed this directly and `smooth_k=True` vs `False` gave identical relative error, so it isn't the trigger.
`comfy/ldm/modules/attention.py:573` hardcodes `smooth_k=False`:
```python
sage_kwargs = {"is_causal": False, "tensor_layout": tensor_layout, "sm_scale": kwargs.get("scale", None), "smooth_k": False}
```
SageAttention's own default is `smooth_k=True`, and channel-wise mean subtraction of K before int8 quantization is what its paper credits for keeping int8 QK accurate. H3's attention (`model.py:156-181`) applies QK-RMSNorm plus a *partial* rope (`rot = rope_freqs.shape[-3] * 2`, 96 of 128 dims rotated), which leaves rotated and unrotated channels with markedly different statistics — the kind of channel-wise outlier structure `smooth_k` exists to handle. Speculative and not instrumented; the opt-out above makes it moot for H3, but it may explain why other models needed the same escape hatch.
### Reproduction
- ComfyUI v0.30.1, torch 2.11.0+cu130, Python 3.13, Windows 11
- RTX PRO 6000 Blackwell (96 GB), `sageattention` installed
- `minimax_h3_fl2va_bf16.safetensors` + `qwen3vl_32b_minimax_h3_bf16.safetensors`
- `MiniMaxH3ImageToVideo` → `BasicGuider` → `SamplerCustomAdvanced` (`res_multistep`, 20 steps), 1920x1088, 362 frames
- Launch with `--fast-disk --use-sage-attention` → noise.
- Identical graph and seed without `--use-sage-attention` → correct output.
Same seed both runs, so the two are directly comparable.
Contributor guide
Research direction
Reproduce the MiniMax H3 workflow on an RTX PRO 6000 with ComfyUI 0.30.1 and sage attention, then compare it with 0.31.1. Read comfy/ldm/modules/attention.py around lines 550-573 and comfy/ldm/minimax/model.py around lines 156-181; done means identifying the sm_120 kernel behavior and confirming a reliable clean-output path without regressing supported GPUs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, pytorch
- Domain
- machine-learning, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 38/100