Skip to content

[Bug]: qwen36 tier: an int8 container never promotes on the decode path (QT_NO_WARMSTART=1 stays at 0 uploads) #1391

Description

@crichalchemist

Commit or version

dev at f18a54a (also reproduced on the #1338 branch, which is dev plus the Vulkan tier).

Environment

Observed through the Vulkan tier on a Radeon Pro 580 under MoltenVK (macOS 13 x86_64), but the gate is in the engine before any backend is involved, so the CUDA tier is affected identically.

Reproduction steps

ci.yml's Qwen3.6 tiny fixture, converted at --ebits 8 (int8 experts), engine built with a tier backend, and a 400-token reference so the run outlives the uploader's first copy (a 16-token run ends before anything could upload in either mode, which hides the difference):

python3 tools/make_qwen36_tiny.py --out qwen36_tiny --ref-mode full --emit-ref qwen36_tiny/ref_full.json
python3 tools/convert_qwen36.py --model qwen36_tiny --out qwen36_tiny_c --ebits 8
COLI_DENSE_I8=0 SNAP=qwen36_tiny_c COLI_VULKAN=1 VK_EXPERT_GB=auto COLI_TIMERS=1 QT_NO_WARMSTART=1 ./qwen36 8 8 ref_long.json

Then the same fixture converted at --ebits 4, same command.

Expected behavior

With QT_NO_WARMSTART=1 the tier fills on first use for either container format, as it does for int4, and as the warmstart already does for int8 since #1331/#1334.

Actual behavior and logs

int8 container, 400 tokens, no warmstart: nothing is ever enqueued, the tier reports itself active and sits at 0 % for the life of the process.

[qtier] resident 0/64 experts | uploads 0 | miss(CPU) 6464 | q_skips 0
[qtier] VRAM hit rate: 0.0 % | LFRU swaps 0

int4 container, same command:

[qtier] resident 64/64 experts | uploads 64 | miss(CPU) 901 | q_skips 126
[qtier] VRAM hit rate: 86.1 % | LFRU swaps 0

Cause: both decode-path call sites in c/qwen36.c only offer an expert to the tier when it has a packed int4 copy:

if (e->g4) qt_note(layer, idx[kk], e->g4, e->u4, e->d4, e->gs, e->us, e->ds);      // ~line 1969
if (ps->g4) qt_note(lnext, eid, ps->g4, ps->u4, ps->d4, ps->gs, ps->us, ps->ds);   // ~line 2374, prefetch

On an int8 container e->g4 is NULL (there is nothing to pack), so qt_note is never called. The warmstart was taught to hand the tier e->g in that case (wg = expert_is_int4 ? e->g4 : e->g); the decode path was not. Same shape as #1331, one call site over.

Fix shape: mirror the warmstart at both call sites, expert_is_int4 ? e->g4 : e->g (the tier accepts int8 pointers since #1334 and refuses grouped-scale int8 at init). A test in the shape of test_qwen36_tier_int8_engine.c, driving the decode path on an in-memory int8 model against the fake backend and asserting fake_uploads > 0, would fail today and pass with the change. Happy to send that if the reading is agreed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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