--- layout: default title: Qwen3-VL Numerical Parity permalink: /vision-encoder-parity/ ---

Qwen3-VL Numerical Parity

Qwen3-VL forced CKE to treat numerical behavior, execution schedules, cache transitions, and position semantics as explicit compiler contracts. This page records what failed, how X-ray attribution evolved, what is proven, and what remains open.

Status on July 14, 2026: the Q8_0 vision encoder is byte-exact against llama.cpp on the inspected 1008 x 16384 prefixes. Fresh, source-fingerprinted production runs pass 128 generated tokens for the second OCR fixture and the public Fake 2 fixture. The first OCR fixture reproducibly diverges at decoder step 20. Full replay fails at the same step, isolating shared decoder arithmetic rather than persistent cache state. The 5-, 10-, and 40-image gates are intentionally paused until that defect is fixed.

Evidence, Not A Single Parity Label

Qwen3-VL parity has several independent levels. Passing one does not imply the next.

LevelQuestionRequired evidence
Vision geometryAre the same patches and visual rows produced?Grid, prefix rows, embedding width, patch order
Encoder valuesIs every visual-prefix value identical?Elementwise comparison and byte hash
Mixed prefillAre visual and text segments executed with the same positions and cache transitions?Segment trace, cache metadata, logits
Full replayDoes recomputing the complete prefix produce the same next token?Teacher-forced ranking and logits
Persistent decodeDoes incremental KV-cache execution stay aligned?Token trace through EOS plus cache-state attribution
ApplicationDoes OCR behavior remain aligned across varied images?Multi-image output and accuracy sweep

Current Multi-Image Sweep

FixtureGeometryEncoderDecoder result
OCR fixture 128 x 36, 1008 rowsInspected prefix exactFirst top-1 mismatch at step 20; full replay also fails
OCR fixture 236 x 28, 1008 rowsInspected prefix exact128 / 128 top-1 tokens
Public Fake 2 fixture36 x 28, 1008 rowsInspected prefix exact128 / 128 top-1 tokens
Remaining OCR corpusVariedNot promoted5-, 10-, and 40-image gates pending

Top-1 equality is a behavioral gate, not a claim that every decoder logit is byte-exact. The landscape run matched all 128 selected tokens while its minimum logits cosine was approximately 0.9504. Close rankings can hide numerical drift until a later prompt or image changes the margin. For that reason the gate records cosine, RMSE, top-k overlap, margins, full replay, and the generated token trace.

Why An Ordinary Qwen3 Decoder Was Not Enough

Qwen3-VL reuses a Qwen-like text transformer, but its runtime contract is not simply vision_encoder -> ordinary_Qwen3_decode. The decoder must consume and preserve multimodal state that a text-only Qwen3 path does not have.

The core decoder weights may be Qwen3-shaped, but the bridge, execution schedule, position contract, deepstack injection, and cache lifecycle make Qwen3-VL a distinct stitched circuit.

What Actually Failed

Frontend And Geometry

Resize policy, patch order, tiled position interpolation, and floating-point evaluation order all had to match the reference.

Vision M-RoPE

Rotary width, pair count, split-half partner indexing, axis sections, recurrence, and rounding points were initially conflated.

Reference Math

GGML fp16-table GELU, Q8 activation thresholds, FP16 K/V storage, online softmax, split thresholds, and merge order exposed differences hidden by formula-level tests.

Capability Identity

A legacy FP32 decode function incorrectly advertised the FP16 online/FP32 merge capability. Resolution was deterministic but followed false metadata until the explicit contract provider became authoritative.

Bridge And Decoder State

Combined versus segmented prefill, deepstack placement, semantic versus physical positions, append indices, cache strides, and persistent state all affected the result.

Diagnostic Artifacts

Some Q/K/V dumps used different layouts. Internal llama.cpp dumps disabled flash attention. Stale generated libraries and incomplete runtime hashes produced misleading comparisons.

Harness Semantics

Comparing after both runtimes emitted EOS created a false divergence. Segmented full replay produced multiple valid checkpoint files, and unsupported checkpoint aliases previously triggered long runs that emitted nothing.

Bug Stages And Fix Ownership

StageFailure classObserved exampleCorrect ownerRegression evidence
Reference harnessInvalid comparison windowTokens were compared after both runtimes emitted EOS.Parity runner and bridge stop-token metadataEOS-aware multitoken tests
Reference adapterWrong tensor or backend modeSegmented replay selected the wrong Q/K occurrence; internal llama.cpp dumps could change flash mode.llama.cpp/PyTorch adapter and parity profileOccurrence, alias, layout, and mode-metadata tests
Generated artifactStale or uninstrumented runtimeA cached library omitted imported compiler sources from its fingerprint or lacked CK_PARITY_DUMP.Runtime builder and capture preflightSource-set fingerprint and instrumentation rejection tests
CircuitWrong execution semanticsCombined prefill did not express text_before -> visual -> text_after cache-preserving execution.Circuit schedule, bridge contract, and semantic positionsSegmented-prefill and call-IR tests
Kernel mapFalse capability advertisementA legacy FP32 decode function claimed an FP16 online-softmax/FP32-merge contract.Exact provider capability and resolverZero/ambiguous provider failures and resolved-function assertions
KernelMissing numerical implementationRMSNorm/QK normalization needed an explicit ascending FP64 row-sum provider.Leaf kernel with exact storage, arithmetic, reduction, and threading contractConcrete scalar oracle and production-shape tests
Stateful executionCache or position mismatchPersistent decode can differ from full replay through append index, stride, M-RoPE position, or prior-row corruption.Execution-state X-ray and runtime state APIBounded cache metadata, row-hash, and replay classification tests
Remaining arithmeticSmall seed amplified laterAt image-1 step 20, Q/K first differ near 1.79e-7; post-RoPE K reaches 4.58e-5 and attention first materially fails near 1.47e-4.Same-input primitive oracle, then kernel or capability selected by evidenceNot closed; no tolerance relaxation permitted

The harness is part of the correctness architecture, not disposable test scaffolding. A faulty adapter can falsely accuse a correct kernel, while a permissive harness can conceal a real circuit or reduction defect. Every diagnosed harness failure therefore receives a regression test and enters the same nightly report as kernel and compiler contracts.

Rejected Hypotheses And Negative Results

A rejected experiment is retained as bounded evidence, not treated as wasted work. Its conclusion applies only to the recorded model, tensor boundary, compiler, ISA, and execution mode.

Hypothesis or interventionObserved resultConclusion for this failureWhere it may still matter
Disable AVX-512 VNNINative VNNI and native no-VNNI layer-0 MLP boundaries were identical; forced AVX2 still differed.VNNI was not the source of that encoder drift.Other quant formats, compiler versions, or kernels with different VNNI implementations.
Change the simple AVX2 Q8 dot-product accumulation wrapperThe layer-0 MLP-up metrics did not move.The wrapper was not the first cause; activation quantization or the batched GEMM path remained stronger suspects.Shapes routed directly through the wrapper rather than the batched path.
Force scalar/reference Q4 projection at image-1 step 20The token mismatch and granular metrics were unchanged.The selected Q4 SIMD provider was not responsible for the current step-20 seed.Other layers, shapes, weight formats, ISAs, or exact-input projection failures.
Force reference Q6 projectionThe step-20 result was unchanged.The V projection/Q6 provider was not the current first cause.Later Q6 MLP-down boundaries and different natural inputs.
Force exact M-RoPE, alone and with reference projectionsThe step-20 result was unchanged.The tested M-RoPE implementation was not the remaining top-1 cause.Different position grids, partial rotary widths, section patterns, or BF16 storage contracts.
Attribute the mismatch to persistent KV stateFull replay failed at the same generated step as persistent decode.The remaining failure is shared arithmetic after the replay inputs are reconstructed.Other images and steps where persistent decode fails but full replay matches.
Trust an older strict-mode passSource-set fingerprinting rebuilt the runtime and reproduced the failure.The earlier pass was stale-artifact evidence and cannot support a parity claim.Strict mode remains useful when explicitly labeled and built from the same source identity.
Compare production logits with an internal-dump reference run without mode metadataSome llama.cpp internal captures can disable flash attention.That comparison changes the oracle execution mode and cannot attribute production-flash arithmetic.Unfused-to-unfused diagnostic comparisons when both sides declare the mode explicitly.

Future agents should rerun a rejected path only when at least one recorded condition changes. A new ISA, compiler, model shape, storage dtype, backend mode, or first-divergence boundary is a valid reason. Repeating the same intervention on the same evidence is not.

Why Small Differences Became Large Failures

The difficult bugs were rarely grossly incorrect matrix multiplication. They were differences in when values were rounded, how reductions were partitioned, and which state was reused. A one-ULP input change can cross a Q8 scale or code threshold. The following projection expands that changed code across many outputs, residual layers accumulate it, and a close token ranking can eventually flip even when cosine similarity remains high.

Sequence length and threading also change algorithms. At a KV threshold, a reference can move from one online-softmax reduction to worker-local partials and an ordered merge. Diagnostic capture can disable a production flash path. A test is valid only when backend mode, dtype, thread count, partitioning, runtime libraries, positions, and input bytes are recorded together. CKE's global strict flag is also an execution mode, not proof of correctness: it can select diagnostic implementations that differ from the circuit-resolved production providers.

Three Numerical Lanes

LaneReferencePrimary risksCurrent claim
AVX2 GGUFllama.cppQ8 quantization, AVX2 reduction order, FP16 cache attention, persistent stateEncoder exact on tested fixtures; decoder sweep still open
AVX-512 GGUFllama.cppISA dispatch, VNNI/non-VNNI routing, reduction and cache contractsSeparate Xeon validation is required; results are not inferred from AVX2
BF16 / AMXPyTorchBF16 storage boundaries, SDPA tiling, LayerNorm/GEMM rounding, M-RoPELeaf and practical contracts are strong; full BF16 encoder and generation are not byte-exact

How X-Ray Had To Evolve

The first X-ray implementation compared named tensors and found the first divergent layer or op. That was necessary but insufficient for a stateful multimodal decoder. The current workflow checks execution state before expensive tensor capture.

  1. Verify runtime, model, engine, shim, manifest, compiler, ISA, thread, and attention-mode identity.
  2. Compare prefill segmentation and the actual kernel batch shapes.
  3. Compare physical cache count, append index, strides, and semantic positions.
  4. Verify the newly appended FP16 K/V row round-trips and every previous row remains unchanged.
  5. Hash and compare every valid cache row, reporting the first and worst logical coordinates.
  6. Use full replay at the failing token to classify persistent-state versus shared arithmetic failures.
  7. Bisect sparse layers, then every layer in the failing interval, then internal op checkpoints.
  8. Replay identical input bytes through the suspected quantizer or kernel before changing production math.
Current varied-image classification: exact encoder prefixes were established for four inspected fixtures. Fresh, fingerprinted production runs pass 128 tokens for the second OCR image and the public Fake 2 fixture. The first OCR image has a reproducible shared-arithmetic mismatch at generated step 20: persistent and full replay agree with each other but not llama.cpp. An older strict-mode pass was invalidated after source-set hashing forced the stale decoder runtime to regenerate. Granular replay now shows Q/K/V projection, Q/K normalization, and post-RoPE values remain close, with attention output the first material amplification. Production, strict/debug, flash, and diagnostic unfused results are recorded as distinct modes and are never combined into one parity claim.

Capture Adapter Guardrails

Architecture Hardened By The Investigation

The accepted ownership model is now explicit:

A fix belongs in the circuit when the model requires different graph or schedule semantics, in the kernel map when an existing implementation has a distinct numerical capability, and in a kernel when the required capability does not exist. The DSL should change only to express a generic missing concept, never to special-case Qwen3-VL.

Regression Gates

make test-v8-dsl
make test-v8-qwen3vl
make test-qwen3vl-methodical-parity
make test-v8-vision-kernels
make test-numerical-contracts
make test-attention-f16-split-kv
make llamacpp-parity-full

Artifact-backed encoder, mixed-prefill, teacher-forced, persistent decode, and OCR sweeps remain resource-gated. Missing models or unsupported BF16 hardware must report SKIP, not PASS. Numerical failures are hard failures; performance regressions are reported separately because machine topology and thermal state affect timing.

What Happens Next

  1. Close the first OCR fixture's shared layer-0 attention/reduction mismatch with a same-input production-flash oracle.
  2. Rerun the first five fixtures through at least 128 tokens and EOS where bounded.
  3. Expand to ten images only after the five-image gate is clean.
  4. Run the full 40-image encoder, mixed-prefill, persistent-decode, and OCR sweep.
  5. Publish exact artifacts, negative results, compiler and ISA identity, and application accuracy.
  6. Resume performance tuning only after correctness remains green.

Bottom Line

Qwen3-VL was difficult because correctness spans more than kernels and more than a tensor graph. It spans image geometry, dtype boundaries, evaluation order, execution schedules, position spaces, cache transitions, backend modes, and persistent state. X-ray made those contracts observable and converted repeated manual debugging into a bounded first-divergence process. The encoder evidence is now strong, but the project will not call end-to-end parity complete until the varied-image persistent-decode and OCR gates pass.

Image
100% | |
Scroll to zoom | Drag to pan | W/H to fit | 0 to reset | ESC to close