Repository navigation
cluster: opt-in q8 activations on the wire (COLI_CLUSTER_ACT=q8), protocol v2 - #1963
Conversation
|
CI on this PR has no verdict yet: of its 114 checks, 112 are CANCELLED and 2 SUCCESS (read from the check rollup on 2026-10-09); no job failed. The branch still merges cleanly against For context: #1968 is closed as superseded by #1774 ( |
|
Thanks for the series. #1962 and #1969 are in the external batch of 2026-10-16 (#2112). #1963, #1964, #1967 and #1970 could not go in: they conflict with #1962 and with each other in |
…tocol v2 The expert-worker protocol moves every routed row as raw f32 both ways, so on a LAN the transfer, not the expert FFN, bounds a delegated layer. distributed-llama syncs its activations as blocks of 32 int8 behind one scale for a ~4x cut. Same idea here, behind an env switch and off by default: the cluster parity gate is token-exact and int8 rows are not. - COLI_CLUSTER_ACT=q8: the coordinator speaks a v2 header (magic, version 2, act, layer, D, I, n) whose rows are ceil(D/32) f32 block scales followed by D int8 -- qrow_i8 per block, the engine's own activation rounding, so no new quantizer -- and the worker answers in the same format. f32, the default, sends the v1 bytes unchanged, so a cluster of mixed binaries keeps working. - The worker accepts v1 and v2, names the versions it speaks when it refuses one, and refuses an unknown act word by name. A coordinator whose v2 request meets a closed socket names the worker and the COLI_CLUSTER_ACT=f32 escape hatch instead of just "failed". The worker's response-header writes free the batch when the peer is gone mid-header, as a bad request already did; the act word had widened that leak. - The coordinator reports bytes sent and received at exit, so the cut is measurable: on the tiny GLM oracle, 8203 -> 2316 B/position (3.54x) with the same argmax at every position. - test_cluster_protocol: the q8 codec byte for byte against qrow_i8 (partial last block, zero row, decode within half a block scale), a v2 q8 round trip over a socketpair, and a v2 header with act=f32 still carrying raw rows.
test_cluster_sharding's f32 gate is unchanged: the same assertions, now on shared _expert_worker/_coordinator helpers. ClusterQ8DriftTest runs the delegated oracle with COLI_CLUSTER_ACT=q8 on both fixtures and asserts that the f32 delegation stays exact, that the q8 run scores the same positions and mismatches at most Q8_MAX_MISMATCHES of them (measured 0 on fmt6 and fmt4; the bound carries no slack, raise it with a measurement), and that q8 moves less than a third of f32's bytes; it prints bytes per position for the record.
73b29e0 to
7a4ba6c
Compare
|
Done. The four, plus #2120 (which was stacked on #1970), are rebased as one stack on
Gates, same invocations on today's
One thing for CI: #1967's timing assertion ( |
The expert-worker protocol moves every routed row as raw f32 both ways. On a LAN that is the cost that scales with workers: distributed-llama's answer is to sync activations as 8-bit blocks, and today on two M1 Max MacBooks over wired 1 GbE its own per-token line showed ~28 ms/token on the wire for 712 kB/token, half of each step. This ports that idea, opt-in, with the token-exact default untouched.
Protocol.
COLI_CLUSTER_VERSIONstays 1 and its bytes are unchanged. New v2 header ismagic version act layer D I n;actis f32 (0) or q8 (1). A q8 row is its ceil(D/32) f32 block scales followed by its D int8 values,qrow_i8per block of 32 (the engine's own activation rounding), both directions. The coordinator speaks v1 unlessCOLI_CLUSTER_ACT=q8(defaultf32; anything else is refused by name at start), so a cluster of mixed binaries keeps working by default. The worker accepts v1 and v2, echoes version and act in the reply, and refuses a v3 request or an unknown act by name. When a q8 coordinator meets a v1 worker, which refuses v2 by closing, the failure names the protocol versions, the worker's host:port and theCOLI_CLUSTER_ACT=f32escape. Byte counters oncluster_io; the coordinator prints[CLUSTER] transfer: N bytes sent, M bytes received (activations q8)at exit.Also fixed on the way: the worker's response-header writes
break'd on a peer gone mid-header without freeing the batch; they now take the same free path a bad request does.Tests.
test_cluster_protocol: the v1 round trip is untouched; newtest_q8_codec_matches_qrow_i8(D=256/70/1: wire bytes equalqrow_i8per block, decode within s/2, zero row exact),test_v2_f32_rows_are_raw,test_wire_round_trip_q8(v2 header over a socketpair, the worker checks the wire bytes, round-trip error ≤ 2·amax/127, and asserts the path is really lossy).test_cluster_sharding.py: the f32 token-exact gates are unchanged; newClusterQ8DriftTeston both fixtures asserts the f32 delegated run stays oracle-exact and the q8 run scores the same positions with mismatches ≤Q8_MAX_MISMATCHES(0, measured, documented as no-slack: raise it with a measurement, not silently) while moving < 1/3 of the bytes.Measured on the tiny GLM oracle (hidden 256, 2 MoE layers, top-2, 32 positions): f32 8203 B/position, q8 2316 B/position (3.54×), oracle argmax identical at all 32 positions on fmt6 and fmt4.
make colibri tests/test_cluster_protocolwarning-free;pytest tests/test_cluster_sharding.py: 4 passed.Open choice: the block scale is f32 (the tree has no f32→f16 encoder); f16 like distributed-llama would be another ~6% for ~15 lines if you want it.