Fix #547: scalar fallback for i2_s dot kernels on x86 without AVX2#580
Open
amitpatole wants to merge 1 commit into
Open
Fix #547: scalar fallback for i2_s dot kernels on x86 without AVX2#580amitpatole wants to merge 1 commit into
amitpatole wants to merge 1 commit into
Conversation
…thout AVX2
The ggml_vec_dot_i2_i8_s_* kernels were gated on
`#if defined(__AVX2__) ... #elif defined(__ARM_NEON)` with no other
branch. On x86 CPUs without AVX2 (e.g. Ivy Bridge, or any build with
-DGGML_AVX2=OFF) neither branch is compiled, so the kernels have an
empty body and never write the output `s`. The uninitialized result
makes i2_s inference emit a garbage token loop ("GGGG..."), while
non-BitNet quants like Q2_K work fine on the same hardware.
Add a portable scalar `#else` fallback to all four kernels
(_1x1, _1xN, _Nx1, _1x4_32W) via a shared ggml_i2_s_block_dot() helper
that reproduces the AVX2 ternary unpack bit-for-bit (2-bit codes at bit
offsets 6/4/2/0 paired with activation sub-blocks 0/1/2/3). Also define
QK_I2_S for the no-SIMD case so the block layout matches.
Verified:
- tests/test-i2s-scalar-fallback.cpp cross-checks the scalar fallback
against the exact AVX2 kernels over 7163 random cases: bit-exact.
- Built BitNet with -DGGML_AVX2=OFF (AVX=1, AVX2=0, MATMUL_INT8=0) and
ran BitNet-b1.58-2B-4T i2_s:
before: "The capital of France is!!!!!!!!!!!!!..." (garbage)
after: "The capital of France is Paris. Paris is a city known for
its rich history, culture, and architecture..." (coherent)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author
|
@microsoft-github-policy-service agree |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #547 —
i2_sinference produces garbage output (a repeating token loop such asGGGG…/!!!!…) on x86 CPUs without AVX2 (e.g. Ivy Bridge, or any build configured with-DGGML_AVX2=OFF), while standard quants likeQ2_Kwork fine on the same hardware.Root cause
The four
ggml_vec_dot_i2_i8_s_*kernels insrc/ggml-bitnet-mad.cppare gated as:On an x86 target without AVX2, neither branch is compiled, so each kernel has an empty body and never writes its output
s. The uninitialized dot-product results propagate into the softmax, and generation collapses to a constant token. This matches the reporter's environment exactly (AVX = 1 | AVX2 = 0 | MATMUL_INT8 = 0).Fix
Add a portable scalar
#elsefallback to all four kernels (_1x1,_1xN,_Nx1,_1x4_32W) through a shared helper:It reproduces the AVX2 ternary unpack bit-for-bit: 2-bit weight codes are extracted at bit offsets 6/4/2/0 and paired with activation sub-blocks 0/1/2/3 (32 lanes each), summed into
int32.QK_I2_Sis also defined for the no-SIMD case so the 128-element block layout is interpreted identically. No behavioural change on AVX2 or NEON targets — the new code only compiles when neither SIMD path is available.Verification
1. Bit-exactness vs AVX2 (unit).
tests/test-i2s-scalar-fallback.cppre-implements the exact AVX2 kernels as ground truth and cross-checks the scalar fallback over 7163 random cases across all four kernels — 0 mismatches.2. End-to-end (real model). Built with
-DGGML_AVX2=OFF(AVX = 1 | AVX2 = 0 | SSSE3 = 1 | MATMUL_INT8 = 0) and ranBitNet-b1.58-2B-4T(ggml-model-i2_s.gguf):The capital of France is!!!!!!!!!!!!!!!!!!!!!!!!…The capital of France is Paris. Paris is a city that is known for its rich history, culture, and architecture. It is also a major center for art, fashion, and cuisine…Notes
to_floatUB in fix: wrap dequantize_row_i2_s to_float callback to fix UB on ARM #469/fix(i2_s): resolve to_float UB + guard BLAS I2_S routing #533, NEON int16 overflow in fix: prevent int16 overflow in NEON non-dotprod fallback path #459/Fix Word Salad (Tensor Corruption) on ARM Devices for i2_s Quantization #551) — this addresses a distinct, currently-unhandled build configuration.