HiramKHackenbacker commited on
Commit
15c2afa
·
verified ·
1 Parent(s): 0d2065c

README: ring3 per-layer-type SDPA bundles

Browse files
Files changed (1) hide show
  1. README.md +44 -0
README.md CHANGED
@@ -404,3 +404,47 @@ dimension appears in either entrypoint of either bundle.
404
  > host-side work can be developed against the contract over a smaller download. It carries
405
  > real weights for the layers it keeps and produces low-quality text; do not evaluate
406
  > quality from it.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
  > host-side work can be developed against the contract over a smaller download. It carries
405
  > real weights for the layers it keeps and produces low-quality text; do not evaluate
406
  > quality from it.
407
+
408
+
409
+ ## `ring3/` — per-layer-type SDPA form
410
+
411
+ > **EXPERIMENTAL — gated in torch, no on-device numbers yet.** Same weights, same
412
+ > quantization, same host contract as `ring/`. One thing changes inside the graph: the
413
+ > grouped-query expansion is folded into the query **only in the full-attention layers**,
414
+ > and the sliding layers keep the stock gathered form.
415
+
416
+ **Why the split.** Folding the GQA expansion into the query removes the gathered copies and
417
+ the broadcast index tensor, but it also turns G independent per-head matmuls into a single
418
+ batch-1 matmul with G times the rows. That trade is worth taking when the key length is long
419
+ (the full-attention layers read the whole capacity) and not worth taking when it is short
420
+ (the sliding layers read a fixed 576-slot ring, where the operation is short enough that
421
+ losing the per-head parallelism costs more than the bytes it saves). `ring/` applied the fold
422
+ everywhere; `ring3/` applies it only where the key length is long.
423
+
424
+ Both forms compute the same dot products in the same order. The equality gate below is run
425
+ against the shipped graph, not against `ring/`.
426
+
427
+ **Contract: unchanged.** Same four inputs in the same order, same two KV states in the same
428
+ positional order, `position_ids` carrying the absolute position of each of the S tokens in
429
+ the call, the mask derived inside the graph, the same requirement that a `prefill` call start
430
+ at a multiple of 64. A host driving `ring/` drives these with no change.
431
+
432
+ **Equality.** Gated in eager torch against the shipped graph before conversion: 1,600 prompt
433
+ tokens as 25 chunks of 64 then 32 greedy decode steps, final position 1,631, so the sliding
434
+ ring wraps about three times. fp32, 57 comparisons per run, **0 argmax mismatches** on every
435
+ bundle below. No dynamic dimension appears in either entrypoint of any of them.
436
+
437
+ | Bundle | Context | KV state shape | KV bytes, both states | Sliding / full slots |
438
+ |---|---:|---|---:|---|
439
+ | `ring3/gpu-pipelined/gemma4_e2b_qat_decode_int4lin_tbl_pf64_ring_c4096_gqafull` | 4,096 | `[1, 1, 1, 19200, 512]` x2 | 39.3 MB | 12 x 576 + 3 x 4,096 |
440
+ | `ring3/gpu-pipelined/gemma4_e2b_qat_decode_int4lin_tbl_pf64_ring_c2048_gqafull` | 2,048 | `[1, 1, 1, 13056, 512]` x2 | 26.7 MB | 12 x 576 + 3 x 2,048 |
441
+
442
+ E2B runs 28 sliding and 7 full attention layers; in these bundles the 28 keep the gathered
443
+ form and the 7 use the folded one.
444
+
445
+ ## `ring3-smoke/` — truncated proving asset
446
+
447
+ > **EXPERIMENTAL — not a usable model.** A 5-layer truncation of the E2B decoder at the 4,096
448
+ > capacity (`[1, 1, 1, 6400, 512]` states, 4 x 576 + 1 x 4,096), published only so host-side
449
+ > work can be developed against the contract over a smaller download. It carries real weights
450
+ > for the layers it keeps and produces low-quality text; do not evaluate quality from it.