Skip to content

Use the query dtype's lowest finite value for the causal attention mask - #2992

Open
Subhajit Mitra (SubhajitMitra-GH) wants to merge 1 commit into
microsoft:mainfrom
SubhajitMitra-GH:fix-causal-attention-mask-dtype-min
Open

Use the query dtype's lowest finite value for the causal attention mask#2992
Subhajit Mitra (SubhajitMitra-GH) wants to merge 1 commit into
microsoft:mainfrom
SubhajitMitra-GH:fix-causal-attention-mask-dtype-min

Conversation

@SubhajitMitra-GH

Copy link
Copy Markdown

_causal_attention_mask fills masked positions with -inf. The boolean mask path was already moved to the dtype's lowest finite value in #2654 (issue #2561), following the ONNX Runtime recommendation, but the causal path — which is_causal=True routes through — still emits infinities.

Note that is_causal=True produces a float mask, so it is dispatched to _aten_scaled_dot_product_attention_float_mask_onnx, which has no IsNaN guard (unlike the boolean path). That makes the -inf here more exposed than in the masked path.

Change

attn_mask = op.Where(
    op.Equal(attn_mask, op.Constant(value_float=0.0)),
    op.Constant(value=ir.tensor(query.dtype.min, dtype=query.dtype)),
    op.Constant(value=ir.tensor(0.0, dtype=query.dtype)),
)

The constants are built in the query dtype directly rather than created in float32 and cast down. This matters: casting float32's lowest value to float16 overflows back to -inf, which would defeat the purpose. Building them in the query dtype also makes the trailing op.CastLike(attn_mask, query) redundant, so it is removed.

Before / after

Exported constant for the causal mask, torch.nn.functional.scaled_dot_product_attention(..., is_causal=True):

dtype before after
float32 -inf -3.4028235e+38
float16 -inf -65504.0

Testing

Adds a parameterized regression test over float32 and float16 asserting the exported causal mask contains no infinities and equals the expected mask. It fails on main and passes with this change.

Numerics are unchanged: the existing ops_test.py -k scaled_dot_product suite passes. The float16 case skips assert_onnx_program because float16 attention exceeds its default tolerances on main too (3/64 elements, identical with and without this change), which is unrelated to the mask value under test.


Disclosure: this patch was written with the help of an AI coding assistant. I have reviewed and tested the change myself and will respond to review feedback here directly.

`_causal_attention_mask` filled masked positions with `-inf`. The boolean
mask path was already moved to `dtype.min` in microsoft#2654 (issue microsoft#2561) following
the ONNX Runtime recommendation, but the causal path, which `is_causal=True`
routes through, still emitted infinities.

The constants are now built in the query dtype directly instead of being
created in float32 and cast down: casting float32's lowest value to float16
overflows back to `-inf`, which would defeat the purpose. This makes the
trailing `CastLike` redundant, so it is removed.

Adds a regression test asserting the exported causal mask contains no
infinities and matches the expected mask for float32 and float16.
@SubhajitMitra-GH

Copy link
Copy Markdown
Author

@justinchuby
Justin Chu (justinchuby) requested review from Ti-Tai Wang (titaiwangms) and a lite review from Copilot and removed request for Copilot August 18, 2026 00:58

@justinchuby Justin Chu (justinchuby) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@SubhajitMitra-GH

Copy link
Copy Markdown
Author

@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.63%. Comparing base (ab2b5f4) to head (b6af6c4).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2992      +/-   ##
==========================================
- Coverage   72.63%   72.63%   -0.01%     
==========================================
  Files         265      265              
  Lines       32208    32207       -1     
  Branches     3042     3042              
==========================================
- Hits        23395    23394       -1     
  Misses       7779     7779              
  Partials     1034     1034              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@SubhajitMitra-GH

Copy link
Copy Markdown
Author

Hey I see there are three tests failing do you want me to fix those or thats okay?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

2 participants