Field notes on inference, evals and small language models.

I build and measure ML systems for a living. This is where I write down what worked, what didn't, and the numbers behind both.

Recent notes

Projects

tinyeval

A deliberately small evaluation harness: YAML task specs, deterministic sampling, diffable JSON reports. Built to run in CI without a GPU.

pythonevalsci

kvtrace

Records per-layer KV cache usage during generation and renders it as a timeline. Useful for sizing batch limits before they page you at night.

pytorchprofilingvisualization

quantdiff

Runs the same prompts through a full-precision and a quantized model and reports where the outputs diverge, token by token.

quantizationllmtesting

Notes

Your eval set is drifting, and that's fine

2026-09-28 · 4 min

Every eval set I've maintained for longer than a quarter slowly stopped describing production traffic. Freezing it forever gives you comparable numbers that no longer mean much; rewriting it every month gives you meaningful numbers you can't compare.

What has worked for me is a two-tier setup: a small frozen anchor set that never changes, and a rolling set rebuilt from a fresh traffic sample each month. Report both. When they disagree, that disagreement is the interesting part.

Speculative decoding on a single consumer GPU

2026-08-14 · 6 min

Pairing a 1B draft model with an 8B target gave a 1.7–2.1× speedup on chat-style prompts, and almost nothing on code completion. Acceptance rate is everything: when the draft model guesses badly, you pay for both models and get the speed of one.

Measure acceptance rate per task type before you ship it, not after.

What 4-bit quantization actually costs you

2026-06-30 · 5 min

Average benchmark scores barely moved. The damage was concentrated in a few places: long arithmetic, rare languages, and strict output formats. If your feature depends on any of those, average scores will tell you everything is fine right up until it isn't.

This is why I wrote quantdiff: look at where outputs diverge, not at the mean.

Watching the KV cache fill up

2026-05-02 · 3 min

Most out-of-memory incidents I've seen during inference were not caused by the weights but by a handful of very long requests sharing a batch with everything else. Plotting cache usage per request over time made the fix obvious: cap context per request and route long ones to a separate queue.

p50 lies: latency budgets for LLM features

2026-03-19 · 4 min

Users experience your p95, not your median. For streaming features, time to first token matters more than total generation time; for tool-calling agents, the sum of the slowest steps dominates. Set budgets per stage and alert on percentiles, not averages.

About

ML engineer working on inference infrastructure and model evaluation. Mostly Python and PyTorch, some Rust when latency matters. Opinions here are my own and usually backed by a notebook somewhere.

Not taking on new projects at the moment.