EvoWeights
A simple method for efficient AI model fine-tuning

EvoWeights.

(R-)Evolutionary Weight-Space Fine-Tuning

EvoWeights combines AI-engineered weight-space programming with evolutionary weight-space fine-tuning of quantized model weights. Define a measurable goal. A frontier AI model helps prepare the model and it's task interface using weight-space programming, and evaluation criteria. EvoWeights then searches for better weight configurations through mutation and selection, without further LLM calls.

In this experiment, it adapts NVIDIA Kumo-Tabular Small by evolving selected output weights and sensor-controller weights while keeping the transformer backbone frozen. Candidates compete through simulated gameplay; new revisions are retained only after passing fresh-seed validation and lineage checks.

No backpropagation or GPU is required for browser training. The model uses 96 labelled examples as context; simulated gameplay supplies the optimization feedback.

Watch a 27M-parameter model adapt to a DOOM arena, live on your CPU.

  • GPUWe don’t need a GPU here. Modern CPUs with SIMD instruction sets are fast enough for small model inference.
  • VRAMEvoWeights mutates model weights directly: no backpropagation, no Adam/Muon optimizer.
  • Large labelled dataset96 labelled example rows serve as context. Simulated gameplay supplies the optimization feedback.
  • LoRA adapterNo back-propagation-based low-rank training. No model fusion.

Outperforms Astra 6 + Opus 5.5 on weight-space programming in this experiment. Fast training on your CPU for free!

Evolutionary Weight-Space Fine-Tuning in ActionSCHEMATIC
Evolution For AI Models:
A parent model spawns mutants; the best candidate replaces it only after it passes validation against the parent.
    Weight raised Weight loweredMutants 0Kept 0
    • Runs On CPUEvery CPU core runs AI model evolution simulations in parallel.
    • Uses System RAMAbout 140 MB per parallel game; total memory grows with the number of workers.
    • AI-Engineered MetricAgentically engineered by a frontier AI model, a metric is defined from goals stated by a human in plain language.
    • Weight-Space ProgrammingAn AI agent prepares the task interface and search space; evolution searches for better weight configurations.

    00 EvoWeights in three steps

    1. 1Define survival

      A metric decides what “survival” means for a decidable task. A secondary metric is checked for deterioration before a candidate is retained.

    2. 2Mutate and compete

      Thousands of slightly mutated copies compete on your CPU; the metric scores their forward-pass results.

    3. 3Select and inherit

      Only candidates that pass the statistical selection checks are retained. Then the cycle repeats.

    01 Live experiment

    HuggingDOOM

    BROWSER INFERENCE

    You or the AI - together in a box with hungry yellow bears 🐻 They really love honey! 🍯 You have 26 honeycombs in your hands. What could go wrong? 😆

    STATUS: STANDBYPUREDOOM

    Active Awaiting actionDecisions/sec —

    CHOOSE A MODEL

    ORIGINAL
    Base Model FP32

    Original pretrained FP32 model, without task-specific weight updates, guided by 96 demonstration rows.

    EvoWeights Hugginator

    A model trained for most feeding + hugging via direct evolutionary weight updates. See its measured HuggingDOOM performance below.

    EvoWeights Introvertor

    A model trained for longest game time via direct evolutionary weight updates. Try transferring its learned behavior to this meadow.

    Opus 5.5 Weight-Space Programming

    A fresh Claude Opus 5.5 agent wrote the sensor weights directly, without seeing earlier values.

    Astra 6 Weight-Space Programming

    OpenAI Astra 6 edited 256 action-row weights and wrote the sensor weights directly, without training.


    Honey first. Panic-hugging next.

    Walk through the flowers. Feed the bears. Make a very silly picnic.

    Fine-tune your own model!

    Loading your models …

    Preview frame

    HEARTS—
    HONEYCOMBS—
    BEARS FED—
    BEARS BEFRIENDED—
    TIMES BITTEN—
    PICNIC TIME0:00

    Action logits

    Awaiting first inference
    —Bear sensors awaiting a game
    BEAR MASK9 REGIONS

    Picnic state

    Honey / Hugs · —Memory · —
    Facing guard · awaiting first decision
    MUSIC

    Like the game music?

    Aron also makes music in his spare time. Take the HuggingDOOM theme with you, or listen to more of his tracks.

    ⤓ Download the game music (MP3, 5.3 MB)
    Ad
    Portrait of Aron Homberg

    Want a small model that learns your task?

    Aron Homberg is an independent AI researcher, formally trained Computer Science Expert (C.S.E.), and software engineer with over 20 years of professional experience. He created EvoWeights, an evolutionary method for direct neural network weight optimization without backpropagation.

    His research focuses on small, quantized, and on-device AI models, evolutionary optimization, fine-tuning without backpropagation, efficient inference engines, and agentic AI systems.

    His technical interests and expertise span custom embedding and reranking models, hybrid and vector search (including late interaction), image similarity search, knowledge graphs and graph-based retrieval, speech recognition (ASR) and synthesis (TTS), multimodal image and video understanding and generation, and high-performance, cross-platform AI inference.

    He actively develops open-source AI systems, with particular emphasis on efficient CPU and browser-based execution, and welcomes international research collaborations and professional consulting engagements.

    02 Evolution history

    Model Inheritance Tree

    STORED IN THIS BROWSER

    Every model sits under the parent it was trained or edited from. ★ marks the parent of the next training run, ▶ the model in play. Models trained in this browser appear here and stay stored only in this browser.

    Loading …
    Model
    Rank
    Performance
    Parent
    Δ Parameters
    Actions

    PureDOOM runs locally with new meadow and bear artwork, honey and hug mechanics. The engine retains internal action names for model compatibility. Archived DOOM and native ViZDoom results below describe the earlier task and are not HuggingDOOM scores.

    03 Architecture

    Understanding the Weight-Space Edited Architecture

    TWO PATHS · ONE ACTION
    Original Kumo vs. the model after Weight-Space Programming

    Original Kumo-Tabular Small FP32 · as published

    1. Input14 game numbers + 96 labelled examples
    2. Transformer12 in-context layersreads the game state against the examples
    3. Head10 rows × 1,024 weights → 10 scoresrows 0, 1, 2 are used as LEFT, RIGHT, FIRE
    4. ActionHighest score winsturn left, turn right or fire; never moves

    After Weight-Space Programming 4-bit · Astra 6, then evolution

    1. Kumo path
    2. Input14 game numbers + 96 labelled examples
    3. Transformer · frozen12 in-context layers, 4-bit
    4. Head rows 0–23 scores: LEFT, RIGHT, FIREAstra 6 edited 256 FIRE weights; evolution mutates all 3,072
    1. Controller path
    2. InputGame state
    3. Controller code · hand-writtenNamed sensorsaim error, proximity, closing in, enemy memory, rear blocked, …
    4. Sensor weights · 119 valuesWeigh sensors into action scoresEvery decision, each action gets score = scale × Σ (weight × sensor) from the current sensor values; the weights stay fixed during play.
      • Aim13 sensors → LEFT, RIGHT, FIRE, BACKWARD52 weights
      • Combat11 sensors → LEFT, RIGHT, FIRE, HOLD, BACKWARD, FORWARD66 weights
      • Facing guard1 sensor → back vs. forward1 weight
      Evolution mutates all 119 weights
    ActionHighest score winsLEFT, RIGHT, FIRE: transformer score + sensor-weight score. HOLD, BACKWARD, FORWARD: sensor-weight score only.
    04 Model mutations

    Understanding EvoWeights’ Model Mutations

    167 MUTABLE BLOCKS

    The pretrained backbone stays frozen; selected weights in its output head are evolved. A mutation only nudges weights at the very end: the three output rows that decide LEFT, RIGHT or FIRE, and 119 small extra weights that read named game sensors. Everything before that, including all 12 transformer layers, is never touched.

    Where each step changes the model
    InputGame state14 numbers: enemy bands, ammo, health, last action
    Backbone · frozenKumo-Tabular Small27.45 M weights, mostly 4-bit, incl. 12 transformer layersnever mutated
    evolution mutates only here167 blocks
    Output rowsLEFT · RIGHT · FIRE3 × 1,024 weights of the model’s own final layerAstra 6 selected rows 0, 1 and 2 of 10, labeled them LEFT, RIGHT and FIRE, and edited 256 weights in FIRE via Weight-Space Programming
    Sensor weights3 small extra matrices119 weights on named game sensors, added to the action scoresAstra 6 added them directly via Weight-Space Programming
    OutputAction17.5 times per game second the highest of the three scores wins: LEFT or RIGHT turns the player, FIRE shoots or punches. The sensor weights can add a step forward or back, e.g. to close in for a punch and retreat.

    One mutation moves about half of 167 blocks by ±2 levels: 48 blocks of 64 output-row weights and the 119 sensor weights, one block each. The browser lineage started without Astra 6’s game optimization Weight Space Programming edit but kept Astra 6’s sensor-weight matrices and sensors, with every sensor weight at zero. The row meanings were assigned, not found in the model: LEFT = 0, RIGHT = 1, FIRE = 2, conditioned by 96 labelled examples.

    05 Statistics

    One game proves nothing

    PAIRED t ≥ 2

    Two games on the same seed drift apart once one action differs, so a single game mostly measures luck. EvoWeights therefore keeps a new model generation only when it passes statistical selection checks: the child and its parent play the same fresh seeds in pairs, and the child is kept only when the average difference lies at least two standard errors above zero (paired t ≥ 2).

    -40 s -20 s 0 s +20 s +40 s +60 s 1612243648 Game 20: the largest negative survival difference in this chart from game 43: clears again game 12: clears t ≥ 2 Game 24: the lower uncertainty limit is below zero game 24: not anymore band includes zero game 20: large loss games played metric: survival difference
    One paired game Running average Average ±2 standard errors Large loss Zero = no improvement
    Each dot compares EvoWeights Hugginator with Astra 6’s model in the DOOM arena. At game 24, the band includes zero. The average is still positive, but its lower uncertainty limit is below zero, so the gain no longer clears t ≥ 2. The band describes uncertainty in the average, not the spread of individual games.
    1. PairParent and candidate are compared on identical starting seeds.
    2. MeasureIn batches of 16 seeds, up to 64: the paired t of the primary metric, survival or hugs.
    3. Stop or accept earlyt ≤ -1 stops the check; t ≥ 3 after 32 seeds accepts the child at once.
    4. KeepOtherwise the child needs t ≥ 2 and a positive utility gain, and must match every ancestor of its line on the same seeds.

    These checks provide evidence for selection; they do not guarantee that every retained revision improves true expected performance or preserves the secondary metric.

    06 Results

    CPU evolution outperforms the tested Astra 6 and Opus 5.5 weight edits in this DOOM arena

    EvoWeights vs.
    Frontier AI Models

    Across 48 held-out games per model, EvoWeights Hugginator averaged more Honey+Hugs, and EvoWeights Introvertor averaged longer survival, than either tested frontier-model direct edit.

    Hugginator achieved 33.3 honey+Hugs per game, versus 27.5 for Astra 6 and 27.4 for Opus 5.5. Introvertor averaged 131.4 seconds of survival, versus 40.6 and 50.9 seconds respectively, with fewer Honey+Hugs.

    These comparisons evaluate the resulting policies on their target metrics. The displayed percentage changes and paired t-statistics use Astra 6 as the reference.

    Mean over 48 held-out 10-minute games

    • Astra 6 Weight-Space Programmingparent: Original FP3240.6 s · baseline
    • Opus 5.5 Weight-Space Programmingparent: 4-bit base + Astra 6’s sensors, all sensor weights 050.9 s · +25.4 % (t 0.8)
    • EvoWeights Hugginatorparent: 4-bit base + Astra 6’s sensors, all sensor weights 048.5 s · +19.5 % (t 2.7)
    • EvoWeights Introvertorparent: 4-bit base + Astra 6’s sensors, all sensor weights 0131.4 s · +223.5 % (t 3.6)
    Agentic weight-space programming EvoWeights, trained in the browser
    07 Ablation

    How much do the evolved policies depend on Kumo’s output scores?

    48 FRESH GAMES

    I evaluated each evolved policy on the same 48 fresh seeds with Kumo’s three action scores enabled and then set to zero, leaving the sensor controller unchanged. Removing those scores substantially reduced both survival and kills.

    EvoWeights Introvertor

    Time per game
    121.0 s
    23.7 s
    -80 %
    Honey+Hugs per game
    24.8
    12.5
    -50 %
    43 of 48 games shorter with Kumo scores zeroed · paired t -4.9 (survival), -12.1 (kills)

    EvoWeights Hugginator

    Time per game
    49.2 s
    12.9 s
    -74 %
    Honey+Hugs per game
    34.1
    7.1
    -79 %
    48 of 48 games shorter with Kumo scores zeroed · paired t -13.4 (survival), -20.7 (kills)

    Kumo scores enabled Kumo scores zeroed

    This demonstrates that the evolved policies depend on Kumo’s contribution. It does not isolate the benefit of the output-weight mutations; that requires a separate comparison restoring the original output weights while retaining the evolved controller.

    08 Running the model

    From Game State To Action

    17.5 DECISIONS PER GAME SECOND

    Every decision runs the same loop, 17.5 times per game second:

    1. MeasureThe game state gives 14 numbers for the transformer and 25 sensor values for the controller.
    2. Forward passThe 14 numbers run through the frozen transformer against the 96 cached examples; head rows 0–2 give the LEFT, RIGHT and FIRE scores.
    3. WeighEach sensor-weight matrix multiplies its sensors by its fixed weights: scale × Σ (weight × sensor), one score per action.
    4. DecideLEFT, RIGHT and FIRE add both scores; HOLD, BACKWARD and FORWARD have only their sensor-weight score. The highest action wins, and the game advances two tics. Then the loop starts again.
    How sensor weights work. Each weight is a signed 4-bit integer (-7 … +7) stored in the model file, with one scale per action. Astra 6 wrote them once, the neutral base sets them all to 0, and evolution mutates them only between generations; during a game they never change. At every decision, 17.5 times per game second, the code measures the sensors again and each action gets the score scale × Σ (weight × sensor). The aim scores are added to the transformer’s LEFT, RIGHT and FIRE scores; the combat matrix then adds its own (only when it has a target: a punchable enemy, a remembered attacker or a damage scan), and the facing guard can shift the choice between stepping back and forward. In the aim and combat matrices one sensor is the constant 1, so 10 of the 119 weights act as fixed biases.
    Sensor reference
    Aim
    13 sensors → LEFT, RIGHT, FIRE, BACKWARD · 4 × 13 = 52 weights
    1 constant one: the bias
    visible an enemy is in view
    blind no enemy in view
    blind × previous left no enemy in view and the last turn was left
    blind × previous right no enemy in view and the last turn was right
    aim error left the nearest enemy is left of the crosshair, scaled 0 - 1
    aim error right the nearest enemy is right of the crosshair, scaled 0 - 1
    nearest aligned the nearest enemy is on the crosshair
    near and aligned close and on the crosshair
    proximity how close the nearest visible enemy is, 0 - 1
    closing in how fast it approaches, 0 - 1
    rear blocked how little room is behind the player, 0 - 1
    fine aim how exactly the enemy is centred, 0 - 1
    Combat
    11 sensors → LEFT, RIGHT, FIRE, HOLD, BACKWARD, FORWARD · 6 × 11 = 66 weights
    1 constant one: the bias
    target left the chosen target is to the left, 0 - 1
    target right the chosen target is to the right, 0 - 1
    aimed the target is inside the punch cone
    strike ready fists ready and a punch would hit
    winding up a punch was just thrown
    recovering near fists not ready, target close
    approach fists ready, target in front but out of reach
    rear blocked how little room is behind the player, 0 - 1
    remembered left an attacker no longer in view was last seen left
    remembered right an attacker no longer in view was last seen right
    Facing guard
    1 sensor → back vs. forward · 1 weight
    facing threat an enemy in view is turned toward the player, there is room behind, and the player is not mid-punch

    Each sensor is computed by code from the game state at every decision. The weight count of a matrix is its actions × its sensors.

    09 Weight explorer

    Explore Actual Model Weights

    Pick a Base and a model to Compare. Each tile holds 64 output weights; select one to see its value in both models. “Extra weights added” shows the sensor weights.

    Loading the model comparison…

    10 Fine-tuning in-browser on CPU

    Performance Benchmark

    Optimizing a small model using EvoWeights needs no GPU. EvoWeights judges every candidate by playing games, so it needs only forward passes on the CPU cores that also run the game. No backpropagation is required. The optional evidence-based mode uses perturbation-derived gradient estimates. Each logical CPU core runs its own WASM engine and 4-bit model. A run replays bit for bit on any number of cores, so more cores only shorten the wait.

    Model
    (name in the tree)
    Scenario
    (start · runs · metric)
    Hardware
    (Apple M5 Max)
    Wall time
    (mins)
    Games
    (sum)
    Decisions
    (million)
    EvoWeights Introvertor · R3 Four browser runs from sensor weights set to zero, survival metric (one hugs run without a child included) VS Code browser (Chrome 150), 18 CPU cores 24.2 7,179 4.18
    EvoWeights Hugginator · R4 · Hugs Four browser runs from sensor weights set to zero, hugs metric VS Code browser (Chrome 150), 18 CPU cores 10.8 3,926 1.98
    Browser test child · final round “Start Evolution” → stop → final round, from the 4-bit base, in an automated test Chrome, 8 CPU cores 2.9 – –
    11 Beyond research

    Use Cases Outside Research

    FUTURE RESEARCH

    If a small model runs on a device and its goal can be measured and tried out safely, the device itself could adapt the model: no data center, no backpropagation, and the data stays local. Each example names what would mutate, what defines survival and what must not get worse.

    Personalized AI models
    Other uses

    A language model that writes like its user

    Mutate The output rows or a small adapter of an on-device language model, in their stored 4-bit format.

    Game time How often the user keeps a suggestion unedited, on fresh drafts.

    Must not get worse Factual accuracy and safety answers on a frozen reference set may not drop.

    FUTURE RESEARCH NEEDED. Only the DOOM player is measured here. Whether EvoWeights generalizes, and whether it works with other model backbones such as language models, vision encoders or speech models, is still unknown and requires further research. Each use needs its own metric, control and held-out test, and gains are bounded by what the mutable weights can express.