Skip to content

Check quantized embedding qparam dtypes against how the kernels read them - #23912

Open
Shakhtar-Sankur wants to merge 2 commits into
pytorch:mainfrom
Shakhtar-Sankur:quantized-embedding-qparam-dtypes
Open

Shakhtar-Sankur wants to merge 2 commits into
pytorch:mainfrom
Shakhtar-Sankur:quantized-embedding-qparam-dtypes

Conversation

@Shakhtar-Sankur

@Shakhtar-Sankur Shakhtar-Sankur commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The reference ops in exir/passes/_quant_patterns_and_replacements.py require weight_zero_points to share weight_scales' dtype, and the variants without a dtype argument return the scales' dtype. The kernels checked the zero points against the output dtype instead (while reading them as the scales' type), and the .out variants read the scales as the output type without checking it. So:

  • embedding_byte/2bit/4bit.dtype_out with fp16 scales and zero points and a fp32 output (valid per the reference) aborts;
  • fp32 zero points with fp16 scales are accepted and reinterpreted as fp16;
  • embedding_byte/2bit/4bit.out with fp16 scales and a fp32 output reads past the end of the scales (AddressSanitizer: heap-buffer-overflow).

This checks the zero points against the scales, and the scales against the output in the .out variants.

Related to #23677 (index bounds check in the same kernels); the two changes are independent and merge cleanly in either order.

Test plan

Built quantized_kernels_test with CMake (Debug, -fsanitize=address).

  • With the change: 86/86 quantized kernel tests pass (88/88 together with Add index bounds check to 2-bit and 4-bit quantized embedding kernels #23677).
  • Without it, all 6 new tests fail: the two fp16-qparams/fp32-output tests abort, the two zero-point mismatch tests fail to die, and the two .out mismatch tests die in AddressSanitizer (heap-buffer-overflow) instead of the dtype check.
  • Python reference cross-check: embedding_byte.dtype with fp16 scales and zero points and dtype=float32 returns [[3.5, 2], [5.5, 13]], the value the new test expects; fp32 zero points with fp16 scales raise an assertion.

Authored with AI assistance. I reviewed the change and ran the tests myself.

cc @larryliu0820 @manuelcandales @JakeStevens @nil-is-all

@pytorch-bot

pytorch-bot Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

🔗 Helpful Links

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

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

⚠️ 17 Awaiting Approval

As of commit e297841 with merge base 8ecf0fb (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 Oct 16, 2026
@Shakhtar-Sankur

Copy link
Copy Markdown
Contributor Author

@pytorchbot label "release notes: ops & kernels"

@pytorch-bot pytorch-bot Bot added the release notes: ops & kernels Changes to the opset and any new / changed kernel implementations label Oct 16, 2026
@executorch-triage executorch-triage Bot added the community: contribution PRs coming from community (excluding hardware partners) label Oct 16, 2026
@rascani
rascani requested a review from metascroy October 16, 2026 14:47
@nil-is-all nil-is-all added the module: kernels Issues related to kernel libraries and utilities, and code under kernels/ label Oct 16, 2026
@nil-is-all

Copy link
Copy Markdown
Contributor

@Shakhtar-Sankur could you rebase and ping for review? Thanks

@Shakhtar-Sankur
Shakhtar-Sankur force-pushed the quantized-embedding-qparam-dtypes branch from f79810b to 460b8b9 Compare October 21, 2026 19:17
@Shakhtar-Sankur

Copy link
Copy Markdown
Contributor Author

@nil-is-all rebased onto main (it now sits on top of #23677), thanks. @JakeStevens @metascroy could you take a look when you have a moment?

@JakeStevens

Copy link
Copy Markdown
Contributor

The fake implementations for the non-dtype embedding_2bit and embedding_4bit return torch.nn.Embedding(...)(indices). That is always fp32, whatever the scales' dtype. instead, return weight_scales.dtype

…them

The reference ops (exir/passes/_quant_patterns_and_replacements.py) require
weight_zero_points to have the same dtype as weight_scales, and the variants
without a dtype argument return the scales' dtype. The kernels instead read
the zero points as the scales' type but checked them against the output
dtype, and the .out variants read the scales as the output type without
checking it.

As a result, embedding_byte/2bit/4bit.dtype_out aborted on fp16 scales and
zero points with a fp32 output, which the reference accepts, and accepted
fp32 zero points with fp16 scales, reading them as fp16. The .out variants
with fp16 scales and a fp32 output read past the end of the scales.

Check the zero points against the scales, and in the .out variants check the
scales against the output. The new tests for the 8-bit and 4-bit ops (2-bit
shares the 4-bit code) fail without the change.
The fake kernels of embedding_2bit and embedding_4bit (the variants
without a dtype argument) returned torch.nn.Embedding(...)(indices), which
is always fp32. The reference ops return weight_scales.dtype, so with fp16
or bf16 scales export recorded fp32 for a tensor that is fp16 or bf16 at
run time.

Return weight_scales.dtype from both fakes. The new test compares each fake
with its reference op for fp16, bf16 and fp32 scales; the fp16 and bf16
cases fail without the change.
@Shakhtar-Sankur

Copy link
Copy Markdown
Contributor Author

Thanks @JakeStevens, good catch. The fake kernels for embedding_2bit and embedding_4bit now return weight_scales.dtype, matching the reference ops, and test_embedding_xbit_fake_dtype checks each fake against its reference op for fp16, bf16 and fp32 scales (the fp16 and bf16 cases fail without the fix).

@nil-is-all I've rebased on main. Ready for review, thanks!

This branch has not been deployed

No deployments
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. community: contribution PRs coming from community (excluding hardware partners) module: kernels Issues related to kernel libraries and utilities, and code under kernels/ release notes: ops & kernels Changes to the opset and any new / changed kernel implementations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants