Skip to content

core: decode and encode csf_32x2_v1 block scales on the host - #1021

Closed
Bizuayeu wants to merge 1 commit into
ashhart:mainfrom
Bizuayeu:pr/fp4local-csf
Closed

Bizuayeu wants to merge 1 commit into
ashhart:mainfrom
Bizuayeu:pr/fp4local-csf

Conversation

@Bizuayeu

Copy link
Copy Markdown
Contributor

What this changes

Adds core/nvfp4_csf32.zig, a host decoder and encoder for csf_32x2_v1, the lossless encoding of the routed experts' NVFP4 block scales in NVIDIA's GLM-5.3-Flash-FP4-Local (#1015). Decoding gives the e4m3 [n, k/16] bytes that core/nvfp4.zig reads today; nothing calls it yet.

  • The decoder takes the five stored parts and allocates nothing. One pass checks them against the format and refuses malformed parts: wrong lengths, a base above 240, page prefixes that do not start at 0 or that decrease, a page origin that does not follow the records before it, records out of their block or out of order, and records left over.
  • The encoder chooses each row's base as the format's reference does: the 16-wide window that covers most of the row's bytes, the lowest on a tie.
  • The format is docs/csf-scale-blocks.md of local-inference-lab/flashinfer (Apache-2.0). The code is written for TensorFold from that document. The test's golden digests were computed with its reference encoder, scripts/encode_csf.py (Apache-2.0). None of its code is in this change.
  • The file sits beside core: decode lossless NVFP4 CSF scale planes #904's slab codec, core/nvfp4_csf.zig, which reads the slab encoding (csf, Qwen3.8 FP4-Local). This file reads the block one, csf_32x2_v1, and takes its name from the checkpoint's weight_scale.csf32_* tensors. The two share no code.

Receipt

  • Environment: TensorFold 9ccf4727 plus this commit, Zig 0.17.0. Host tests on x86_64 Linux, on an LF tree from git archive. The checkpoint check ran on a GB10 (aarch64) against nvidia/GLM-5.3-Flash-FP4-Local@76348ddb.
  • Exactness: n/a, since no served path calls this. On the checkpoint, all 36,288 routed-expert scale matrices were decoded and encoded again: 24,192 of 2048 × 256 and 12,096 of 4096 × 128, with 19,025,362,944 scales and 53,886,672 exceptions. Every matrix gave back its five stored parts byte for byte. The check is a ReleaseSafe tool built on this file, and it also checks that each weight is u8 [R, K/2] with K = 16C.
  • Decode speed before and after: n/a, host code that no served path calls.
  • Prompt speed before and after: n/a, for the same reason.
  • Tests run:
    • zig build test: 84/84 steps, 1383/1390 tests passed, 7 skipped.
    • zig build test-kernel-contract, test-golden, fuzz-cortheon and a plain zig build: succeeded.
    • lean: 0 new problems (517 on main). git diff --check: clean.
    • nvfp4_csf32.zig adds 7 tests:
      • a block built by hand;
      • the format's tile order;
      • the base choice, with ties and the 240 cap;
      • the reference encoder's bytes for three boundary shapes (32 × 1, 160 × 3, 160 × 67);
      • round trips of seven shapes, up to 2048 × 256 and 4096 × 128;
      • malformed parts refused;
      • a page's origin.
    • A copy with the tile order changed to row-major still passed the round trips, but failed the order and golden tests.
  • Not run: GPU checks, since there is no kernel and no served path. Metal, since there is no Mac here.

Checklist

  • Every token still goes through the lane rounds. No serial path, and nothing that needs drafts off. (Host code only; no serving code changes.)
  • Drafted output equals "draft": false, a resumed prompt equals a fresh one, and concurrent equals solo. (No served path changes; nothing calls the decoder yet.)
  • No precision traded for speed. If the bits change, the description says which sums change and why. (Decoding is lossless: it returns the stored e4m3 bytes exactly.)
  • A new or changed GPU kernel is registered with the kernel contract (docs/kernel-contract.md); each backend's SUMMARY line is in the receipt. (No GPU kernel.)
  • Prompt processing is no slower than the last release. (No served path changes.)
  • The description says which platforms I ran, Metal M1 to M5 and CUDA, and which I could not. (Host tests on x86_64 Linux and the checkpoint check on a GB10; no Metal.)
  • New tests fail before the change, pass after it, and skip cleanly without their dependency. (They need only std; a changed tile order fails the order and golden tests.)
  • Comments and docstrings are one line. No measurements or history in the source. (lean: 0 new problems.)
  • No personal data, machine names, internal hosts or local paths. No AI attribution lines.

…d and encoded on the host (FP4-Local's routed experts)
@ashhart

ashhart commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Thanks @Bizuayeu for the block-CSF codec and the reported byte-for-byte round trips of all 36,288 scale matrices. We're taking this with a geometry/exception-count overflow guard for 1.1.1. The independent order/digest tests matter: a matching encoder and decoder can both have the wrong layout and still round-trip. Review keeps the local-inference-lab format/reference attribution and checks allocation-failure cleanup. The full checkpoint result remains your reported receipt; we have not independently repeated it. This is a host foundation for #1015, with the mixed-format loader and its device/model gate still separate. No further codec changes are requested beyond the guarded integration.

Posted by Ash's AI Assistant Synthena

@ashhart ashhart mentioned this pull request Oct 18, 2026
ashhart pushed a commit that referenced this pull request Oct 19, 2026
Credit: @Bizuayeu for the contributed implementation and original tests.
Retain local-inference-lab format and reference-oracle attribution.
Include the mandatory maintainer geometry, exception-count and allocation-unwind review fixes.
@ashhart

ashhart commented Oct 19, 2026

Copy link
Copy Markdown
Owner

Thanks @Bizuayeu for #1021 and your reported round trip of all 36,288 scale matrices. 1.1.1 includes the block-CSF host codec with the geometry, code-length and exception-count overflow guards, independent layout/order checks and allocation cleanup. The local-inference-lab format and reference attribution stays with it. This is a host foundation; mixed-format family loading and #1015's checkpoint/device/model checks remain separate. The full checkpoint round trip has not been independently repeated here.

Posted by Ash's AI Assistant Synthena

@ashhart ashhart closed this Oct 19, 2026
BlivionIaG pushed a commit to BlivionIaG/TensorFold that referenced this pull request Oct 20, 2026
Credit: @Bizuayeu for the contributed implementation and original tests.
Retain local-inference-lab format and reference-oracle attribution.
Include the mandatory maintainer geometry, exception-count and allocation-unwind review fixes.
@Bizuayeu
Bizuayeu deleted the pr/fp4local-csf branch October 25, 2026 07:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants