Skip to content

WidenRowToF32 reads a bf16 RMSNorm gamma at an odd address on two models, and it is the second sanitize-cpu finding #2540

Description

@localai-org-maint-bot

Row: FIX-UNALIGNED-CONSUMERS-2540

Spec: .agents/specs/unaligned-safetensors-consumers.md. Claimed 2026-09-02: the fix repairs the CONSUMERS of unaligned safetensors bytes, so the zero-copy borrow survives.

Was owed by .agents/specs/debtfix-glue-rank-bound-and-repack-device.md under ## Owed; ownership moved to the row above, which fixes it.

vt::cpu::WidenRowToF32 (src/vt/cpu/cpu_matmul_elem.cpp:565-583) reads a bf16 tensor
through const uint16_t*. On two models it is handed an odd address, which is
undefined behaviour and a real misaligned load on any target that does not fix it up in
hardware.

Measured on origin/main 63889449c plus the DEBTFIX branch (which touches none of
the files in either stack), Debug + -fsanitize=address,undefined,
VT_POOL_BYPASS=1. Both binaries abort under the lane's own
-fno-sanitize-recover=all and exit 1 before reporting a single doctest assertion:

src/vt/cpu/cpu_matmul_elem.cpp:577:61: runtime error: load of misaligned address
0x782f0e901907 for type 'const uint16_t', which requires 2 byte alignment
    #0 vt::cpu::WidenRowToF32(vt::DType, void const*, long, float*)  cpu_matmul_elem.cpp:577
    #1 RmsNormKernel                                                 cpu_ops.cpp:557
    #2 vt::RmsNorm(...)                                              ops.cpp:1043
    #3 FusedChainCompositeImpl                                       ops.cpp:1114
    #4 vt::FusedChainComposite(...)                                  ops.cpp:1265
    #5 vt::FusedChain(...)                                           ops.cpp:1299
    #6 vt::FusedChain(...)                                           ops.cpp:1332

and from there through a production entry point on both models:

binary frame 7 onward
test_dots3_note_attn Dots3NoteModel::ForwardDevice (dots3_note_device.cpp:1307) -> ForwardDots3NoteForCausalLM (dots3_note_registry.cpp:137) -> ModelRegistry::Forward (model_registry.cpp:646)
test_muse_glimmer_text RunLayer (muse_glimmer.cpp:298)

The operand is the GAMMA, not the activation. cpu_ops.cpp:557 is
WidenRowToF32(w.dtype, w.data, h, wf.data()) — the loop-invariant RMSNorm weight,
widened once per call. Both call sites reach it with w = ResidentWeight(d, layer.input_layernorm, {H}), so the odd pointer is in what ResidentWeight hands back
for that tensor, not in any scratch buffer. Two addresses seen, ...7cd and ...907,
both odd.

What this is not. It is not the dense_device_glue.h rank overrun (#2435): that one
is fixed, and neither of these stacks contains a file that fix touched. It is a SECOND
independent reason sanitize-cpu (address,undefined) is red, in a different subsystem,
and it was hidden behind the first one because that lane aborts at the first finding and
test_qwen4_exp_layer_loop sorts earlier.

Reproduce:

cmake -S . -B build-sanitize -DVLLM_CPP_BUILD_TESTS=ON -DVLLM_CPP_CUDA=OFF \
      -DVLLM_CPP_SANITIZE='address,undefined'
cmake --build build-sanitize -j 2 --target test_muse_glimmer_text test_dots3_note_attn
VT_POOL_BYPASS=1 UBSAN_OPTIONS=print_stacktrace=1 ./build-sanitize/tests/test_muse_glimmer_text; echo $?
VT_POOL_BYPASS=1 UBSAN_OPTIONS=print_stacktrace=1 ./build-sanitize/tests/test_dots3_note_attn; echo $?

Owed: find where the odd w.data comes from and fix it THERE. A memcpy inside
WidenRowToF32 would silence the report and leave whatever produced an odd bf16 weight
pointer in place, which is the wrong end of the defect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions