Skip to content

glm cuda: TF_GLM_COPY_SHARE=1 lets shared rounds' copies take the lone ramp, to a stream's share of the rows - #3333

Draft
Bizuayeu wants to merge 2 commits into
ashhart:mainfrom
Bizuayeu:pr/glm-copy-share
Draft

Bizuayeu wants to merge 2 commits into
ashhart:mainfrom
Bizuayeu:pr/glm-copy-share

Conversation

@Bizuayeu

@Bizuayeu Bizuayeu commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

What this changes

With TF_GLM_COPIES=1, a copy in a shared round is always the first copy's three tokens wide; only a stream alone grows its copies on the lone ramp (2w+1 after a copy kept whole, back to three after a miss). So a quote or an edit at two or four streams drafts no more a round than one stream's first copy: 3.9 tokens a chunk on the bench below, against 15.4 for the same quote alone.

TF_GLM_COPY_SHARE=1 lets shared rounds' copies take the lone ramp too, each capped at its stream's share of the round's 32 rows less its pending row: 15 tokens at two streams, 7 at four, 3 from seven streams on. The cap leaves the other streams' rows open, and the prices still decide what fills them. It is off by default and refused at the open without TF_GLM_COPIES=1, so the default and TF_GLM_COPIES=1 alone keep their facts.

Cell, decode tok/s (aggregate) TF_GLM_COPIES=1 + TF_GLM_COPY_SHARE=1
a quoted document (~400 tokens back), 1 stream 132.2, 132.4 132.3, 132.4 within
quote, 2 streams 77.4, 76.9 116.2, 116.1 +50.6%
quote, 4 streams 96.3, 96.6 124.2, 124.2 +28.8%
a file edited back, 1 stream 113.5, 113.5 111.7, 113.5 −0.8%
edit, 2 streams 70.5, 70.0 107.7, 108.6 +54.0%
edit, 4 streams 79.0, 78.2 96.9, 97.4 +23.6%
prose, 4 streams 56.5, 56.4 56.1, 56.9 within
code, 4 streams 70.7, 71.7 71.1, 71.1 within

These are two fresh launches an arm, placed symmetrically in one window (off, on, …, on, off), from a fork build of this change on main d001c28f29 that also carries an experiment-only switch, left at its default here. Receipts from this head, main against head, come before Ready. The 1-stream edit cell's −0.8% is one launch (111.7) against two equal ones; one stream never shares a round, and its tokens a chunk are the same (12.800) in all four launches.

Where it costs, with one copying stream beside prose or code:

Set the copying stream, tok/s the others as run, tok/s the others' round gap while it decodes
a quote + three prose (4 streams) 28.0 → 49.4 15.8 → 16.1 137.5 → 155.1 ms (+12.9%)
an edit + three code (4 streams) 22.0 → 35.2 19.0 → 19.2 176.1 → 195.6 ms (+11.1%)
a quote + one prose (2 streams) 45.2 → 98.9 25.9 → 28.5 85.6 → 147.0 ms (+71.8%)

The copying stream finishes sooner, so the others end a little faster as run; while it decodes, their rounds are longer. Without the share cap (a copy taking every row the others leave, measured only as a comparison), the totals rose another 0.4–2.6% and the others' gaps another 14–29%, so the cap stays. Every item's token_sha256 was one hash over its streams, reps, alone and serial runs and all sixteen launches (29 items), with the share on and off.

Tests:

  • New in core/lanes/shared_copy_test.zig: "without the ramp a shared round's copy keeps first_copy's four rows", "the ramp grows two streams' copies to their share and starts over after a miss", "eight streams keep four-row copies, and so do streams that share no round", "a copy keeps to its stream's share of the round, leaving the other streams their rows".
  • New in families/glm/cuda_env_test.zig: "TF_GLM_COPY_SHARE=1 widens TF_GLM_COPIES=1's copies and is refused without them".
  • New in native/copy_drafts_cuda_test.zig: "GLM's TF_GLM_COPY_SHARE adds only the shared ramp, and nothing without TF_GLM_COPIES", "GLM's shared ramp widens shared rounds' copies past four rows and keeps plain tokens".
  • Red: the lane core's four, on a tree with the fact's field and the tests but not the ramp, fail the two that grow ("expected 8, found 4") and pass the two that pin today's widths; with the share cap removed, only the cap test fails (copied <= 2 * (32 / 4 - 1)). On a copy of this head where GLM's apply never sets the fact, test-glm-copies-host fails exactly the two native copy tests (18/20).

Checks on this head

  • Head commit: b33bb29f36, the CHANGELOG number on the change 375b5ccd1e; the checks below ran on 375b5ccd1e, whose code this head keeps.
  • Lean checker, python3 tools/zig/lean_check.py, on the base and on this head: 341 and 341, the same findings. tools/pr_check.py --base origin/main --pr 3333: 14 changed files, 0 new findings, 0 errors and 0 warnings.
  • Tests run, with the command and pass, fail and skip counts: WSL (x86_64, Zig 0.17.0), zig build -Dfixed-cpu STEP: test-environment-host 23/23, test-shared-lane-regressions-host 371/372 (1 skipped), test-root-copy-host 48/48, test-glm-copies-host 20/20, compile-cuda-tests 10/10 steps, and test-cuda-host 6,200 passed, 32 skipped and 1 failed on the first run: server/linear_time.zig's timing test "fastest's work leaves out a sleep in a run", which this change does not reach, while the machine was also running other work. Rerun on the quiet machine, all 398 steps passed, that test's binary (52 tests) with them. pytest -q -rs from the root: 459 passed, 86 skipped, 519 subtests passed; main's CI on the same base has 461 and 84, the two apart being tools/zig/test_nfkd_tables.py, which skips on this machine's Python (Unicode 15.0.0).
  • CI: not yet run on this head (opened as a draft).
  • Not run, and why: the -Dnvcc build and receipts from this head on GB10s, which come before Ready. Metal, HIP, Vulkan and XPU, with no such machine here; only GLM's CUDA lanes set the fact.

Receipt

  • Main against branch: before Ready, from this head. The tables above are a fork build of the change.
  • Boxes it reaches: CUDA boxes serving GLM with TF_GLM_COPIES=1 and TF_GLM_COPY_SHARE=1, at two streams or more. These numbers: two GB10s at TP=2.
  • New switch? TF_GLM_COPY_SHARE: unset or 0 keeps the facts (the default), 1 turns it on; it is refused at GLM's open without TF_GLM_COPIES=1, and any other text is refused by name. Its rows are in platform/environment.zig and docs/environment.md, with a paragraph in docs/recipes/cuda-lane-copies.md.
  • Environment: the fork build above (main d001c28f29 and this change); Zig 0.17.0 and CUDA for sm_121; two GB10s at TP=2 with --parallel 4; Bizuayeu/GLM-5.3-Flash-Jammed-XSFP4 at 0a22bb46ec; greedy, 3 reps, tools/bench_concurrent.py --alone --serial.
  • Paths and platforms the change reaches, which I ran and which I could not: GLM's CUDA lanes, where apply sets the fact and the core's copy proposal reads it in shared rounds. Ran TP=2 only.
  • Exactness: above.
  • Main against this branch, same machine and checkpoint: before Ready.
  • Decode speed before and after: the tables above (tools/bench_concurrent.py); tools/bench_openai.py with the receipts.
  • Prompt speed before and after: n/a. The fact sizes copy drafts in decode rounds; prompt passes propose no copies.
  • Licence of any new weights or drafter: n/a.

Checklist

  • The title and description match the head commit, including the receipt and the stack.
  • New tests fail before the change, pass after it, and skip cleanly without their dependency. (The red runs above. None needs a GPU, a checkpoint or the process environment, so none skips.)
  • Comments and docstrings are one line. No measurements or history in the source.
  • No personal data, machine names, internal hosts or local paths in the diff or its commits. No AI attribution lines.
  • Every token still goes through the lane rounds. No serial path, and nothing that needs drafts off. (The fact only widens a copy window the lanes already verify.)
  • Drafted output equals "draft": false, a resumed prompt equals a fresh one, and concurrent equals solo. (Concurrent equals solo and serial above; "draft": false and a resumed prompt with the receipts from this head.)
  • No precision traded for speed. If the bits change, the description says which sums change and why. (No arithmetic changes; the tokens are the same.)
  • Decode and prompt processing are no slower than main at one stream and the widest admitted; with --drafter, no slower than without it, greedy and sampled. (With the receipts from this head; off by default, the facts are main's.)

…e ramp, to a stream's share of the rows

In a shared round every copy window was first_copy wide (three tokens for GLM): the lone ramp (2w+1 after a copy
kept whole, back to first_copy after a miss) ran for a stream alone only. With TF_GLM_COPIES=1, a quote or an edit
at two or four streams drafted no more a round than one stream's first copy.

Model.shared_copy_ramp lets a family's shared rounds take the ramp too, each copy capped at its stream's share of
batch_rows less its pending row (32 rows: 15 tokens at two streams, 7 at four, first_copy from seven on), so a copy
cannot take the rows the other streams' windows need. The cap keeps rows open; whether the allocator fills them is
the prices' (TF_GLM_COPIES=1 prices every shared row). It needs shared rounds: with TF_GLM_SHARED=0 each stream's
copy keeps first_copy, and Recall keeps its width.

GLM sets the fact only with TF_GLM_COPIES=1 and TF_GLM_COPY_SHARE=1, so the defaults and TF_GLM_COPIES=1 alone keep
their facts; TF_GLM_COPY_SHARE=1 without TF_GLM_COPIES=1 is refused at the open, not read as off.
@ashhart

ashhart commented Nov 14, 2026

Copy link
Copy Markdown
Owner

DEVICE

@Bizuayeu, no must-fix found. The option stays off by default, requires copies to be enabled, and keeps the existing target verification and row allocator. The new tests cover the shared ramp, miss reset and plain-token equality for both drafter modes.

Host checks and Linux cross-compiles pass: 6,985 tests passed, 43 skipped, with formatting clean and zero new lean findings.

We will run the device check on our side at TP=2: copies off and on, greedy and seeded, one through eight streams, MTP and DFlash2, including rejected copies and resumed turns. Tokens must match plain decoding before we compare complete round costs and served speed.

  • Synthena (Ash's Agent)

This branch has not been deployed

No deployments
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