Repository navigation
Support int16 in vision quantized_layer_norm (#24094) - #24094
mvartani-meta wants to merge 3 commits into
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/24094
Note: Links to docs will display an error until the docs builds have been completed. ✅ No FailuresAs of commit 3bc9a24 with merge base 2c3e231 ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
@mvartani-meta has exported this pull request. If you are a Meta employee, you can view the originating Diff in D126953450. |
This PR needs a
|
5f820ca to
a1a7d96
Compare
Summary: The vision quantized_layer_norm kernel only handled uint8 and int8; int16 input aborted at its ET_CHECK_MSG. It also had the same precision problems as the HiFi and generic kernels: - int32 accumulators, which overflow for int16 because one squared value can reach 2^30. - An E[x^2] - E[x]^2 variance, which cancels catastrophically when the mean is large compared to the spread. This kernel is registered for Cadence Vision builds through functions_vision.yaml. This change closes the last int16 gap among the Cadence layer norm kernels. Changes: - Add an int16 (Short) branch to both overloads. - Accumulate in int64 for 16-bit types; 8-bit keeps 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. The per-row mean and variance stay in double as before. - Declare both kernels in vision/operators/operators.h. Reviewed By: DrJessop Differential Revision: D126953450
Summary: The vision quantized_layer_norm kernel only handled uint8 and int8; int16 input aborted at its ET_CHECK_MSG. It also had the same precision problems as the HiFi and generic kernels: - int32 accumulators, which overflow for int16 because one squared value can reach 2^30. - An E[x^2] - E[x]^2 variance, which cancels catastrophically when the mean is large compared to the spread. This kernel is registered for Cadence Vision builds through functions_vision.yaml. This change closes the last int16 gap among the Cadence layer norm kernels. Changes: - Add an int16 (Short) branch to both overloads. - Accumulate in int64 for 16-bit types; 8-bit keeps 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. The per-row mean and variance stay in double as before. - Declare both kernels in vision/operators/operators.h. Reviewed By: DrJessop Differential Revision: D126953450
a1a7d96 to
dc6a0a8
Compare
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
Summary: The generic quantized_layer_norm kernel has the same int16 gap as the HiFi kernel fixed earlier in this stack. The generic kernel is the portable implementation used on CPU and on Xtensa cores that have no backend-specific layer norm kernel. Before this change, both overloads dispatched with ET_FORALL_CADENCE_QUANTIZED_TYPES, so int16 fell through to an ET_DCHECK_MSG that compiles out in release builds and left the output unwritten. The statistics also used int32 accumulators, which overflow for int16 because one squared value can reach 2^30. The variance was formed as E[x^2] - E[x]^2, which cancels catastrophically when the mean is large compared to the spread. This applies the same fix as the HiFi kernel: - Dispatch both overloads with ET_FORALL_CADENCE_QUANTIZED_TYPES_WITH_INT16. - Accumulate in int64 for 16-bit types; 8-bit keeps 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. The per-row mean and variance stay in double as before. - Add a gtest with the same hand-computed cases as the HiFi test. Reviewed By: DrJessop Differential Revision: D126951724
Summary: The vision quantized_layer_norm kernel only handled uint8 and int8; int16 input aborted at its ET_CHECK_MSG. It also had the same precision problems as the HiFi and generic kernels: - int32 accumulators, which overflow for int16 because one squared value can reach 2^30. - An E[x^2] - E[x]^2 variance, which cancels catastrophically when the mean is large compared to the spread. This kernel is registered for Cadence Vision builds through functions_vision.yaml. This change closes the last int16 gap among the Cadence layer norm kernels. Changes: - Add an int16 (Short) branch to both overloads. - Accumulate in int64 for 16-bit types; 8-bit keeps 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. The per-row mean and variance stay in double as before. - Declare both kernels in vision/operators/operators.h. Reviewed By: DrJessop Differential Revision: D126953450
dc6a0a8 to
3bc9a24
Compare
Summary:
The vision quantized_layer_norm kernel only handled uint8 and int8; int16 input aborted at its ET_CHECK_MSG. It also had the same precision problems as the HiFi and generic kernels:
This kernel is registered for Cadence Vision builds through functions_vision.yaml. This change closes the last int16 gap among the Cadence layer norm kernels.
Changes:
Reviewed By: DrJessop
Differential Revision: D126953450