Every token an LLM samples is a quantization step. The model produces a probability distribution over its vocabulary; the sampler collapses that distribution into a single choice; the difference between the two is sampling error. Image processing has spent five decades studying where to put exactly this kind of error, and the answer it converged on was never white noise.

This article connects three pieces of work: an error diffusion technique that generates high-quality blue noise without precomputed tables, a random number generator built on it, and a llama.cpp patch that uses that generator for token sampling. Each step is small. Together they put a well-understood body of signal processing underneath a part of LLM inference that has mostly been left at its defaults.

01Sampling Error Is Quantization Error

Halftoning collapses a continuous tone into discrete pixels. What separates a good halftone from a bad one is not the amount of error, which is fixed by the bit depth, but where that error sits in the spectrum. Push the energy into high frequencies and the eye integrates it away; leave it in low frequencies and it reads as blotches and banding. Noise with the desirable shape, rising at roughly +6 dB per octave, with neighboring values anticorrelated, is called blue noise. Error diffusion algorithms such as Floyd-Steinberg produce it constructively: each pixel's quantization error is subtracted from its neighbors before they are quantized, so every local excess immediately corrects itself.

Token sampling faces the same collapse, and the standard sampler draws its randomness from white noise: every draw independent, all frequencies equally loud. Independent draws clump. A few high draws in a row dig into the tail of the distribution repeatedly; a stretch of low draws locks onto the head. In generated text those clumps have familiar names, degeneration in the literature: rambling, drift, flat passages that never end, and at the extreme the repetition collapse, where generation locks onto one word and repeats it until the context runs out. Temperature trades off the head against the tail but cannot escape the clumping: it reshapes the distribution but not the color of the noise behind the draw.

Bit streams at the same densityDetails
1s and 0s at the density you choose. In the first panel every row is a stream of independent white noise draws; in the second every row is its own blue noise RNG, thresholded at the same level. Runs of five or more identical bits are highlighted. The last panel is two-dimensional blue noise at the same density, from kernel-switching error diffusion. The noise source applies to every lab below except the tree walk: the seeded lowbias32 hash used throughout, or the system's cryptographic generator.
The bit streams, waveforms and spectra on this page are generated in your browser by a line-for-line port of the C reference generator, checked sample for sample against it. The white noise comparisons use the same underlying hash, unshaped.
White noise
Blue noise (1D)
Blue noise (2D)
10run of 5 or more

02Blue Noise Without Lookup Tables

The starting point is an image dithering result: stochastic kernel-switching error diffusion. Standard error diffusion kernels each produce characteristic periodic artifacts. Switching per pixel between two proven kernels, Floyd-Steinberg and Jarvis-Judice-Ninke, with a low-bias integer hash deciding each switch, disrupts the periodicities of both while injecting far less white noise than perturbing thresholds or weights. The measured spectrum sits almost exactly on the theoretical +6 dB per octave blue noise curve, with good isotropy.

Floyd–Steinbergweights ÷ 16 X7 351 Jarvis–Judice–Ninkeweights ÷ 48 X75 35753 13531 hash bit picks the kernel at every pixel X is the pixel being quantized; the weights say where its error goes.

What matters for everything downstream is that the technique is generative. Classical blue noise comes from precomputed threshold tables such as void-and-cluster arrays; this technique produces it on the fly from a running error state and a hash, in integer arithmetic, with constant memory.

03A Generative Blue Noise RNG

A random number generator needs the one-dimensional, temporal version of the same idea. That reduction is a single ditherer that alternates between two kernels: a tight one that forwards all error to the next step, and a spread one that defers part of it further. An exhaustive search over the spread kernel's weights found the best partner for the tight kernel at [46, 2] out of 48: 46 parts to the next step and the remaining 2 to the one after. Switching between [48] and [46, 2] reaches a +5.67 dB per octave average slope for a single ditherer.

The settled design abandons the fractions altogether and gains something better than slope. It routes the entire quantization error to either t+1 or t+2, decided by one bit of white noise per step: kernel switching taken to its extreme, where the two kernels are simply "everything now" and "everything later." With binary routing, the ditherer reduces to an integer state machine with just five reachable states across its two error slots.

t t+1 t+2 bit 1 · 48⁄48 bit 0 · 46⁄48 bit 0 · 2⁄48 found by exhaustive search[48] or [46, 2]tight or spread t t+1 t+2 bit 1 · 48⁄48 bit 0 · 48⁄48 the settled design[48, 0] or [0, 48]everything now or later

A ditherer, though, produces bits, not values: a 1-bit stream whose long-run density matches its input level. The step that turns dithering into a random number generator is population splitting, first worked out in two dimensions to build multi-bit dither patterns one bit layer at a time. A uniform random value is a stack of fair coin flips: each bit splits the remaining range in half. Watched over time, every one of those splits is a 50% duty cycle stream, which is what a ditherer handles. Every side of every split is a population: the samples that share the same higher bits. Give each population its own ditherer and the flips stop clumping at every scale at once: the output is a full-range value, evenly distributed, and thresholding it at any level yields blue noise.

In the generator these populations form a binary tree of five-state ditherers: 2^N − 1 nodes for N bits. Binary routing makes the tree cheap. In two dimensions, diffusion is spatial, so every population at every depth has to be computed in full. Here, a population that is not part of the current value simply waits, and the waiting is only possible because of the binary kernels: a fractional kernel branches into more possible error states with every flip, while full-error routing stays within the same five states however many flips pass. And since each visit consumes a fresh white-noise routing bit (a single hash per sample supplies all of them), a node's behavior depends only on its own visits, never on the steps in between: there is nothing to catch up on. An N-bit sample walks a single root-to-leaf path and touches exactly N nodes. A 16-bit tree holds all its state in 131 KB (two bytes per node) and uses no floating point, no division, and no tables. The root sees every sample and the deepest nodes see the fewest, so significance and noise quality line up. Each output is a 64-bit word whose top 16 bits carry the blue noise; plain white noise fills the rest so the 16-bit grid never shows through.

Walk the treeDetails
A 3-bit generator: seven ditherers. Each step hashes once, then walks one root-to-leaf path, letting every node on the path decide a bit and route its error. Node labels are the two error slots, err0 · err1.
Hash
—
step to begin
Output
—
Rule
bit = err0 ≥ 0
error = err0 + (bit ? −1 : +1)
hash bit 1 → t+1, 0 → t+2
LevelNodeBeforeBitErrorRouted toAfter
Last 32 outputs, 0 to 7consecutive values repel

The underlying white noise source is pluggable: lowbias32, MT19937, and PCG64-DXSM backends all produce identical spectral quality. Measured over 67 million samples of its 16-bit output, the complete generator maintains a +5.1 dB per octave spectral slope, fitted from 0.01 to 0.1 of the sample rate, with at most 0.10% deviation from a uniform distribution.

Spectral slope
+5.1 dB/oct
67 million samples
Uniformity
≤ 0.10%
deviation from uniform
Ditherer states
5
reachable per node
16-bit tree
131 KB
2 bytes per node
An 8-bit noise waveform, liveDetails
The same generator run as audio: samples on the scope, the averaged spectrum below. White noise is flat; blue noise rises with frequency and its neighbors repel, so the trace zigzags instead of wandering.
White noiseindependent draws
Blue noisethe RNG above
Averaged spectrum, dB against frequency
whiteblue16-sample moving average (top) · +6 dB per octave (spectrum)
The slope is fitted live from 65,536 samples over 0.01 to 0.25 of the sample rate, a wider range than the figure above, so it reads a little lower. Listening is optional and starts quiet.

04Blue Noise in llama.cpp

llama.cpp PR #19409 adds a --blue-noise sampling option. The mechanism is minimal: candidate tokens are sorted by probability, and the blue noise generator supplies the draw that selects among them, in place of the standard white noise draw, at a cost per token of two white noise words and a few integer operations for each of the value's 16 bits.

The behavioral consequence: consecutive draws repel. After the sampler takes a risk deep in the distribution's tail, the following draws stay near the head; after a conservative stretch, exploration comes due. It is error diffusion on the draws themselves: deviations pay themselves back locally instead of compounding. The working hypothesis carries over the masking argument from graphics. A language model integrates its context, so a single unusual token gets absorbed and reinterpreted, much as the eye absorbs high-frequency pixel error. What context cannot absorb is clumped deviation: several risky tokens in a row steering the text somewhere the model then commits to. Blue noise moves sampling error out of the frequencies that hurt.

Draws from a made-up distributionDetails
Eight candidate tokens sorted by probability. Each cell is one sampler draw: teal is the top token, amber is a moderate risk, red is deep in the tail. This is an illustration with an invented distribution, driven by the real generator. Coloring draws by rank follows GLTR, which colors the words of a text by their rank under a model to show that generated text over-samples the head. A rank histogram is blind to order, which is why the readouts here are run lengths: blue noise changes when the tail is visited, not how often.
Candidate probabilities46 · 20 · 12 · 8 · 6 · 4 · 3 · 1 %
White noise draws
Blue noise draws
top token2nd or 3rdtail, 4th or lower

On Falcon 7B, an older base model from before synthetic training data became widespread, the early qualitative results all point the same way: noticeably less high-temperature rambling, fewer stock-phrase loops, readier use of uncommon vocabulary, documents that reach their natural end rather than meandering, and far fewer repetition collapses. That last one is the mechanism at its clearest: a loop begins as a run of same-way draws that lets a token feed its own probability, and runs are what blue noise pays back before they form.

Attribution

Implementations derived from this article, in any language, must keep a reference to it: the address https://polyverse.dev/articles/bluenoise-sampling.html, credit to Jan Boon (Kaetemi), and this requirement itself, so that the reference is carried into whatever is derived from them in turn.

The sampler is also integrated in friend.cpp, the inference engine Ava (Solenopsisbot) builds downstream of koboldcpp, adapted from the llama.cpp branch.

05Running Live

Polyverse runs its AI characters on this today, and the sampler has already retired a workaround from the production stack. Ruri, the first of those characters, speaks through a Llama 3 base model, and newer bases like it carry enough synthetic assistant text in their pretraining data to form an attractor. On Llama alone under white noise, output slips into standard assistant phrasing: capital letters and sentence-final periods creep into a character who writes in lowercase chat, and once a few of those tokens land in context the pull compounds. The register itself is not the failure — a character switches modes deliberately all the time; the failure is capture, where the character stops being able to switch back. A hybrid inference setup pairing Llama 3 with Falcon 7B was previously used to avoid this. With blue noise sampling the slip just does not happen: the hybrid is no longer needed and Ruri can run directly on Llama 3. That is consistent with the mechanism, since capture by the attractor begins as a run of correlated deviations, and runs are exactly what blue noise breaks up.

The same sampler drives every instance of Aoi, Polyverse's second character, across six thousand Discord servers.

06First Benchmark Results

Most standard evaluations barely exercise the sampler. Perplexity is measured against fixed reference text, multiple-choice suites compare answer likelihoods, and generative benchmarks are usually decoded greedily for reproducibility: the sampler is bypassed in every case, so a sampling change is invisible by construction. Reasoning models are the exception. They degrade under greedy decoding and are meant to be run sampled, so every chain of thought is sampled generation from end to end, with final-answer accuracy scoring the whole trace objectively.

A first run used MATH-500 on a DeepSeek-R1 Qwen distill, answers scored by math-verify. Discordant counts the problems where exactly one of the two samplers succeeded, the flip ratio splits those wins blue against white, and p is from McNemar's test on that split:

Sampling configWhiteBlueΔDiscordantFlip ratiop
top-p 0.95, temp 0.692.4%94.0%+1.6%30 19:11
~0.20
min-p 0.02, temp 0.894.0%93.8%−0.2%19 9:10
1.0
min-p 0.01, temp 0.9592.4%94.0%+1.6%18 13:5
~0.10
problems only blue solvedproblems only white solved

In the min-p 0.01 configuration, blue noise won 13 of the 18 problems where the two samplers disagreed. Blue noise also held nearly the same score in all three configurations (94.0, 93.8, 94.0%), where white noise moved between 92.4 and 94.0%. At 500 problems a swing of eight is about one standard error, and no p-value here is below 0.05: these are first signals, which is what the evaluation at scale is for.

The next step is to run these benchmarks at scale: across seeds, temperatures, and model families, against both white noise and existing anticorrelated baselines, with long-form coherence and repetition metrics, and with human preference studies.

07Scaling the Evaluation

Polyverse is seeking partners, grants, and research collaborations to run this evaluation. Reach us at [email protected].

08The Rhythm of Human Text

Two passages with every word colored by its rank under GPT-2. The human-written one mixes green, yellow, red and purple; the generated one is almost all green.
Figure 1 of GLTR (Gehrmann, Strobelt and Rush, ACL 2019, CC BY 4.0). Each word is colored by its rank under GPT-2: green in the top 10, yellow in the top 100, red in the top 1,000, purple beyond.

GLTR makes the difference between human and generated text visible by coloring tokens according to their rank under a language model. Its generated examples lean heavily toward the model's most likely choices; the human examples mix in more unexpected ones. Looking at those colors alongside the sampling strips above, there is a suggestive resemblance to the contrast between white and blue noise: stretches of predictable choices versus a more interspersed mix.

The hypothesis is that some of the difference between human and the measured generated text may be related to the temporal structure of sampling. A model reads its own choices as context, so the order in which predictable and surprising tokens arrive can influence the probabilities that follow. Blue noise could change that feedback by spreading exploration through the sequence. Comparing the token probabilities, ranks and run lengths of human text with white- and blue-noise generations would give that visual connection something measurable to follow.

09References

  1. Jan Boon (Kaetemi), "Stochastic Kernel-Switching Error Diffusion," blog.kaetemi.be, 2026.
  2. Jan Boon (Kaetemi), "Blue noise RNG for token sampling," llama.cpp pull request #19409, 2026.
  3. Ava (Solenopsisbot), "friend.cpp: Blue-noise sampling," an inference engine downstream of koboldcpp with the sampler integrated, 2026.
  4. R. W. Floyd, L. Steinberg, "An Adaptive Algorithm for Spatial Greyscale," Proceedings of the Society for Information Display, 1976.
  5. J. F. Jarvis, C. N. Judice, W. H. Ninke, "A Survey of Techniques for the Display of Continuous Tone Pictures on Bilevel Displays," Computer Graphics and Image Processing, 1976.
  6. R. A. Ulichney, "Dithering with Blue Noise," Proceedings of the IEEE, 1988.
  7. A. Holtzman, J. Buys, L. Du, M. Forbes, Y. Choi, "The Curious Case of Neural Text Degeneration," ICLR 2020. Degeneration, and the repetition loops of sampled decoding.
  8. S. Gehrmann, H. Strobelt, A. M. Rush, "GLTR: Statistical Detection and Visualization of Generated Text," ACL 2019, system demonstrations. Words colored by their rank under a model; generated text over-samples the head.