Skip to content

[ET-VK] Clamp the tanh argument in the gelu shader - #22324

Open
msluszniak wants to merge 1 commit into
pytorch:mainfrom
msluszniak:ms/vulkan-gelu-clamp
Open

[ET-VK] Clamp the tanh argument in the gelu shader#22324
msluszniak wants to merge 1 commit into
pytorch:mainfrom
msluszniak:ms/vulkan-gelu-clamp

Conversation

@msluszniak

@msluszniak msluszniak commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #22323.

The gelu shader evaluates the tanh approximation with an unclamped argument. That argument grows cubically in the input, so x = -13.24 already yields -93.4, and a driver that computes tanh(y) as (e^y - e^-y) / (e^y + e^-y) overflows fp32 at |y| > ~88 and returns inf/inf = NaN.

The tanh op in this same file already clamps to +/-15 for exactly this reason. This change makes gelu do the same.

The clamp costs no accuracy: 1 - tanh(15) = 1.9e-13, well below fp32 epsilon, so the output is bit-identical for every input that gets clamped.

Verification

Whisper-tiny encoder, Vulkan delegate, Samsung Galaxy S10+ (Mali-G76), against a CPU reference:

before after
NaN elements in output 576000 / 576000 0
cosine vs reference n/a 0.99999702
max abs deviation n/a 3.97e-02
distinct outputs over 10 runs 1 (all NaN) 1 (all correct)

Before the fix the failure is silent: the runner reports success and normal per-iteration timings while returning an all-NaN tensor.

cc @digantdesai @freddan80 @per @zingo @oscarandersson8218 @mansnils @Sebastian-Larsson @robell @rascani

@pytorch-bot

pytorch-bot Bot commented Aug 30, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/22324

Note: Links to docs will display an error until the docs builds have been completed.

⚠️ 16 Awaiting Approval

As of commit 11bac85 with merge base c27baa8 (image):

AWAITING APPROVAL - The following workflows need approval before CI can run:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 30, 2026
@github-actions

Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

@github-actions github-actions Bot added ciflow/trunk module: arm Issues related to arm backend ciflow/docker Trigger docker-builds to rebuild and push the CI images for this PR labels Aug 30, 2026
@pytorch-bot

pytorch-bot Bot commented Aug 30, 2026

Copy link
Copy Markdown

The following ciflow label(s) have been added but CI has not been triggered yet because the workflows are awaiting approval:

  • ciflow/trunk
  • ciflow/docker

Once a maintainer approves the workflows (scroll to the bottom of the PR page), the corresponding CI jobs will be triggered automatically. Please ping one of the reviewers if you do not have access to approve and run workflows.

1 similar comment
@pytorch-bot

pytorch-bot Bot commented Aug 30, 2026

Copy link
Copy Markdown

The following ciflow label(s) have been added but CI has not been triggered yet because the workflows are awaiting approval:

  • ciflow/trunk
  • ciflow/docker

Once a maintainer approves the workflows (scroll to the bottom of the PR page), the corresponding CI jobs will be triggered automatically. Please ping one of the reviewers if you do not have access to approve and run workflows.

The gelu shader evaluates the tanh approximation with an unclamped
argument. For an input of x the argument is

    sqrt(2/pi) * (x + 0.044715 * x^3)

which grows cubically, so x = -13.24 already yields -93.4. A driver
that evaluates tanh as (e^y - e^-y) / (e^y + e^-y) overflows fp32 at
|y| > ~88 and returns inf/inf = NaN. On a Mali-G76 this makes the
Whisper encoder emit NaN from conv2 for exactly the two activations
below -13, and the first LayerNorm then propagates them across the
whole tensor.

The tanh op in this same file already clamps to +/-15 for this reason;
gelu now does the same. The clamp is numerically free: 1 - tanh(15) is
1.9e-13, well below fp32 epsilon, so the result is bit-identical for
every input that gets clamped.
@msluszniak
msluszniak force-pushed the ms/vulkan-gelu-clamp branch from fbfdafc to 11bac85 Compare August 30, 2026 09:17
@msluszniak
msluszniak requested a review from SS-JIA as a code owner August 30, 2026 09:17
@msluszniak

Copy link
Copy Markdown
Contributor Author

Sorry guys, my fault with the original push.

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

Labels

ciflow/docker Trigger docker-builds to rebuild and push the CI images for this PR ciflow/trunk CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. module: arm Issues related to arm backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Vulkan] gelu shader returns NaN for inputs below about -13 (unclamped tanh argument overflows fp32)

2 participants