Skip to content

Support int16 in HiFi quantized_layer_norm (#24091) - #24091

Merged
meta-codesync[bot] merged 1 commit into
pytorch:mainfrom
mvartani-meta:export-D126939431
Oct 23, 2026
Merged

meta-codesync[bot] merged 1 commit into
pytorch:mainfrom
mvartani-meta:export-D126939431

Conversation

@mvartani-meta

@mvartani-meta mvartani-meta commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary:

The HiFi quantized_layer_norm kernels dispatched with ET_FORALL_CADENCE_QUANTIZED_TYPES, so int16 inputs fell through to ET_DCHECK_MSG. That check compiles out in release builds, which left the output tensor unwritten and produced garbage numerics for int16 models.

Simply widening the dispatch is not enough because the statistics used int32 accumulators. For int16, a single squared value can reach 2^30, so sq_sum overflows after two elements. The variance was also computed as E[x^2] - E[x]^2 in fp32, which cancels catastrophically when the mean is large relative to the spread.

Changes:

  • Dispatch both overloads with ET_FORALL_CADENCE_QUANTIZED_TYPES_WITH_INT16.
  • Accumulate sum and sq_sum in int64 for 16-bit types. 8-bit types keep int32 in the inner loop.
  • Widen to the accumulator type before squaring, so the product cannot overflow int32.
  • Apply the zero-point correction in int64 and compute the variance numerator N*sum(v^2) - sum(v)^2 exactly in integers before converting to float. For 8-bit this is equal or more accurate than before.
  • Declare quantized_layer_norm_out and quantized_layer_norm_per_tensor_out in operators.h and add a gtest.

Reviewed By: DrJessop

Differential Revision: D126939431

@pytorch-bot

pytorch-bot Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

🔗 Helpful Links

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

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

❌ 1 New Failure, 1 Cancelled Job, 4 Unclassified Failures

As of commit 6c2392d with merge base 71a713c (image):

NEW FAILURE - The following job has failed:

UNCLASSIFIED FAILURES - DrCI could not classify the following jobs because the workflow did not run on the merge base. The failures may be pre-existing on trunk or introduced by this PR:

CANCELLED JOB - The following job was cancelled. Please retry:

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 Oct 22, 2026
@meta-codesync

meta-codesync Bot commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

@mvartani-meta has exported this pull request. If you are a Meta employee, you can view the originating Diff in D126939431.

@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.

Summary:

The HiFi quantized_layer_norm kernels dispatched with ET_FORALL_CADENCE_QUANTIZED_TYPES, so int16 inputs fell through to ET_DCHECK_MSG. That check compiles out in release builds, which left the output tensor unwritten and produced garbage numerics for int16 models.

Simply widening the dispatch is not enough because the statistics used int32 accumulators. For int16, a single squared value can reach 2^30, so sq_sum overflows after two elements. The variance was also computed as E[x^2] - E[x]^2 in fp32, which cancels catastrophically when the mean is large relative to the spread.

Changes:
- Dispatch both overloads with ET_FORALL_CADENCE_QUANTIZED_TYPES_WITH_INT16.
- Accumulate sum and sq_sum in int64 for 16-bit types. 8-bit types keep int32 in the inner loop.
- Widen to the accumulator type before squaring, so the product cannot overflow int32.
- Apply the zero-point correction in int64 and compute the variance numerator N*sum(v^2) - sum(v)^2 exactly in integers before converting to float. For 8-bit this is equal or more accurate than before.
- Declare quantized_layer_norm_out and quantized_layer_norm_per_tensor_out in operators.h and add a gtest.

Reviewed By: DrJessop

Differential Revision: D126939431
@meta-codesync meta-codesync Bot changed the title Support int16 in HiFi quantized_layer_norm Support int16 in HiFi quantized_layer_norm (#24091) Oct 22, 2026
mvartani-meta added a commit to mvartani-meta/executorch that referenced this pull request Oct 22, 2026
Summary:

The HiFi quantized_layer_norm kernels dispatched with ET_FORALL_CADENCE_QUANTIZED_TYPES, so int16 inputs fell through to ET_DCHECK_MSG. That check compiles out in release builds, which left the output tensor unwritten and produced garbage numerics for int16 models.

Simply widening the dispatch is not enough because the statistics used int32 accumulators. For int16, a single squared value can reach 2^30, so sq_sum overflows after two elements. The variance was also computed as E[x^2] - E[x]^2 in fp32, which cancels catastrophically when the mean is large relative to the spread.

Changes:
- Dispatch both overloads with ET_FORALL_CADENCE_QUANTIZED_TYPES_WITH_INT16.
- Accumulate sum and sq_sum in int64 for 16-bit types. 8-bit types keep int32 in the inner loop.
- Widen to the accumulator type before squaring, so the product cannot overflow int32.
- Apply the zero-point correction in int64 and compute the variance numerator N*sum(v^2) - sum(v)^2 exactly in integers before converting to float. For 8-bit this is equal or more accurate than before.
- Declare quantized_layer_norm_out and quantized_layer_norm_per_tensor_out in operators.h and add a gtest.

Reviewed By: DrJessop

Differential Revision: D126939431
mvartani-meta added a commit to mvartani-meta/executorch that referenced this pull request Oct 22, 2026
Summary:

The HiFi quantized_layer_norm kernels dispatched with ET_FORALL_CADENCE_QUANTIZED_TYPES, so int16 inputs fell through to ET_DCHECK_MSG. That check compiles out in release builds, which left the output tensor unwritten and produced garbage numerics for int16 models.

Simply widening the dispatch is not enough because the statistics used int32 accumulators. For int16, a single squared value can reach 2^30, so sq_sum overflows after two elements. The variance was also computed as E[x^2] - E[x]^2 in fp32, which cancels catastrophically when the mean is large relative to the spread.

Changes:
- Dispatch both overloads with ET_FORALL_CADENCE_QUANTIZED_TYPES_WITH_INT16.
- Accumulate sum and sq_sum in int64 for 16-bit types. 8-bit types keep int32 in the inner loop.
- Widen to the accumulator type before squaring, so the product cannot overflow int32.
- Apply the zero-point correction in int64 and compute the variance numerator N*sum(v^2) - sum(v)^2 exactly in integers before converting to float. For 8-bit this is equal or more accurate than before.
- Declare quantized_layer_norm_out and quantized_layer_norm_per_tensor_out in operators.h and add a gtest.

Reviewed By: DrJessop

Differential Revision: D126939431
mvartani-meta added a commit to mvartani-meta/executorch that referenced this pull request Oct 22, 2026
Summary:

The HiFi quantized_layer_norm kernels dispatched with ET_FORALL_CADENCE_QUANTIZED_TYPES, so int16 inputs fell through to ET_DCHECK_MSG. That check compiles out in release builds, which left the output tensor unwritten and produced garbage numerics for int16 models.

Simply widening the dispatch is not enough because the statistics used int32 accumulators. For int16, a single squared value can reach 2^30, so sq_sum overflows after two elements. The variance was also computed as E[x^2] - E[x]^2 in fp32, which cancels catastrophically when the mean is large relative to the spread.

Changes:
- Dispatch both overloads with ET_FORALL_CADENCE_QUANTIZED_TYPES_WITH_INT16.
- Accumulate sum and sq_sum in int64 for 16-bit types. 8-bit types keep int32 in the inner loop.
- Widen to the accumulator type before squaring, so the product cannot overflow int32.
- Apply the zero-point correction in int64 and compute the variance numerator N*sum(v^2) - sum(v)^2 exactly in integers before converting to float. For 8-bit this is equal or more accurate than before.
- Declare quantized_layer_norm_out and quantized_layer_norm_per_tensor_out in operators.h and add a gtest.

Reviewed By: DrJessop

Differential Revision: D126939431
mvartani-meta added a commit to mvartani-meta/executorch that referenced this pull request Oct 22, 2026
Summary:

The HiFi quantized_layer_norm kernels dispatched with ET_FORALL_CADENCE_QUANTIZED_TYPES, so int16 inputs fell through to ET_DCHECK_MSG. That check compiles out in release builds, which left the output tensor unwritten and produced garbage numerics for int16 models.

Simply widening the dispatch is not enough because the statistics used int32 accumulators. For int16, a single squared value can reach 2^30, so sq_sum overflows after two elements. The variance was also computed as E[x^2] - E[x]^2 in fp32, which cancels catastrophically when the mean is large relative to the spread.

Changes:
- Dispatch both overloads with ET_FORALL_CADENCE_QUANTIZED_TYPES_WITH_INT16.
- Accumulate sum and sq_sum in int64 for 16-bit types. 8-bit types keep int32 in the inner loop.
- Widen to the accumulator type before squaring, so the product cannot overflow int32.
- Apply the zero-point correction in int64 and compute the variance numerator N*sum(v^2) - sum(v)^2 exactly in integers before converting to float. For 8-bit this is equal or more accurate than before.
- Declare quantized_layer_norm_out and quantized_layer_norm_per_tensor_out in operators.h and add a gtest.

Reviewed By: DrJessop

Differential Revision: D126939431
mvartani-meta added a commit to mvartani-meta/executorch that referenced this pull request Oct 22, 2026
Summary:

The HiFi quantized_layer_norm kernels dispatched with ET_FORALL_CADENCE_QUANTIZED_TYPES, so int16 inputs fell through to ET_DCHECK_MSG. That check compiles out in release builds, which left the output tensor unwritten and produced garbage numerics for int16 models.

Simply widening the dispatch is not enough because the statistics used int32 accumulators. For int16, a single squared value can reach 2^30, so sq_sum overflows after two elements. The variance was also computed as E[x^2] - E[x]^2 in fp32, which cancels catastrophically when the mean is large relative to the spread.

Changes:
- Dispatch both overloads with ET_FORALL_CADENCE_QUANTIZED_TYPES_WITH_INT16.
- Accumulate sum and sq_sum in int64 for 16-bit types. 8-bit types keep int32 in the inner loop.
- Widen to the accumulator type before squaring, so the product cannot overflow int32.
- Apply the zero-point correction in int64 and compute the variance numerator N*sum(v^2) - sum(v)^2 exactly in integers before converting to float. For 8-bit this is equal or more accurate than before.
- Declare quantized_layer_norm_out and quantized_layer_norm_per_tensor_out in operators.h and add a gtest.

Reviewed By: DrJessop

Differential Revision: D126939431
@meta-codesync
meta-codesync Bot merged commit d533adf into pytorch:main Oct 23, 2026
249 of 255 checks passed

This branch was previously deployed

1 inactive deployment
cadence — 6c2392d7 Deployed Oct 22, 2026 by mvartani-meta via hifi-op-test / hifi4 #34413
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. meta-exported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants