Private Intelligence

The first 10 million GPU memory requests were the wrong sample

A fixed-size prefix covered as little as 0.34% of a decode step. Processing the complete streams changed the locality story without changing a single hardware-counter total.
By Moussa Ba · August 2026 · ~11 minute read · GPU memory measurement
Editorial illustration of a GA102-class desktop GPU feeding a long memory-request stream. A magnifying glass and inset examine only a tiny regular prefix while a different, expanding phase appears much later.

I thought compilation had nearly quadrupled the sequentiality of one model's GPU memory stream. The number was 15.90. It was clean, repeatable, and supported by ten million memory requests.

It was also based on the first 2.13% of the decode step.

When I processed the complete stream, 15.90 became 7.79. The Llama TensorRT-LLM INT4 engine moved further: 10.81 became 3.37, almost back to eager Llama execution. Nothing about the model, GPU, cache filter, or full-step hardware-counter totals had changed. I had measured the beginning accurately and mistaken it for the whole.

TL;DR
  • A fixed first-10-million-request sample represented only 0.34%–6.84% of the complete post-L2 streams across ten workloads.
  • The bias was positional, not merely “too small.” It favored the early GEMM-heavy region and missed late phases such as the unquantized lm_head.
  • Matched BF16 compilation still improved whole-step run locality by 2.44× (3.19 → 7.79). The original “nearly 4×” number was true only inside the early GEMM-dominant region.
  • All hardware-counter totals and quantization's 3.22× read-volume reduction remain unchanged. The correction is to descriptive address-distribution claims, not to the measured byte totals.
  • The practical rule: if execution has phases, a first-N prefix is a position, not a sample.
Four terms used below
GA102 (RTX 3090)
The GPU used as the capture vehicle in this experiment. “GA102” names the NVIDIA GPU die; the card on the rig is an RTX 3090.
Llama TensorRT-LLM
A compiled Llama-3.1-8B engine built with NVIDIA TensorRT-LLM.
Post-L2 request stream
The 32-byte sector addresses that the replay model sends toward device memory after applying its cache model to captured SM-side requests. It is a modeled boundary, not a native DRAM command trace.
effR
Effective consecutive run length: accesses divided by maximal +32-byte sequential runs, broken by an address discontinuity or read/write turnaround. Higher means longer consecutive runs. It is a descriptive address-stream statistic, not the DRAM's measured row-hit rate.

The number that looked like a conclusion

The experiment began as a determinism ladder. I ran the same Llama-3.1-8B decode step three ways on the same GA102 (RTX 3090): eager BF16, a compiled Llama TensorRT-LLM BF16 engine, and a compiled Llama TensorRT-LLM INT4-AWQ engine. CUDA graphs were disabled for instrumentation. The compiled engines reduced the launch population from 1,563 to 273 and 305, and their kernel schedules repeated exactly across captures.

The first address-level result looked wonderfully legible:

3.76
Llama eager
first 10M effR
15.90
Llama TRT-LLM BF16
first 10M effR
10.81
Llama TRT-LLM INT4
first 10M effR

That shape fit the software story. Compilation fused work into a compact engine plan and produced long regular address runs. INT4 changed the kernels and phase texture. The traces were deterministic across repeated captures. The numbers even passed the preregistered calibration-versus-held-prefix stationarity gate.

The mistake was subtler than a broken counter. The gate answered whether two halves of the same early prefix agreed. It did not answer whether that prefix represented the entire decode step.

What effR counts Each square is one consecutive 32-byte sector. A gap starts a new run. R = 1 four isolated accesses → four runs R = 4 four consecutive sectors → one 128-byte run R = 16 long contiguous movement; fewer run boundaries
A run ends when the address jumps or the stream turns from reads to writes (or back). effR summarizes contiguity; it does not identify the cause.

The first 10 million was a compute budget, not a sampling design

Ten million records was a practical early choice. It was large enough to expose repeatable phase structure and cheap enough to run repeatedly while the tracing and replay machinery was still changing. The dangerous step came later: I let “large” become a synonym for “representative.”

The complete recuts made the denominator visible. Ten million requests covered less than seven percent of every step, and less than three percent of six of them. For OpenVLA, it covered 0.34%. For eager Llama it covered 2.09%; for Llama TensorRT-LLM BF16, 2.13%.

Workloads in this study

The roster deliberately spans language generation, autonomous driving, and robot-control workloads. Multiple rows from one model family represent different execution configurations or stages.

Model familyWhat it doesWhat was measured
GraniteLanguage-model inferencectx-62 and ctx-2048 decode windows
Llama 3.1 8BLanguage-model inferenceEager execution, Llama TensorRT-LLM BF16, and Llama TensorRT-LLM INT4-AWQ
Gemma-4 E4BLanguage-model inferenceOne decode-step window
OpenVLAVision-language robot controlAction-generation window
AlpamayoAutonomous-driving reasoningReasoning decode window
GR00TVision-language-action robot policyS1: diffusion-transformer action-head denoising. S2: vision-language backbone forward pass used for reasoning.
Horizontal bar chart showing that the first ten million requests cover between 0.34 and 6.84 percent of each complete stream.
The fixed prefix was never a fixed fraction. Each bar is the same 10M records divided by that workload's complete post-L2 stream.
GA102
(RTX 3090)
same workload execution
SM request tracewarp-level memory requests
Frozen L1/L2 replaypost-L2 sector stream
First 10Mposition-biased prefix

This distinction matters because neural-network execution is ordered. A decoder does not draw kernels independently from a bag. It walks through phases: attention, projections, copies, output heads, sometimes image towers or action heads. A prefix has a fixed position inside that schedule. Adding more records only makes that position more precisely measured.

If execution has phases, the first N requests are a location, not a sample.

The complete streams changed the locality story

Across the roster, the prefix usually overstated effective run length. The compiled Llama legs moved the most: BF16 fell from 15.90 to 7.79, while INT4-AWQ fell from 10.81 to 3.37. Eager Llama moved from 3.76 to 3.19. Gemma, Alpamayo, and Granite ctx-2048 all moved downward too.

But this was not a universal “prefixes are optimistic” rule. The GR00T S2 reasoning stage moved in the opposite direction, from 2.25 to 2.84, because its write-heavy back half was under-represented in the prefix. OpenVLA barely moved at all, from 3.97 to 3.90, and became the clean control: its body really was phase-homogeneous at the scale this statistic could see.

Slope chart comparing prefix and full-step effective run length for ten workloads. Most fall, GR00T S2 rises, and OpenVLA stays nearly flat.
A filled point is the full step. The opposite-direction GR00T S2 result and stable OpenVLA control rule out a convenient one-direction correction factor.

The missing phase was sitting at the end

The Llama mechanism is visible without a statistical model. Eager execution spends most of the step near four-sector runs, then drops into a short-run tail. The compiled BF16 engine holds a plateau near sixteen sectors for most of the step. The compiled INT4-AWQ engine holds a plateau near eleven. Then both encounter a late output-head phase.

That tail is the unquantized lm_head: the final projection from hidden state to vocabulary logits. It contributes about 7.0% of BF16 bytes and 22.5% of INT4-AWQ bytes. As the INT4 engine shrank the quantized backbone, the unquantized tail's share grew from marginal to 22.5% of all bytes. A 10M prefix at the start of the step could not possibly observe it.

Three aligned line charts across one complete decode step. Eager Llama has roughly four-sector runs and a short-run tail; Llama TensorRT-LLM BF16 and INT4 have long plateaus followed by late short-run output-head cliffs.
Amber marks the true width of the first 10M records. The ribbons are descriptive address-level diagnostics; they are not native DRAM row-hit measurements.

The corrected whole-step comparison is still interesting, just less theatrical. Matched BF16 compilation increases effR from 3.19 to 7.79, a 2.44× gain. That is a substantial software-stack effect on memory-request shape. It is not the nearly 4× claim implied by the early region.

The INT4 result is sharper. Full-step hardware counters measured device reads falling from 15.044 GB to 4.671 GB per step, a 3.22× reduction. But its whole-step effR returned to 3.37, nearly eager's 3.19, because the output head did not shrink with the backbone. Quantization improved volume while exposing a different locality bottleneck. “Less traffic” and “more sequential traffic” were never the same claim.

What the correction changed and what it did not

Changed

  • Whole-step effR values and row-hit-floor descriptions
  • The “compilation nearly quadruples run length” framing
  • Any implication that the compiled step was phase-homogeneous
  • The magnitude of downstream window-based memory-replay comparisons

Unchanged

  • Full-step hardware-counter byte totals
  • Compilation's deterministic kernel plan under the fixed contract
  • The 3.22× INT4 read-volume reduction
  • The original 10M fit/validation record, still valid at prefix scope

This is the part of correction work that is easiest to mishandle. Discovering a sampling flaw does not license throwing away every result from the campaign. It requires tracing each claim back to the quantity that supported it. Hardware counters covered the complete profiled step, so those totals stand. The prefix statistics described the prefix, so they keep that scope. The correction is not “the experiment was wrong.” It is “one descriptive statistic escaped its denominator.”

The control that matters. OpenVLA's prefix was the smallest share of any complete stream at 0.34%, yet its effR barely changed. That is evidence that sample position and phase structure, not coverage percentage alone, determine bias. A tiny prefix can be representative of a homogeneous body. A larger prefix can still miss a late regime change.

The checks I would require now

  1. Record the denominator. Every prefix artifact should state both its record count and its percentage of the complete execution.
  2. Plot position before averaging. A hundred normalized windows across the full step expose phase cliffs that a single aggregate hides.
  3. Keep one stable and one opposite-direction control. They prevent a convenient global correction factor.
  4. Separate measured totals from descriptive address statistics. A sampling correction to effR says nothing by itself about a full-step hardware byte counter.
  5. Scope formal gates exactly. The 10M stationarity tests remain legitimate prefix tests. They do not become whole-step tests because the prefix happened to be repeatable.
Measurement boundary. These streams come from a GA102 (RTX 3090) execution trace passed through a frozen cache replay model. They are useful for comparing address structure inside this research lineage. They are not Thor-native traces, architecture-neutral workload descriptions, or native DRAM command streams. The write path is not validated for point prediction, so this post makes no energy claim.

The larger lesson is about phases, not prefixes

The first ten million requests were not useless. They helped build the tracer, expose repeatable kernel states, and preregister tests that could fail. Their failure came from a promotion: a development window quietly became a description of the workload.

Full-stream processing did not merely produce better averages. It showed why summary-statistic traffic generators kept failing later validation. The missing information was not another marginal histogram. It was sequence: which phase appears when, how long it lasts, and what follows it. A synthetic generator faithful enough to reconstruct that order begins to look like compressed replay of the trace itself.

That leads to the next boundary. Even the complete post-L2 stream is not “the workload.” It still carries the kernel choices, memory layouts, allocator behavior, and library dispatch of the capture stack. A full trace fixes the sampling problem. It does not make the trace portable.

Caveats