Repository navigation
feat(compile): export Q8_0 / Q4_0 Linear weights as a block-quant linalg chain - #1478
Merged
Merged
Conversation
…alg chain Keep packed weights packed through export so an NPU compiler can match them to a block-quantized matmul kernel instead of a dense FP32 copy. - PackedConstantHandling.KEEP_PACKED: the weight node carries its PackedBlockStorage; HloGenerator.generate takes packedConstants. - BlockQuantMatmulFusionPass: folds weight -> transpose -> matmul (or a transposeB matmul) into a block_quant_matmul node; skips are reported. - BlockQuantMatmulConverter: emits (sitofp(codes) - zp) * scale over [nB, 32, N] i8/i4 codes with bf16 scales, then linalg.batch_matmul, constants inline. A negative block scale d is stored exactly as codes -1 - c, zero point -1, scale -d. A packed weight left unfolded fails the export. On an SL2610, Torq 2.3.0 with --iree-input-type=stablehlo-torq compiles the emitted Q8_0 and Q4_0 projections to mixed_quant_matmul with no generic fallback; outputs match the dequantized weights at cosine 0.999996 / 0.999997. TorqBlockQuantGoldenTest checks the kernel match when SKAINET_TORQ_COMPILE is set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
📖 Documentation Preview The documentation has been built successfully for this PR. Generated Files:
Artifacts:
This comment will be updated automatically when the PR is updated. |
This was referenced Nov 5, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A Q8_0 or Q4_0
Linearcan now be exported with its weight kept packed: integer codes plus per-block scales, emitted as a linalg chain that an NPU compiler can match to a block-quantized matmul kernel. Until now a packed weight could only fail the export or be dequantized to a dense FP32 constant.PackedConstantHandling.KEEP_PACKED(skainet-compile-dag): the weight node carries itsPackedBlockStorageunderpacked_weight, with no float copy.HloGenerator.generatetakespackedConstants.BlockQuantMatmulFusionPass(skainet-compile-opt, DAG phase): foldsweight → transpose → matmul(or atransposeBmatmul, afterTransposeEliminationPass) into oneblock_quant_matmulnode. It only folds a weight that is exclusive, Q8_0/Q4_0,ROW_MAJORand hasin % 32 == 0; every skip is reported in the diagnostics.BlockQuantMatmulConverter(skainet-compile-hlo, registered in every converter set): emits(sitofp(codes) - zp) * scaleover[nB, 32, N]i8/i4codes withbf16[nB, 1, N]scales, thencollapse/expand→linalg.batch_matmul. The activation is converted tobf16and reshaped to[1, M, K]around the chain, and all constants are inline.dis stored exactly as codes-1 - c, zero point-1and scale-d. That fitsi8andi4, so ggml Q4_0 (d = max / -8) needs no requantization. The zero-point tensor is emitted only when such a block exists.ConstantOperationsConverterfails the export and names the fusion pass andDEQUANTIZE.A target opts in with
TargetOptimizers.registerDagPasses("torq") { listOf(BlockQuantMatmulFusionPass()) }. The docs (compile-flexibility.adoc) and the CHANGELOG are updated.Verification
BlockQuantMatmulExportTest(common, 7 tests): it tracesmatmulWeightTransposedwith real Q8_0/Q4_0 storage, then runsKEEP_PACKED, the pass andtoStableHlo. It checks:dot_general;storage.toFloatArray()within bf16 scale rounding;apiDumpis updated, and hlo compiles for linuxX64 and wasmJs.TorqBlockQuantGoldenTest(jvm) runs only whenSKAINET_TORQ_COMPILEnames a command that takestorq-compile's arguments. With Torq 2.3.0 (--iree-input-type=stablehlo-torq --torq-hw=SL2610), both the Q8_0 and the Q4_0 (negative scales) projection compile totorq_hl.mixed_quant_matmul, 8 tiles each, with no generictorq_hl.matmul.bf16(x) · Wᵀwith the dequantized weight: cosine 0.999996 (Q8_0) and 0.999997 (Q4_0).Limits
llvm-cpuhas produced wrong results fori4weights, so keep Q4_0 to targets that were checked.🤖 Generated with Claude Code