In 2025, DeepMind's AlphaEvolve made a specific recipe famous: wrap a large language model in an evolutionary loop and point it at problems where a better program is worth real money. The loop is simple: propose a code change, score it with an automated evaluator, keep what wins, mutate what was kept. The reported results ran from a new 4×4 complex matrix multiplication algorithm (48 multiplications, the first improvement on Strassen's 49 in that setting since 1969) to a ~0.7% recovery of Google's fleet compute and a 23% faster matmul kernel inside Gemini's own training stack. The same recipe, in different clothes, produced FunSearch's combinatorics results and AlphaDev's sorting routines that shipped into LLVM's standard library.
This project asks a smaller, sharper version of the question: does that recipe work on my laptop, against Apple's own inference stack, on silicon whose instruction set nobody outside Apple can read? Part 1 built the prerequisite: a measured map of where MLX leaves performance on the table: which operations, at which shapes, against ceilings my machine actually sustains rather than the ones on the spec sheet. This page is what happened when an evolutionary search was pointed at that map, three times.
The short version: the recipe works, and it is a power tool with no judgment. An evolved attention kernel now beats Apple's shipping implementation by 2.3×, reaching 80% of the hardware ceiling on an operation the stock stack ran at 34%. But the same loop, with the same mechanics, the same mutator family, and the same safety rails, returned 0.96× when its fitness function sat on a noise floor, and a kernel worth only 1.04× end-to-end when it was pointed at the wrong operation. The search executes a diagnosis; it does not produce one. Everything below is mined from the per-candidate logs: every score, every failure, and the parent-to-child code diff behind every jump worth naming.
Everything this recipe needs, GPU kernels have. An objective, automatic score: kernels are timed, not judged. A cheap, reliable correctness oracle: compare against a reference implementation on shapes the candidate has never seen. A search space too gnarly for gradient methods and too large for humans to sweep: tile sizes, memory layouts, thread mappings, and algorithmic restructurings interact in ways nobody can predict on undocumented silicon. That is exactly the regime where trying ten thousand things beats reasoning about one.
Classical genetic programming mutates programs blindly: flip a node in a syntax tree and hope. The modern recipe replaces blind mutation with a language model that has read every GPU programming guide ever written: it receives a parent program, the parent's measured scores per test shape, the error text of recent failures, and a system prompt carrying the project's hardware facts, then proposes a complete rewritten program. Selection stays classical: an archive keeps winners, parents are drawn from the archive, and losers are discarded but logged.
Two structures keep the population from collapsing onto its first good idea. MAP-Elites keeps the best candidate per region of a feature space (here, efficiency × code complexity), so a slow-but-novel approach survives next to the current champion instead of being culled by it. Islands evolve three sub-populations with occasional migration, so lineages can develop differently before competing. And because most mutations are simply broken, cascade evaluation kills them cheaply: a small correctness smoke first, the expensive full measurement only for survivors.
The controller here is OpenEvolve, an open-source implementation of the AlphaEvolve recipe: the MAP-Elites database, islands, cascade evaluation, checkpoint/resume, and the artifact channel that feeds failure text back to the mutator. Three properties made it the right base. It is model-agnostic: the mutator is whatever command you give it, which here means the same flat-rate CLI the rest of the project runs on, swapped between model tiers with one config line. It is inspectable: when a run stopped early or scored oddly, the answer was in readable Python, twice found by reading it. And it checkpoints, which matters on a machine that this project has crashed.
A campaign is a fitness function with a population attached. Each iteration: pick a parent from a MAP-Elites archive, hand the mutator the program, its measured scores per shape, and the failure text of anything that just died; get back a complete rewritten program; score it. Correctness runs first: an fp32 reference, ragged holdout shapes, both mask modes, and bit-determinism across calls. A candidate that fails any of it scores zero with the reason fed back to the mutator. Speed is measured paired against the shipping kernel, and anything beating the best-so-far faces the champion defense: the worst of three spaced re-measurements becomes its score.
The first target was chosen the intuitive way, which is the cautionary part: the mixture-of-experts feed-forward block moves the most bytes per decoded token, and the project's first audit (single-call timing, the only kind that existed yet) showed it well short of the bandwidth roofline. Big op, apparent headroom, obvious campaign. Both premises were wrong: the headroom was an artifact of timing operations in isolation, and the op was actually running at 90–97% of its ceiling.
Campaign #1 forced the two reforms every later run stands on. Timing moved to dependent chains: each sample a strip of 64 chained calls, the way generation actually executes. That collapsed the phantom headroom and re-drew the whole opportunity map. And promotion grew a noise gate: a would-be champion must beat the incumbent by more than max(2σ, 1%), then survive three spaced re-measurements with the worst run as its score. On the re-drawn map, one gap survived: decode attention, at 49–71% of its bandwidth roofline across product shapes while everything else sat above 85%. That is where campaign #2 went.
Campaign #2 produced a genuine kernel, 1.23× re-verified, and the project's most expensive pricing lesson: end-to-end it was worth 1.04×, because decode attention's roofline gap was large but its share of time was not. The value model built in response multiplies efficiency-gap by time-share, and it pointed somewhere else entirely: prefill attention at head-dim 256, running at 34% of the compute ceiling on the operation that dominates time-to-first-token. Two more prerequisites landed before launch: a control experiment separating the kernel deficit from the mask path, and a hand-written seed proving a fused Neural-Accelerator kernel could beat the fallback at all: 1.31×, after a first attempt on the wrong silicon lost at 0.37×.
| candidate | minutes / call | output tokens | score (seed = 1.312) |
|---|---|---|---|
| opus 1 | 20 | 88k | 1.4673 |
| opus 2 | 19 | 86k | 1.4216 |
| sonnet 1 | 9 | 53k | 1.3013 |
| sonnet 2 | 20 | 112k | 1.3063 |
Findings. The AlphaEvolve recipe does transfer to a single laptop and a proprietary stack: an evolved fused attention kernel runs at 80% of my machine's measured compute ceiling where Apple's shipping path ran at 34%, and it survived every gate built to kill it: ragged holdout shapes, bit-determinism, fresh-process re-verification, and an end-to-end A/B with output-quality checks. Combined with a one-line tile fix found by reading MLX's dispatch source and the chunk-size raise the kernel's own memory savings unlocked, time-to-first-token on a 32k-context 35B model fell from 70.2 s to 35.5 s on my laptop. Both fixes are offered upstream. The search's genuine inventions (the kv-head-major dispatch order, the in-place score tile, the output-validated runtime autotune) are things no prompt asked for.
Lessons. Three campaigns, three grades of the same loop, and the grade tracked the measurement discipline, not the mutation engine. A search with a noisy fitness invents staircases out of nothing (campaign #1, re-verified at 0.96×). A search pointed at the op with the biggest efficiency gap rather than the biggest share of time optimises the wrong thing beautifully (campaign #2, a real 1.23× kernel worth 1.04× end-to-end). And even a winning campaign's champion is only a claim until it passes gates the search never saw. The bf16 incident, where a perfectly bound integration computed fluent garbage at speed, is the cleanest argument this project can offer that invocation is not correctness and speed is not truth. The evaluator is the product; the kernels are the receipts.
Next. The remaining headroom splits cleanly into two different problems. Sustained generation is nearly done: the decode step already runs at 91% of my machine's measured memory bandwidth, so no kernel rewrite can buy more than single digits. The one real lever left is fusing the dozens of launch-bound micro-ops (norms, rotary, routing) whose cost is being separate kernels at all, worth perhaps 7%. Time-to-first-token still has real ground: of the 35.5 s, the matrix multiplies are saturated and attention now sits at 80% of ceiling, but the gated-delta-net recurrence, the linear-attention layers' state update, runs at 3% of both ceilings at once, because its shipping kernel is a long chain of sequential dependent steps: a formulation problem, not a tuning problem. The chunked delta-rule algorithm from the linear-attention literature is the known fix, and early attempts confirmed it must be a hand-written fused kernel: every ops-level expression loses to the incumbent before any search could tune it. That kernel is the next seed, worth ~3 s; a small fused output-norm is worth ~1.5 s more; together they point at roughly 30 s. Hybrid architectures like this one are the direction the field is moving, so the kernel outlives the model that motivated it. Beyond my desk: shepherding the two upstream contributions: mlx#3924, a static_assert closing the silent no-op that returns zeros at full speed, and mlx#3925, the routed-expert tile fix with its measurements. Also on the list: validating portability on other Apple Silicon tiers. The technique transfers; the kernels are shape-specific and will age out. That asymmetry is the reason Part 1 and this page lead with method.