Repository navigation
Conversation
…dim (sqliteai#69) Three shapes a container controls that cfg_sane did not bound, each reachable from a manifest (sqliteai#69): - shared_expert_intermediate_size batches the shared expert's gate and up projections into m->ff, sized from max(dense_inter, moe_inter) only. shared 512 over moe 16 writes past the buffer under ASan and runs to completion without it. Flash-Next fits exactly (640 = 640), which is why nothing noticed. - ngram_size 1 makes validate_qwen_tensors divide by (ngram_size - 1) * heads_per_ngram: arm64 sdiv quietly yields 0, x86 idiv raises #DE before the shape check. Bounded to >= 2. - linear_conv_kernel_dim 0 sizes the GDN conv ring as (k - 1) elements: empty ring, negative gdn_conv_range offset. The generic conv_k bound allows 0; Qwen states its own floor. One qwen_refused case per bound in tests/run.sh. Valid-container logits bit-identical (sha256 3e4a4a70... base vs fixed, steps 3,7,11); suite 93 passed / 0 failed / 17 skipped (89 -> 93, the four new refusals). make asan: same single pre-existing QSA failure as base.
…ntainer The shared_inter upper bound this branch added was wrong. It refuses Qwen2-57B-A14B, which ships shared_expert_intermediate_size 20480 against max(intermediate_size 18944, moe_intermediate_size 2560) -- a published checkpoint the guard would lock out. Our own audit of sqliteai#63 found this while reviewing the same bound proposed there, so the bound is withdrawn here. The underlying defect is real, but it is an allocation bug, not a manifest one: the shared expert batches its gate and up projections into m->ff, which was sized from the dense and routed widths only, so a container whose shared width exceeds both writes past the buffer. Flash-Next fits exactly (640 == 640), which is why nothing noticed. m->ff now takes the maximum of the dense, routed and shared widths, so the wide shape loads and decodes. The two other bounds stand and are unchanged: ngram_size >= 2 guards the divide at the PLE width computation, and linear_conv_kernel_dim >= 1 guards the GDN conv ring allocation. Proven, not asserted. tools/make_test_container.py sized the shared-expert tensors from moe_intermediate_size, so a manifest-only edit could never exercise this path; it now follows shared_expert_intermediate_size and takes --shared-inter. With the fix reverted, a decode step over a wide container aborts under AddressSanitizer with a heap-buffer-overflow, WRITE of size 4 past m->ff; with the fix it completes. tests/wide_step.c drives that step through waste_eval with raw token ids, since waste info only reads the manifest and never allocates. Suite: 93 passed, 0 failed.
|
Correcting this branch: the While auditing the same bound in sqliteai#63 I checked it against published configs.
The defect it was aiming at is real, but it is an allocation bug rather than a manifest one. The shared expert batches its gate and up projections into Red-before / green-after, under AddressSanitizer. Two things had to be fixed before the bug was even reachable:
With the allocation fix reverted, that step aborts: With the fix it completes ( The other two bounds stand, unchanged. I re-checked both rather than assuming: The SIGFPE at |
|
Closing this — your branch already carries all three bounds, and in a better form than this PR proposes. Verified against
So both guards this PR adds are already live. The third is the interesting one. The shared-expert bound this PR opened with was wrong, and your branch is right not to carry it. An upper bound on Rebasing onto One thing I could not settle from reading alone and am not claiming: the Withdrawing, no action needed. sqliteai#69 is covered on your branch. |
Closes the three shapes from sqliteai#69 on this branch, one
cfg_sanebound and oneqwen_refusedcase each — the same shape as #1.What is bounded, and the evidence for each
1.
shared_expert_intermediate_size— heap write pastm->ffm->ffis sized frommax(dense_inter, moe_inter)whileqwen_moe_layerbatches the shared expert's gate+up into it atshared_inter. Verified with a tensor-consistent container (shared512 overmoe16, the threeshared_expert.*tensors shaped from 512): base accepts it (rc 0). Marco's ASan trace in sqliteai#69 is the write; the bound isshared_inter <= max(dense_inter, moe_inter), as sqliteai#69 proposes. Flash-Next fits exactly (640 = 640), which is why nothing noticed.2.
ngram_size == 1— x86 SIGFPEReproduced independently before fixing: the ngram=1 container (PLE tensors shaped for the widest legal interpretation so no shape check can refuse it first) loads fine on arm64 (sdiv quietly yields 0) and dies
rc=136(SIGFPE/#DE) on an x86_64 build under Rosetta. Bounded tongram_size >= 2.3.
linear_conv_kernel_dim == 0— negative GDN ring offsetThe generic
conv_k < 0bound permits 0; with KS=0 the conv ring is empty andgdn_conv_rangecomputesring + b * (KS - 1). Qwen states its own floor (>= 1).Evidence
8d5405d):tests/run.shon the fixed tree: 93 passed, 0 failed, 17 skipped (base: 89 — the delta is the four new refusals, all PASS).make asan: 90/1/19 — the single failure (QSA's attention differs from the loops it replaced) is identical on the unmodified base, i.e. pre-existing, not introduced here.3e4a4a70…on base and fixed, steps 3, 7, 11.The suite cases are manifest-only edits in the existing
qwen_refusedidiom; the tensor-consistent containers that carry the ASan/SIGFPE evidence are described above for reproduction.AI-agent-assisted (Hermes), posted with human authorization.