AI & Tools

Four times past the trained window: one million tokens still finds the needle, in 14 minutes

bar chart on a very dark ground: A million tokens takes one work step. seconds for one complete request at full context · median of two KV residency settings · needle at half and top depth series: 512k (YaRN ×2), 1 M (YaRN ×4). groups: int8 (mid KV tier) 324.6 / 819.0 (21.66 GiB KV at 1 M); k8v4 (key 8, value 4 bit) 356.8 / 871.8 (16.73 GiB KV at 1 M); q4_0 (both 4 bit) 383.6 / 783.9 (11.81 GiB KV at 1 M); GB10 at 262k (for scale) 486.8 (unified memory) right needle test, 2 probes each: 512k: 2/2 in all six cells, 1 M: 2/2 in all six cells, GB10 262k: 3/3, prefill stays 1,590 to 2,090 tok/s, decode 39 to 55 tok/s side panel needle test, 2 probes each: 512k: 2/2 in all six cells, 1 M: 2/2 in all six cells, GB10 262k: 3/3, prefill stays 1,590 to 2,090 tok/s, decode 39 to 55 tok/s
A million tokens takes one work step. seconds for one complete request at full context · median of two KV residency settings · needle at half and top depth

Two nights in a row I pushed the same model past its trained window: 524,288 and 1,048,576 context tokens on two GeForce RTX 3090s, won with rope stretching (YaRN, scale 2 and 4), run through the production engine, with a restart after every configuration. The question was short: past the trained window, does the model still find a needle in the prompt — and what does that cost in time? The answer in one sentence: It finds it more reliably than I expected — 24 of 24 probes across twelve cells, three KV tiers, two window sizes — but the time does not grow linearly with the context, it grows superlinearly: 5.8 minutes for a full pass at 512k, 13.7 minutes at one million, and both k8v4 double-session cells at 512k collapsed along the way. This is part two of the series on long context on the same machine; part one measures what the KV cache costs at 262,144 tokens.

If you want the ground work: part one — KV memory and the wait at a full window, plus how the fleet is built, the GPU patch (active in every measurement here) and the quant ladder of the same model.

What “stretched” means technically

The model — qwen3.8-flash-next-abliterated, a mixture-of-experts build in IQ3_S — was trained with a rotary window of 262,144 tokens. YaRN shifts the rotation frequencies of the RoPE keys so the same keys map a multiple of that distance without leaving the training regime; the engine gets this as a parameter, not as new weights:

  • --rope-scaling yarn, --rope-scale 2, --yarn-orig-ctx 262144 → the window reports 524,288 tokens.
  • --rope-scale 4 with the same origin window → the window reports 1,048,576 tokens, exactly four times the trained range.
  • KV cache grows linearly with the window regardless: int8 stays at 22,176 bytes per token, so 5.41 GiB at 262,144, 10.83 GiB at 524,288 and 21.66 GiB at one million. q4_0 (4-bit keys and values) uses 12,096 bytes per token: 2.95 / 5.91 / 11.81 GiB. k8v4 (8-bit keys, 4-bit values) sits between them: 4.18 / 8.37 / 16.73 GiB. Computed from the format sizes, not measured.

Relevant for how to read this: YaRN is a documented, mathematically clean method — but whether a specific model still produces usable answers beyond its training window is not part of that documentation. That gap is exactly what this post fills: not the theory, but twelve cells with a needle and a stopwatch.

How it was tested

Measured in phase a2 of the sweetspot matrix: 20 cells, across two nights from 29 October 18:13 to 30 October 04:08, each after an engine restart with the new configuration. Rotated were three KV tiers (int8, k8v4, q4_0) × two KV residency settings (20 GiB and 64 GiB) × two window sizes (512k with scale 2, 1M with scale 4), one session each — those are the twelve cells with a needle test — plus eight cells with two concurrent sessions for parallel behaviour.

Two instruments, kept apart:

  • The timing probe sends a fresh 262,144 token prompt and measures first token, prefill rate and decode rate. It is the same size in all three windows, which makes it the comparison point: what does a stretched window cost when the work stays identical?
  • The needle test builds a prompt that nearly fills the window, hides a code word with a number at half and at top depth, and asks for it back. Thinking is off, temperature 0, at most 32 answer tokens — so the answer time is essentially the prefill time of the entire prompt. Every cell got two probes.

Two honesty notes up front. First: at the top edge of the window the server refused the prompt several times (HTTP 400) and the checker then shrank it — that happened for 5 of 12 probes at 512k and 7 of 12 probes at one million. The prompts therefore landed between 445,471 and 524,123 tokens (512k) and between 890,788 and 1,048,479 tokens (1M). Not every probe was measured at the absolute stop; most were just below it. Second: in stretched context I tested two depths (50 and 90 percent), in native 262k context the preparatory run used three. The hit rates of the two posts are therefore not row-by-row comparable.

Finding 1: Past the trained window the model still finds the needle — in all twelve cells

bar chart on a very dark ground: A million tokens takes one work step. seconds for one complete request at full context · median of two KV residency settings · needle at half and top depth series: 512k (YaRN ×2), 1 M (YaRN ×4). groups: int8 (mid KV tier) 324.6 / 819.0 (21.66 GiB KV at 1 M); k8v4 (key 8, value 4 bit) 356.8 / 871.8 (16.73 GiB KV at 1 M); q4_0 (both 4 bit) 383.6 / 783.9 (11.81 GiB KV at 1 M); GB10 at 262k (for scale) 486.8 (unified memory) right needle test, 2 probes each: 512k: 2/2 in all six cells, 1 M: 2/2 in all six cells, GB10 262k: 3/3, prefill stays 1,590 to 2,090 tok/s, decode 39 to 55 tok/s side panel needle test, 2 probes each: 512k: 2/2 in all six cells, 1 M: 2/2 in all six cells, GB10 262k: 3/3, prefill stays 1,590 to 2,090 tok/s, decode 39 to 55 tok/s
A million tokens takes one work step. seconds for one complete request at full context · median of two KV residency settings · needle at half and top depth
Cell Probes Prompt
(median per cell)
Full pass KV per session
262,144 native, int8, 32 GiB 2/2 261 701 153 s 5.41 GiB
512k, YaRN ×2, int8, 20 GiB 2/2 484 916 325 s 10.83 GiB
512k, YaRN ×2, k8v4, 64 GiB 2/2 484 637 348 s 8.37 GiB
512k, YaRN ×2, q4_0, 64 GiB 2/2 523 759 419 s 5.91 GiB
1M, YaRN ×4, int8, 20 GiB 2/2 969 935 814 s 21.66 GiB
1M, YaRN ×4, k8v4, 64 GiB 2/2 1 047 412 919 s 16.73 GiB
1M, YaRN ×4, q4_0, 20 GiB 2/2 970 201 779 s 11.81 GiB
Seven of the twelve stretched cells plus one native reference, the full set in the Edge walking figure. Prompt column: median of the two probes of this cell; full pass = median time to a complete answer; KV need computed from format sizes. Largest request actually processed in the whole series: 1,048,479 tokens — 97 below the hard stop of the window.

Twelve cells, two probes each, twenty-four hits. No miss at half depth, no miss at top depth, neither at scale 2 nor at scale 4, neither with int8 nor k8v4 nor q4_0. That is a different result than at native 262,144: there, a preparatory run missed the probe sitting on the very last edge (prompt 262,133 out of 262,144 tokens). So the edge of the native window is less reliable than the interior of a window stretched four times.

Two caveats that do not shrink the result but place it. The needle is a retrieval task: a code word with a number sits in the text and must come back. It tests attention over long distance, not reasoning across paragraphs, not arithmetic, not contradiction detection. And: at one million context the 50 percent probe is itself already 524,000 tokens deep — also outside the trained range; it was found anyway. What I take from this: for retrieval in long documents the stretched window is usable. For quality beyond retrieval I have no evidence.

Finding 2: The timing probe barely notices the stretching — the full pass notices it clearly

bar chart on a very dark ground: The stretching itself costs nothing. seconds to first token for a 262,144 token prompt · median of three KV tiers and two residency settings series: time to first token. groups: 262k native, unstretched 139.5 (free cards, int8/64 GiB); 512k, YaRN ×2 131.8 (doubled); 1 M, YaRN ×4 138.1 (context quadrupled)
The stretching itself costs nothing. seconds to first token for a 262,144 token prompt · median of three KV tiers and two residency settings
Window Timing probe
(262,144 tokens)
Prefill probe
median tok/s
Full-pass rate
median tok/s
Ratio Full pass
median
262,144 native (different night, other tiers) 139.5 s 1,756 1,246 0.71 128–325 s
512k, YaRN ×2 131.8 s 2,053 1,454 0.71 293–423 s
1M, YaRN ×4 138.1 s 1,981 1,210 0.61 696–920 s
GB10, 262k native (for scale) 379.4 s 669 520 0.78 425–576 s
Full-pass rate = probe prompt size divided by time to a complete answer; since thinking is off and the answer capped at 32 tokens, that time is almost entirely prefill of the prompt. The “262,144 native” row comes from a different night with different KV tiers, so it compares in ratio, not in absolute values. The ratios 0.71 / 0.71 / 0.61 say: a full pass is always about a third slower than the timing probe inside the same window — and the jump from 512k to 1M adds roughly another 17 percentage points.

The first column is the good news: for a 262,144 token prompt the engine needs 131.8 seconds to the first token inside a 512k window, 138.1 seconds inside the million-token window — and 139.5 in the native window. The stretching itself costs measurably nothing; the compute for a prompt of that size is identical no matter how much further the window stays open above it.

The columns on the right are the bad news, and they are the more interesting ones. Fill the window for real — 485,000 instead of 262,000 prompt tokens — and the effective rate drops from 2,053 to 1,454 tokens per second; at one million prompt tokens it drops to 1,210. The last 500,000 tokens of a prompt cost noticeably more time per token than the first 262,000. Whether that comes from quadratically growing attention, from KV paging, or from both, I did not measure — measured is only the consequence: whoever uses the window does not pay proportionally, but superlinearly.

The decode cadence is untouched by all of this: median 49.5 tokens per second at 512k, 49.6 at one million — practically the number from part one. What changes is exclusively the time until the first token. With long context, prefill decides, not output.

Finding 3: A full pass costs 5.8 to 13.7 minutes — and the KV tier is indifferent

Window KV tier Needle test Prompt median Answer time median Span of both probes
512k, YaRN ×2 int8 (mid tier) 2/2 in both cells 484 817 324.6 s 293.4–355.8 s
k8v4 (key 8, value 4 bit) 2/2 in both cells 523 293 356.8 s 323.2–373.6 s
q4_0 (both 4 bit) 2/2 in both cells 523 795 383.6 s 347.0–422.8 s
1M, YaRN ×4 int8 2/2 in both cells 969 935 819.0 s 723.8–920.0 s
k8v4 2/2 in both cells 1 047 412 871.8 s 735.3–919.3 s
q4_0 2/2 in both cells 970 201 783.9 s 695.6–869.1 s
Answer time = time to a complete answer with thinking disabled and at most 32 answer tokens. One run per cell, median over the two probes of that cell, then median over the two residency settings of the same KV tier. The ranking of tiers flips between 512k and 1M (there q4_0 fastest, here slowest) — with two measurements per tier that is noise, not mechanism.

The median over all six 512k cells is 348 seconds (5.8 minutes) for a single fully answered request, the median over all six million-token cells 819 seconds (13.7 minutes). For scale: 262,144 native tokens cost 153 to 240 seconds in the same measurement series — so the step from 512k to one million is not another increment, it is a doubling.

What stands out is how flat the curve stays across KV tiers: the tier medians read 324.6 / 356.8 / 383.6 seconds at 512k and 819.0 / 871.8 / 783.9 seconds at one million. Across three tiers whose memory needs differ by a factor of 3.7 (5.91 against 21.66 GiB at a million), that is an 18 percent spread at 512k and 11 percent at one million. The tier decides memory, not answer time. Whoever needs room at one million takes q4_0 and loses nothing measurable.

Finding 4: Two sessions at 512k — and the puzzle of the two k8v4 cells

Window KV tier Sessions Decode per session Parallel tok/s First token
512k int8, 20 GiB 2 54.9 77.4 127.4 s
512k int8, 64 GiB 2 54.3 76.1 128.9 s
512k q4_0, 20 GiB 2 46.8 70.9 131.5 s
512k q4_0, 64 GiB 2 47.8 73.9 130.1 s
512k k8v4, 20 GiB 2 12.8 16.5 175.2 s
512k k8v4, 64 GiB 2 8.7 9.7 193.8 s
1M q4_0, 20 GiB 2 47.8 76.2 131.7 s
1M q4_0, 64 GiB 2 47.4 72.1 132.5 s
Eight double-session cells of the phase: six at 512k, two at one million. The k8v4 rows are the outliers — in both k8v4 double cells throughput fell to 8.7 and 12.8 tokens per second, while int8 and q4_0 stayed at 46.8 to 54.9 in the same night. In the single-session k8v4 cells of the same configuration decode ran normally (45.6 to 50.4 tokens per second).

Five of the eight double cells behave unremarkably: two parallel requests cost the same lead time as a single one and together deliver 71 to 77 tokens per second — the pattern I know from part one. Two cells stick out brutally: both k8v4 cells at 512k, at 8.7 and 12.8 tokens per second with parallel numbers of 9.7 and 16.5 — that is standstill, not sharing.

I have no explanation for it and I claim none. The pattern is loud enough to write down: two of two k8v4 double cells collapsed, two of two int8 and two of two q4_0 double cells did not, same night, same machine, same window. Plausible directions would be the mixed dequantisation path (8-bit keys, 4-bit values) under parallelism, or memory pressure, since k8v4 with 8.37 GiB per session sits between the tiers — but I tested neither. Until the counter-test I do not schedule k8v4 for two sessions in the big window. At one million I only ran the double cells with q4_0; nothing broke there.

Finding 5: The GB10 holds 262,144 tokens, but with nearly triple the lead time

table on a very dark ground: Everything is still found — time is the price. probe at half and top depth of the context · median prompt and answer time over both probes columns: configuration | probes | prompt tokens | answer time | KV need. rows: 262k native, int8 (mid tier) 2/2 261,701 153 s 5.41 GiB; 262k native, fp16 2/2 261,802 240 s 10.82 GiB; 262k native, q4_0 (KV off GPU) 2/2 241,868 139 s 2.95 GiB; 512k, YaRN x2, int8 2/2 484,865 325 s 10.83 GiB; 512k, YaRN x2, q4_0 2/2 523,777 384 s 5.91 GiB; 1 M, YaRN x4, int8 2/2 969,783 819 s 21.66 GiB; 1 M, YaRN x4, k8v4 (KV off GPU) 2/2 1,008,973 872 s 16.73 GiB
Everything is still found — time is the price. probe at half and top depth of the context · median prompt and answer time over both probes
Platform Window KV tier First token Prefill tok/s Needle test Full pass
2 × RTX 3090 (Strata) 262,144 native int8, 64 GiB, two sessions 139.5 s 1,857 — —
2 × RTX 3090 (Strata) 262,144 native int8, 32 GiB (needle cell) — — 2/2 153.1 s
GB10 (llama-server) 262,144 native int8, unified memory 379.4 s 698 3/3 471.6 s
GB10 (llama-server) 262,144 native q4_0, unified memory 404.6 s 641 3/3 502.0 s
GB10 (llama-server) 512k / 1M — not measured — — —
The GB10 phase was planned for the native window only; 512k and one million remain open there. Two earlier attempts of this phase (29 October 18:44 and 18:46) had failed technically — empty timing probe, needle test aborted — because the runner looked at a system service unit while the GB10 runs its server instance as a user service; from 20:34 the cells ran cleanly. The GB10 needle tests three depths (10, 50, 90 percent), the 3090 stretch tests two.

On the GB10 with its single unified memory (121 GiB, of which the model occupies 51 GiB), 262,144 tokens run cleanly in both tiers with a hit in all three tested depths — but prefill takes 379 to 405 seconds instead of 139, the full pass 472 to 502 seconds instead of 139 to 261 in the native 3090 comparison cells (two depths tested there, three here). Extrapolated to one million tokens, where int8 KV needs rise to 21.66 GiB and the 3090 pair already needs 13.7 minutes per full pass, the GB10 would sit at roughly 35 to 40 minutes per request. That is arithmetic, not measurement — and the reason long context stays on the two cards in my setup while the GB10 has taken over the embedding and retrieval models.

What I did not measure

  • No quality axis beyond the needle. No perplexity, no summarisation or arithmetic task, no contradiction test across two halves of a document. Twelve cells of a retrieval task are a strong hint of usable long-range attention, not a quality verdict.
  • Only two depths in stretched window (50 and 90 percent) instead of three as in the native run-up. The very shallow and very deep edges of the stretched window are untested.
  • One run per cell. The medians of the speed columns at 512k and 1M rest on one measurement per configuration each, the answer times on two probes. The tier ranking (finding 3) is noise with that sample size, the order of magnitude of the answer times is not.
  • No YaRN scale beyond 4, no dynamic or LongRoPE variants, no continuous curve at constant quality: I measured two points, not the line.
  • Not measured: why k8v4 breaks down under parallelism — and whether it reproduces.
  • Production traffic kept running, at night mainly router and embeddings on the GB10. The timing probes of the stretched cells sit between 1,557 and 2,092 tokens per second — part of that spread is shop floor noise.

What I do with it

four index cards on a dark ground: What I can actually do with 1 M tokens.  cards: Answer time 13 to 15 min: one request, full, single session, 512k by contrast: 5.4 to 7 minutes; Needle rate 24 of 24: twelve cells, two probes each, 512k and 1 M, every probe found; Peak KV need: int8 at 1 M: 21.7 GiB, q4_0 would need 11.8 GiB; Two sessions: 512k: both k8v4 double cells fell, decode 8.7 and 12.8, not 47 tok/s
What I can actually do with 1 M tokens. Rope stretching · what it means in practice

Four sentences that remain from these two nights. First: 524,288 tokens are operationally ready for me — one request that fills the window takes 5.8 minutes and finds what it is supposed to find; that is a lookup job, not an interactive one. Second: one million tokens is doable and noticeably at the edge: 13.7 minutes per request, single-session, and the prompt lands practically against the stop (largest request processed: 1,048,479 of 1,048,576 tokens). From now on I plan windows with 5 to 10 percent headroom at the top, because the stop has edge problems — at native context a probe was missed there, in stretched context 12 of 24 probes had to be shrunk after an HTTP refusal. Third: q4_0 is the sensible tier for stretched context: 11.81 GiB instead of 21.66 at a million, and measurably level on answer time. Fourth: stretching is not a free window. As long as I need 131,072 tokens I take the native window with 66 seconds of lead time; the stretch does not cost the window, it costs the superlinearity behind it.

Open for the next night: the counter-test for k8v4 under parallelism, a quality task beyond the needle at 512k, and the million-token cell on the GB10. Once measured, I will write it up.

Artefacts

The measurements of this phase as open files: all figures as JSON (medians per cell, rope scale, individual needle results with prompt sizes and remarks, origin timestamps) and the cells as CSV (phase, platform, rope scale, KV tier, residency, window, sessions, prompt size, first token, prefill, decode, parallel throughput, needle hit rate, answer time). Part one of the series is here, including the full cell matrix of the KV axis.

The four figures at full size (1200 × 630): A million tokens takes one work step · The stretching itself costs nothing · Everything is still found — time is the price · What I can actually do with 1 M tokens.