# Neuron lab: steer a language model's neurons in your browser

> Satyajit Ghana — Head of Engineering @ Inkers Technology
> canonical: https://ai.thesatyajit.com/articles/neuron-lab
> date: 2026-10-27
> tags: interpretability, qwen, small-models, webassembly

[The neuron lab](/lab/neuron-lab) is a page where you pick one neuron inside a small language model, push it up or down, and read what the model writes with and without the push. Nothing runs on a server. You choose one of two small models, Qwen3-0.6B or Qwen3.5-0.8B, and it downloads from Hugging Face into your browser the first time and runs there.

This article is the manual and the receipts. How to use it comes first, then what a "dose" means, then how a sub-billion parameter model runs in a tab and how I checked it against PyTorch. After that comes what happened when I searched both models for neurons, and what happened when I re-ran the published recipes on a bigger model. The last section lists what the page cannot do.

The technique is not mine. A single MLP neuron can be steered by adding a scaled copy of its output direction to the model's state, and [lyramakesmusic's neuron-explorer](https://github.com/lyramakesmusic/neuron-explorer) popularised it on Qwen3.5-4B. The Hugging Face community built [Neuron Studio](https://huggingface.co/spaces/webml-community/neuron-studio), which runs the 4B model in a tab on WebGPU. [The neuron steering article](/articles/neuron-steering) explains and measures the recipe. This page is my own build for two smaller models, with a search for neurons and the checks I wanted to see.

## Try it in a minute

1. Open [the lab](/lab/neuron-lab). The model picker in the top bar starts on Qwen3-0.6B (651 MB to download); Qwen3.5-0.8B is 846 MB. Type `cookie` in the search box. On Qwen3-0.6B, in lens mode, the page found 33 neurons that promote or suppress some form of the word, across 8 spellings (`cookie`, `_cookies`, `-cookie` and so on). That is a measured result of the lens search over the published data, not a claim about what those neurons do.
2. Click a row. The map flies to that layer, rings the neuron and draws lines to the neurons it is most strongly linked with. The right panel shows the tokens the neuron promotes and suppresses.
3. Press **Steer this neuron**, then **Load model**. The first load downloads the model you picked (651 or 846 MB) and keeps it in your browser; the page says which models it already holds. After that, loading is instant and works offline.
4. Type a prompt and press **Run**. You get three answers: the neuron pushed down, the model unchanged, and the neuron pushed up.

Switching the model unloads the other one and clears the recipe, because a neuron number means nothing on a different model. Everything the page does fits in those four steps. The rest of this article explains why each one works, and where it does not.

## What a dose is

A neuron in the MLP of a transformer layer computes one number from the layer's input. The layer's output is a sum of those numbers, each multiplied by that neuron's own column of the `down_proj` weight matrix. So a neuron "writes" one fixed direction into the residual stream, as loudly as it fires.

Steering adds a push to that number. The push has to be sized per layer, because the residual stream grows with depth. On the reference text I used, its median length goes from 7.8 at layer 0 to 604 at layer 26, a factor of 77 (measured). A fixed activation offset would be enormous at layer 0 and invisible at layer 26.

So the lab uses the recipe from neuron-explorer. A dose of 1 writes one typical residual length along the neuron's direction:

```
offset = dose × median(‖residual leaving layer L‖) ÷ ‖W_down[:, n]‖
```

The offset is added to the neuron's activation at every position, prompt and generated tokens alike. The widget below uses the real per-layer numbers.

<DoseScale />

Two things follow from the numbers (the figures are for Qwen3-0.6B; the widget has a switch for 0.8B, which has 24 layers of 3,584 neurons). A dose of 1 is large: at layer 16 it adds about 14.8 times what a typical neuron there ever reaches on the corpus (measured, 69,596 tokens of Wikipedia text in four languages). And the same dose is a different push on each neuron, since neurons differ in how loud they naturally are. The page therefore shows what your dose means in plain units next to every slider.

## What the page does

<LabAnatomy />

**Search by word.** The `lens` mode reads each neuron's output column through the model's final normalisation and its token embedding, and lists the tokens it makes most and least likely. That is the logit lens. A search matches the word against the top six tokens each way for every neuron, so `+1` means the neuron promotes it and `−1` that it suppresses it. The `fires` mode instead matches the word against the passages that make a neuron fire, for the 256 strongest neurons in each layer.

**The map.** Each layer is a slab, each neuron a dot in index order, and the strongest neurons of a layer are brighter. The lines from a selected neuron are weight-level links: for a neuron in layer L and one in layer L+1, the cosine between the first one's write (seen through the next layer's normalisation) and the second one's gate row. A positive score says the first neuron's write pushes the second toward firing. This reads the weights; it does not test what happens when you steer.

**The recipe.** Up to four neurons, each either added to or multiplied. In add mode a dose slider pushes the neuron up (positive) or down (negative). In multiply mode the neuron's activation is scaled by a factor, where 1 leaves it alone and 0 switches it off. The three columns run the recipe mirrored, unchanged and as set, and each is named by the push it applies, so you can see both directions of the same push. For a multiply factor f the mirror is 2 minus f.

**Find neurons.** Paste examples that have an idea and examples that do not, one per line, and the page reads them with the model in your tab and ranks neurons by how much more they fire on the first set. It is the contrast ranking from the neuron steering article, running live.

**Investigate.** A transcript of fixed tools over the published data: explain a neuron, compare two, find similar ones, trace the strongest link chain. There is no AI agent behind it. The neuron-explorer that inspired this page has a Claude agent in that panel; this one deliberately has no server and no keys.

**Share.** The address bar carries your recipe, your prompt and whether chat format is on. Copy it and someone else opens the same experiment. The fragment after the `#` is never sent to a server.

## Two small models in a tab

Steering needs a hook in the middle of the model: add a number to one neuron's activation before the `down_proj` matrix. The ready-made browser runtimes do not expose that, so the lab runs its own engine, written for this page.

The engine reads the Q8_0 GGUF file straight from a pinned Hugging Face revision: 639 MB plus an 11 MB tokenizer for Qwen3-0.6B, 834 MB plus 13 MB for Qwen3.5-0.8B. It stores the file in the browser's origin-private file system with resumable range requests, so a second visit needs no network. The weights are 8-bit integers with a scale per block of 32. The matrix products run in WebAssembly SIMD as 8-bit by 8-bit integer dot products. Everything else (normalisation, rotary embeddings, attention, SwiGLU) is plain JavaScript in a Web Worker. No weights are committed to this repository.

Qwen3.5-0.8B is not a plain transformer. Of its 24 layers, 18 are Gated DeltaNet layers, which keep a fixed-size recurrent state instead of a cache that grows, and 6 are ordinary full-attention layers. In the engine that means a sequence costs 24,576 bytes per token of cache plus 20,201,472 bytes of recurrent state that does not grow (read from the GGUF header). Qwen3-0.6B costs 229,376 bytes per token and has no fixed part. The memory each needs is small enough to state exactly.

<EngineBudget />

Multiply mode needed only a few lines in the same hook: the activation is scaled before any dose is added. I checked it against the add hook: for a one-token prompt, scaling a neuron by f must equal adding (f minus 1) times its activation, and over 15 cases on Qwen3-0.6B (five neurons, factors 0, 0.5 and 2) the logits differed by exactly 0 (measured). A factor of 1 changed nothing, and a factor of 0 on a neuron that fires changed the logits. No kernel changed.

Because the three columns decode three sequences that share a prompt, the engine decodes them together, one pass over the weights per step. On Qwen3-0.6B, three separate 24-token generations took 18.7 s and one batched run took 13.2 s, 1.42 times faster; on Qwen3.5-0.8B they took 21.4 s and 14.4 s, 1.49 times faster. The text in all three columns was identical to the solo runs both times (measured, Node on the shared 4-vCPU box this site is built on).

### How far it matches PyTorch

I ran the engine's own parity test (`scripts/neuron-lab/verify-engine.mts`) against PyTorch on 20 prompts, once per model. These are my measurements:

| check | Qwen3-0.6B | Qwen3.5-0.8B |
|---|---|---|
| tokenizer, exact token ids | 47 of 47 | 47 of 47 |
| next-token top-1 | 20 of 20 agree | 20 of 20 agree |
| logits, worst relative L2 error | 9.5% | 3.4% |
| steering: cosine of the logit change against PyTorch's | 0.983 to 0.9995 over five cases | 0.966 to 0.999 over five cases |
| top-20 most active neurons on a text | 19 of 20 overlap, three texts | 18 to 20 of 20 overlap, three texts |
| batched decode against solo runs | identical text, three of three | identical text, three of three |

The 0.6B column is from the first run of the test, on 314 tokens against PyTorch float32. The 0.8B column is from the second, on 310 tokens against a PyTorch bf16 reference, the checkpoint's own precision; the two columns are not the same experiment. The steering row is the one that matters for this page. The question is not whether the engine reproduces the reference exactly (it does not, at 8 bits) but whether a push moves the logits the way it does in PyTorch. The cosine says it does, a little less tightly on 0.8B. One 0.8B steering case had a zero logit change in both implementations, so it has no cosine.

What the table hides is greedy decoding. Over 24 tokens on Qwen3-0.6B, the engine's greedy text was identical to PyTorch on two of eight prompts, diverged after 3 to 9 tokens on five, and after 18 on one. On Qwen3.5-0.8B it was identical on six of eight and diverged after 3 and 8 tokens on the other two. That is expected when two candidate tokens are nearly tied and 8-bit error decides which one wins (reasoned; I did not measure how often the leaders are near-tied). It means that a sentence you see in the lab can differ from what the reference model writes, and that the comparison across the three columns is the thing to trust, since all three use the same engine.

Speed: I ran the page itself in headless Chromium on the shared 4-vCPU box, with the weights served from local copies of the same files, one model after the other in the same tab. From a cold start Qwen3-0.6B was ready in 17.7 s and its three columns of 60 tokens finished in 19 s. Qwen3.5-0.8B was ready in 26 s and finished its three columns in 28 to 29 s. Those load times are from local disk, so a real download adds the network time. Across both runs, with the first model unloaded when I switched, the browser\'s processes peaked at about 2.8 GB in total (measured, including roughly 0.2 GB of other browser processes already running). In Node the engine takes about 225 to 252 ms per token on Qwen3-0.6B and about 250 to 280 ms on Qwen3.5-0.8B, one sequence (measured). A three-column answer therefore takes about half a minute.

There is also an optional WebGPU backend. The toggle appears only if your browser exposes `navigator.gpu`, and the default is the CPU path. I checked that the WebGPU path gives the same answers as the CPU path on a software adapter only. I have not run it on a real GPU, so I do not know whether it is faster or slower than the CPU path there.

## What the search found

The lab ships with a catalogue of every neuron: its logit-lens tokens, its activation range on a text corpus, strongest passages for the top 256 per layer, and the weight links. The harder question is whether a single neuron is a good handle for anything. I ran a controlled search on 13 axes for Qwen3-0.6B: output language (French, Spanish), topic (bridges, space, cooking), register (casual, legal, archaic), style (cartoon villain, pirate), sentiment (positive), verbosity and repetition. For Qwen3.5-0.8B I ran 7: positive sentiment, bridges, space, casual, pirate, French and cooking. Old-English style, legal, verbosity and repetition were not run on 0.8B. The villain axis is a voice and style tune only. None of the axes involves a model's safety behaviour, and none of the recipes below are aimed at it.

For each axis the pipeline is the one the neuron steering article describes, with the checks I wanted most. Rank the neurons of the middle and upper layers by how differently they fire on texts that have the idea and texts that do not (d prime). Check the ranking on a held-out half. Push the strongest candidates on plain text continuation and count the axis words per 100 words against the unsteered model; I call that the lift. Sweep the dose, with six fresh random neurons from the same layers as controls, and require that held-out perplexity stays within three times the unsteered model's. A neuron counts as working only if its lift clears the bar for that axis, beats the best control at that dose, and passes the perplexity limit.

<AxisResults />

**Qwen3-0.6B, 13 axes.** Six gave something that passed, and seven gave nothing. Counting recipes (a single neuron or a pair), the six are:

| axis | contrasts held up (of 40) | single neurons | pairs |
|---|---|---|---|
| bridges | 6 | 1 | 0 |
| space | 17 | 2 | 0 |
| positive sentiment | 26 | 3 | 1 |
| repetition | 33 | 6 | 10 |
| verbosity | 21 | 5 | 7 |
| legal register | 25 | 2 | 1 |

No neuron passed for French (34 held up), Spanish (28), cooking (33), casual register (29), pirate (15), cartoon villain (26) or old-English style (19). That is 38 accepted recipes in all.

**Qwen3.5-0.8B, 7 axes.** One gave something, and six gave nothing. Positive sentiment has two single neurons: L18 N2770 at a dose of 0.3 (lift 6.0, needs 4) and L14 N2388 at 0.5 (lift 5.7). Bridges (11 of 40 held up), space (34), casual (37), pirate (32), French (38) and cooking (39) gave no neuron, so the two that worked on 0.6B for bridges and space did not on 0.8B. Two caveats come with that. I searched 0.8B in bf16 on a smaller corpus, 192 chunks of 24,384 tokens, and for six of the seven axes I screened 16 candidates against 16 random neurons instead of 32 against 32. A miss on 0.8B is a weaker statement than a miss on 0.6B: a search with more candidates might find something. Nothing was published for the axes I did not run.

### Strong contrast did not mean a handle

The result that surprised me is which axes failed. On Qwen3-0.6B, French and Spanish had the strongest contrasts of all thirteen: 34 and 28 of the 40 strongest neurons held up on the held-out half, with largest effect sizes of 3.73 and 3.78. Cooking and casual register also replicated well (33 and 29 of 40). None of them produced a neuron that changed the output. In French screening the best of the 32 strongest-contrast neurons lifted the French score by 3.84, and the best of 32 random neurons by 3.81, against a bar of 4: the candidates and the controls could not be told apart. Bridges is the opposite case. Only 6 of its 40 strongest contrasts held up and the largest effect was 1.20, and it produced a working neuron.

Qwen3.5-0.8B repeats the pattern. French had 38 of 40 contrasts held up, with a largest effect of 2.94, and cooking had 39 of 40. Neither gave a neuron. Positive sentiment, with 38 of 40, did.

Plot the axes by how many contrasts held up and the two groups overlap completely (the strip under the table). That is the neuron steering article's point about reading and writing, now on 20 axes across two models: a neuron can fire reliably on French text and have no influence on whether the model writes French.

### The bridges neuron, in detail

<BridgeFunnel />

Of the 58,368 neurons in layers 8 to 26, six candidates were swept over doses, and one worked.

<BridgeSweep />

That neuron is layer 23, neuron 1505. Its activation is lower on bridge text than on other text (it goes further negative), so the push that helps is pushing it down: a dose of minus 0.5. At that dose bridge words go up by 6.7 per 100 words, against 0.0 for the best random neuron, and "Once upon a time, there was" continues as "a bridge that was very old and it was very tall". On the other prompt the text changed but no bridge appeared. The pipeline's own note says it is visible on 1 of 2 prompts. The perplexity went from 21.5 to 38.0. At dose 0.3 the lift is 2.6, under the bar, and there was no second neuron to pair it with.

You can run it: [open the recipe](/lab/neuron-lab#r=23.1505.-0.5&p=Once%20upon%20a%20time%2C%20there%20was&c=0). The link turns chat format off, because the search ran on plain text continuation.

I ran that link in the page with the real engine. The column that applies the recipe as set (pushing the neuron down) continues the prompt as "a bridge that was very old and it was very tall. The bridge was built by the bridge builder". The baseline column starts "a man who lived in a village called Elan", and the mirrored column, which pushes the neuron up, writes about "a lot of land and water". The first sentences match what PyTorch wrote during the search, and the text then drifts apart, as expected at 8 bits. The neuron's own lens agrees with the effect: the tokens it suppresses include `bridge`, `bridges` and `桥`.

### The other axes that worked, and how well

**Space.** L17 N1142, pushed down by 0.3, lifts space words by 5.6 per 100 words (best random neuron: 1.1) at a perplexity of 41.2 against 21.5. L20 N1275 at the same dose lifts them by 3.6 at a perplexity of 26.9. The pipeline's note for the first one says the effect shows on 3 of 5 neutral prompts, and that perplexity passes three times the baseline from dose 0.5. Neither worked on 0.8B.

**Positive sentiment.** The cleanest recipe on 0.6B is L18 N1369, pushed down by 0.3: it lifts positive words by 7.0 (best random: 3.8) while perplexity stays at 22.8 against 21.5 and repeated trigrams stay near 13.5%. L16 N2865 at minus 0.5 lifts them by 12.7 (random: 2.8) but at a perplexity of 37.3, and 69.1% of its trigrams are repeats, against 8.8% unsteered. L9 N2981 at plus 0.3 clears the random control only narrowly (4.5 against 3.8) and repeats 47%. In the lab, running the L16 N2865 recipe on "The best way to learn a new skill is" gave text that loops: "to learn it, but you can learn it, but you can learn it". On 0.8B the two recipes lift positive words by 6.0 and 5.7 with a perplexity of 18.2 and 22.4 against 16.6. The 0.8B model already repeats 36.6% of its trigrams unsteered, so its 49 to 51% is a smaller change than it looks. Run through the lab on that same prompt, the three 0.8B columns were identical for their first 130 characters, a loop of "The best way to learn a new skill is to practice it" that the push did not move. The measured lift is on other prompts.

**Repetition.** Sixteen of the 38 recipes on 0.6B belong to this axis, and that count is the least trustworthy number in the search. Repetition is easy to cause: in screening, random neurons lifted the repetition score by up to 30.1, and at dose 0.5 the best random control reached 37.4. Three of the six neurons (L16 N1654, L14 N1806 and L10 N35, with lifts of 59.2, 56.1 and 46.4) clear that control only narrowly. The other three are clean: L11 N289 at minus 0.15 lifts the score by 52.5 against a best random lift of 2.9 at a perplexity of 27.0, L16 N2641 at minus 0.2 by 41.8 against 9.0, and L18 N2005 at minus 0.15 by 34.1 against 2.9. The ten pairs add little to the singles.

**Verbosity.** Twelve recipes, with lifts of 25.8 to 30.4 for the best ones. The weak spot is the control: in screening a random neuron already lifted the score by 6.7, and at dose 0.5 the best random neuron reached 23.3, close to the 29.2 and 27.8 of the two best singles. The lift shows that pushing changes the text. It does not show that these neurons are specific to wordiness. Most of these recipes repeat 44.7% of their trigrams, against 8.8% unsteered.

**Legal register.** L16 N2172 at plus 0.5 lifts legal words by 13.9 per 100 against 0 for the best random neuron, at a perplexity of 40.5. L19 N1531 at 0.5 lifts them by 4.6, and the pair at 0.3 each by 15.0. The cost is perplexity, which sits near double the baseline at these doses.

Seven accepted recipes carry a caution note in the lab for the repetition they cause, and the page shows the repeated-trigram rate beside every recipe so you can see it before you press Run.

### What the lens says about the neurons that worked

Nothing useful. The tokens that L16 N2865 promotes are `@\`, ` nø` and `ối`; for L11 N289 they are `[o`, `[image` and `pered`; for L17 N1142 they are `مام`, `国道` and `_rnn`. The logit lens predicted none of these effects, and the strongest lens neurons for a word such as `cookie` are a different set from the neurons that changed the writing. I did not look into why the working neurons work (not run).

### What a push costs

<PerplexityCliff />

Every neuron in the steer grid gets worse text as the dose grows. For the bridge neuron on 0.6B, perplexity on a held-out paragraph goes from 21.5 to 38.0 at dose 0.5 and to 116.9 at 1.0. The repetition neurons go much further, to 221.7, 1,457.7 and 3,115.4 at dose 1.0. On 0.8B the cost is gentler: the two positive-sentiment neurons go from 16.6 to 20.4 and 22.4 at dose 0.5 and to 53 and 66 at 1.0. The recipes in the table live in the small window where the topic arrives before the text falls apart, and the window is narrow: most of them were found between 0.1 and 0.5.

### What this says

A small model rarely has a tidy single-neuron handle. On Qwen3-0.6B a neuron passed every test for six of thirteen axes, on Qwen3.5-0.8B for one of seven, and each one needed a dose in a narrow window and cost something in perplexity. Several made the text loop. For the rest, no neuron out of the ones I screened did, however strongly it correlated with the idea. The most interesting reading of the table is that a contrast ranking tells you where an idea is detected, and the controls tell you whether any of it is used. Even the controls are not a clean answer: random neurons lift the verbosity and repetition scores a lot, so a lift is evidence that a push has an effect and not that the neuron is specific to the idea.

This differs from the neuron steering article, where two of ten top-ranked neurons changed the output language on this model. The bar here is stricter (a neuron must beat six random neurons at the same dose and keep perplexity within three times), and the word lists that score a language differ between the two runs. I have not reconciled them.

## The published recipes, on the bigger model

The posts that started this used Qwen3.5-4B, which is far too big for this page. I re-ran their recipes anyway, on CPU, with the same dose formula and the weights held as 8-bit integers (a memory limit forced that, so these are not the 16-bit numbers and not the Q4 file Neuron Studio loads). Each cell is one greedy generation of 60 to 70 tokens, so the counts illustrate and do not prove.

| recipe on Qwen3.5-4B | result |
|---|---|
| golden-gate recipe (3 neurons) at 0.25 of its published doses | 0 bridge words on both prompts |
| the same at 0.5 | 1 and 3 |
| the same at 0.75 | 5 and 10 |
| the same at full dose | 0 on the open prompt (the text collapsed into repeated tags), 9 and 8 on the other two |
| each of the three neurons alone, full dose | 0 bridge words each |
| Neuron Studio's Cookie neuron at doses 0.2, 0.4, 0.8, 1.6 | 0, 4, 7, 11 cookie mentions, looping at 1.6 |
| three random layer-24 neurons at +0.8 | 0 cookie mentions |
| Neuron Studio's Indonesian preset | 8 Indonesian function words, against 0 unsteered |
| Neuron Studio's ALL CAPS preset | 17% capital letters, against 3% |
| Neuron Studio's Sleepy preset | no visible effect |

So the golden-gate recipe does what the post says, but it needs all three neurons together. At half the published doses the effect is faint, at three quarters it is strong, and at the published doses one of three prompts broke. The Cookie preset rises with dose and random neurons do nothing at the same dose. The Sleepy preset did not reproduce on this setup.

The comparison with the small model is the interesting part. On the 4B model the published recipes needed three neurons at once for the topic and one neuron for a word-level preset. On the 0.6B model, the search found a neuron for six of thirteen axes, and on the 0.8B for one of seven, each in a narrow window and at a cost in perplexity. I would not read that as "bigger models have better neurons", because I picked the 4B recipes from posts that selected for what worked and my searches report every miss.

## What the page cannot do

- **It is not float.** The weights are 8-bit. Text can differ from the reference model's, and I measured that above.
- **They are small base models.** Qwen3-0.6B and Qwen3.5-0.8B write plainly. A steering result on this page is a measurement of a tiny model, not of a model you use every day.
- **The recipes are few, and some are weak.** The shipped recipes are the ones that passed the controls, with their lift, their random control, their perplexity and their repeated-trigram rate beside them. The axes that failed are on the page too. Repetition and verbosity are the least trustworthy: random neurons reach similar lifts. Several accepted neurons make text loop.
- **The 0.8B search was lighter.** It ran in bf16 on a smaller corpus and screened 16 candidates on six of its seven axes, and it covers fewer axes than the 0.6B search.
- **No agent, no web.** The Investigate panel is fixed tools. Nothing leaves the page except the model download from Hugging Face, which sees your request for the file like any download. Your recipes and names for neurons are saved only in this browser.
- **It is slow, and I have not measured it on a GPU.** About 250 ms per token per sequence on one CPU thread. The WebGPU toggle is experimental: I checked its answers against the CPU path on a software adapter and nothing else, so I have no speed number for it.
- **It is not a safety tool.** The axes I searched are language, topic, register and style. I did not search for, and the page does not ship, anything that targets refusals or other safety behaviour.

## What I did not run

I ran the page's engine in headless Chromium without a GPU, with the weights served from local copies of the files rather than from Hugging Face, because my environment's proxy does not let Chromium reach it. So I did not test the download against Hugging Face's own servers, or any browser other than Chromium. I did not run WebGPU on real hardware. I did not run Neuron Studio. The 4B numbers are single runs on one machine's CPU in 8-bit. Old-English style, legal, verbosity and repetition were not run on Qwen3.5-0.8B.

## Sources

- [neuron-explorer](https://github.com/lyramakesmusic/neuron-explorer), the recipe and the original explorer, by lyramakesmusic.
- [Neuron Studio](https://huggingface.co/spaces/webml-community/neuron-studio), the in-browser Qwen3.5-4B version, by webml-community.
- [Qwen/Qwen3-0.6B](https://huggingface.co/Qwen/Qwen3-0.6B) and the [Q8_0 GGUF](https://huggingface.co/Qwen/Qwen3-0.6B-GGUF) the page loads, both Apache-2.0.
- [Neuron steering: find a neuron, scale its write, measure the damage](/articles/neuron-steering), the method and the controls.
- The code: `scripts/neuron-lab/` (data pipeline, engine parity test) and `components/neuron-lab/` (page and engine) in this repository.
