UB in to_float callback for I2_S (missing scale param) + 3 more bugs on ARM Ampere Altra
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Accessibilité débutants
- 20/100
- Type d'issue
- Bug
- Clarté
- À clarifier
- Activité
- À l'abandon
- Stack technique
- cmake, cpp
- Domaine
- build-system, machine-learning, performance
Piste de recherche
Commencez par reproduire les résultats ARM avec les commandes et les build flags indiqués dans l’issue, puis inspectez 3rdparty/llama.cpp/ggml/src/ggml.c, CMakeLists.txt et le chemin ARM de ggml-bitnet-mad.cpp. Comparez le chemin gemv de -b 1 avec le chemin gemm de -b 32, y compris le callback I2_S et la configuration dotprod. La tâche est terminée lorsque les problèmes de correction ARM restants sont identifiés et corrigés, et qu’une sortie cohérente est confirmée.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Environment
- Platform: Oracle Cloud Compute A1 Flex (Ampere Altra, armv8.2-a,
asimddppresent in/proc/cpuinfo) - OS: Ubuntu 22.04 LTS
- Compiler: clang 14.0
- Commit: main branch, March 2026
- Build flags:
-DBITNET_ARM_TL1=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_FLAGS="-march=armv8.2-a+fp16+dotprod" - Model:
microsoft/BitNet-b1.58-2B-4T-gguf(ggml-model-i2_s.gguf, 1.2GB) - Python: 3.12 (venv)
System info (from llama-cli output)
NEON = 1 | ARM_FMA = 1 | SVE = 0 | MATMUL_INT8 = 0 | (all x86 = 0)
Problem
With -b 1 (gemv path): model produces real words but completely incoherent output.
With -b 32+ (gemm path for prompt): model produces GGGG garbage for all generated tokens.
# gemv path (-b 1, default in run_inference.py)
$ python run_inference.py -m models/BitNet-b1.58-2B-4T-gguf/ggml-model-i2_s.gguf \
-p "The capital of France is" -n 30 -t 4
The capital of France is offline officially.ai happy collective lower sl ruled m unit proven-for...
# gemm path (-b 32)
$ ./build/bin/llama-cli -m models/BitNet-b1.58-2B-4T-gguf/ggml-model-i2_s.gguf \
-p "Hello, my name is" -n 50 -t 4 -b 32
Hello, my name isGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
Speed is correct (~18 tok/s on 4 ARM cores), model loads without errors.
Bug 1: to_float callback — type mismatch (confirmed, patched)
In 3rdparty/llama.cpp/ggml/src/ggml.c, the type table for GGML_TYPE_I2_S registers dequantize_row_i2_s as a ggml_to_float_t callback, but the signatures do not match:
// Typedef (3 params):
typedef void (*ggml_to_float_t)(const void * x, float * y, int64_t n);
// Actual function (4 params — 4th is the i2 scale):
void dequantize_row_i2_s(const uint8_t * x, float * y, int64_t n, const float i2_scale);
// Bug in type table (ggml.c ~line 1185):
.to_float = (ggml_to_float_t) dequantize_row_i2_s, // scale never passed → UB
The cast silences the compiler but causes undefined behavior — on ARM, the 4th argument register is garbage → i2_scale is random → dequantized weights are garbage.
Applied fix — wrapper in the same translation unit:
// At top of ggml.c:
static void dequantize_row_i2_s_wrapper(const void * vx, float * y, int64_t n) {
const uint8_t * x = (const uint8_t *) vx;
const float i2_scale = ((const float *)(x + (n / 4)))[0];
dequantize_row_i2_s(x, y, n, i2_scale);
}
// In type table:
.to_float = dequantize_row_i2_s_wrapper,
Effect: without this fix → GGGG for all configs. With fix → real words with -b 1 (but still incoherent, see Bug 3).
Bug 2: +dotprod not enabled in CMakeLists for ARM (build issue)
The build system generates -march=armv8.2-a without +dotprod. On ARM Ampere Altra:
- CPU has
asimddp(dotprod SDOT/UDOT) in/proc/cpuinfo - Without
+dotprod,__ARM_FEATURE_DOTPRODis not defined by clang ggml-bitnet-mad.cppfalls to the#elsepath usingvmlal_s8(int16 accumulator)- For vectors of 2560+ elements, int16 accumulator overflows → incorrect results (related to #411)
Verification:
clang -march=armv8.2-a+fp16+dotprod -dM -E - < /dev/null | grep DOTPROD
# → #define __ARM_FEATURE_DOTPROD 1
clang -march=armv8.2-a+fp16 -dM -E - < /dev/null | grep DOTPROD
# → (nothing)
Suggested fix: add +dotprod to CMakeLists.txt for AArch64 targets when CPU supports it, or document it as a required flag.
Bug 3: gemm path (ne11 > 3) produces GGGG on ARM — root cause unknown
When the batch has more than 3 tokens (prompt evaluation with -b 32), the code takes the ggml_gemm_i2_i8_s path instead of ggml_gemv_i2_i8_s. On ARM, this path produces completely wrong output:
# Relevant code path in ggml.c (~line 13268):
if (gemm && (ne11 > 3)) {
if (src0->type == GGML_TYPE_I2_S) {
// gemm path — produces GGGG on ARM
const float * scale = (float *)((uint8_t*)(src0->data) + (ne00 * ne01 / 4));
gemm(...);
for (...) {
tmp[...] = (tmp[...] - act_sums[col]) / (act_scales[col]) * (*scale);
}
}
}
Since prompt tokens are processed via gemm and corrupt the KV cache, all subsequent generated tokens are also garbage.
Workaround: use -b 1 to force all computation through the gemv path (avoids the bug but is slower and still produces incoherent text).
Bug 4: incoherent output even with gemv path (remaining issue)
Even with -b 1 + Bug 1 fix + dotprod enabled, output is semantically incoherent. The model generates real vocabulary tokens but with no semantic coherence:
"The capital of France is offline officially.ai happy collective..."
"Hello, my name is Freedom reduce Dispatch linear Dahl tent corps..."
This persists even with temperature=0 (greedy decoding), suggesting the issue is in the logit distribution rather than sampling. Possible causes:
act_sums(activation zero-point correction) computed incorrectly for ARM- Scale offset wrong for GQA tensors (K/V: [2560, 640] with 5 KV heads vs Q: [2560, 2560])
- Activation quantization (
quantize_row_i8_s) producing incorrect scale values
Steps to reproduce
# 1. Clone and build (Ubuntu 22.04, ARM Ampere)
git clone https://github.com/microsoft/BitNet.git && cd BitNet
git submodule update --init --depth=1
python3 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt
# 2. Build (add +dotprod — not in default CMakeLists)
cmake -S . -B build \
-DBITNET_ARM_TL1=ON \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_FLAGS="-march=armv8.2-a+fp16+dotprod" \
-DCMAKE_CXX_FLAGS="-march=armv8.2-a+fp16+dotprod" \
-DCMAKE_BUILD_TYPE=Release
make -C build -j4
# 3. Download model
huggingface-cli download microsoft/BitNet-b1.58-2B-4T-gguf \
--local-dir models/BitNet-b1.58-2B-4T-gguf
# 4. Test (without Bug 1 fix — GGGG for all batch sizes)
python run_inference.py -m models/BitNet-b1.58-2B-4T-gguf/ggml-model-i2_s.gguf \
-p "The capital of France is" -n 30
# 5. Apply Bug 1 fix to 3rdparty/llama.cpp/ggml/src/ggml.c (see above)
# Rebuild and test — now produces words with -b 1 but still incoherent
Related issues
- #411 — int16 overflow in NEON 1x1 kernel (same root area, different manifestation)
- #195 — ARM inference issues (similar platform)
Hardware confirmation
Tested exclusively on Oracle Cloud Compute A1 Flex (ARM Ampere Altra).
Reports from Reddit/r/LocalLLaMA indicate M1/M2/M3 Mac users achieve coherent output — suggesting the issue may be ARM Ampere-specific or related to the dotprod/vmlal path difference.
- Langage dominant
- C++
- Étoiles
- 40.3k
- Forks
- 3.7k
- Métriques de merge des PR
- Aucune PR mergée en 30 j
Préparer son environnement
Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de microsoft/BitNet
-
Difficulté 2/5 1-3 heures Accessibilité débutants 86/100
-
i2_s SIGSEGVs at n_ubatch >= 32: BLAS backend dequantises by a row stride 4x the real packed rowOuverte
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
-
Difficulté 2/5 1-3 heures Accessibilité débutants 86/100
-
Difficulté 1/5 Moins d'une heure Accessibilité débutants 92/100
-
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
Toutes les issues de microsoft/BitNet
Issues similaires
-
Unconfirmed bug
Difficulté 1/5 Moins d'une heure Accessibilité débutants 88/100
luanti-org/luanti#17605 · 1 commentaire ·
Les mainteneurs répondent en général sous 2 jours
-
area: config area: firmware priority: P2 - medium size: S type: bug
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
Mizithra/ActiveTerrain#16 ·
-
Difficulté 2/5 1-3 heures Accessibilité débutants 84/100
grumpycoders/pcsx-redux#2171 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
Les mainteneurs répondent en général sous 2 jours
-
Difficulté 2/5 1-3 heures Accessibilité débutants 88/100
bytedance/trae-agent#524 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour