Aggregated Weight Binding
Overview
Aggregated weight binding is the technique that reduces on-chain calldata by 28× — from ~2.4M felts (individual weight commitments per matmul) to ~86,723 felts for a 40-layer Qwen3-14B model. It is the key enabler of practical streaming GKR verification on Starknet.
The Problem
In a GKR proof for a transformer model, each matmul layer requires a weight commitment — a Merkle root over the MLE of the weight matrix. For Qwen3-14B with 160 matmuls across 40 layers, submitting individual commitments and opening proofs is prohibitively expensive: each opening proof contains a full Merkle path, and the total calldata exceeds Starknet's sequencer limits.
The Solution: Mismatch Sumcheck Batching
Instead of verifying each weight commitment individually, the prover:
- Commits to a super-root: A single Merkle root over all weight matrix MLEs, organized as a tree of subtree roots.
- Batches via random linear combination (RLC): The verifier draws a random challenge and forms a batched claim over all weight evaluations.
- Runs an aggregated oracle sumcheck: A single sumcheck proves that all weight evaluations are consistent with the super-root commitment.
Individual (old): 160 Merkle roots + 160 opening proofs → ~2.4M felts
Aggregated (new): 1 super-root + 1 batched sumcheck → ~86,723 felts
(28× reduction)
Protocol
Prover Side
1. Build super-root = MerkleCommit(all weight MLEs)
2. For each matmul i, record eval_point_i and expected_value_i
3. Verifier draws RLC challenge α from Fiat-Shamir channel
4. Batched claim = Σ_i α^i · expected_value_i
5. Run aggregated oracle sumcheck proving batched claim
6. Emit: super-root, subtree_roots, opening_proof, eval_points
Verifier Side (Cairo v31)
1. Receive super-root, subtree_roots, opening_proof, eval_points
2. Verify subtree_roots against super-root via Poseidon2-M31 Merkle
3. Draw RLC challenge α from Fiat-Shamir channel
4. Recompute batched claim = Σ_i α^i · deferred_eval_i
5. Verify aggregated oracle sumcheck against batched claim
6. Accept if sumcheck passes
Security
The RLC-only mode (without the full aggregated binding proof) was identified as unsound — a malicious prover could fabricate weight claims without being caught. The full binding mode is now the default and required for streaming verification:
STWO_AGGREGATED_RLC_ONLY=1is rejected by the streaming verifier (SoundnessGate error)need_full_bindingdefaults totrue- Cairo
verify_gkr_stream_finalize_input_mlerequiresweight_eval_pointsanddeferred_eval_points
Performance
| Metric | Value |
|---|---|
| Calldata (40-layer Qwen3-14B) | 86,723 felts |
| Binding overhead | ~4,290 felts (~5% of total) |
| Reduction vs individual | 28× |
| Weight cache hit | <1ms (vs 500s first run) |
Weight Commitment Cache
The prover caches weight Merkle roots on disk at <model_dir>/.stwo_weight_cache.swcf. On subsequent proofs with the same model weights, the aggregated binding computation is effectively free — cache hits skip the entire GPU/CPU pipeline.
References
- ObelyZK Paper, Section 4: Aggregated Weight Binding
stwo-ml/src/aggregated_binding.rs— Prover implementationelo-cairo-verifier/src/aggregated_binding.cairo— Cairo verifierstwo-ml/src/weight_cache.rs— Weight commitment cache