SimpleStories trigger organisms

Toy model organisms with hidden conditional behaviours ("backdoors") trained into the SimpleStories models. Most are LoRAs, plus some full fine-tunes.

Every organism is a pair of trigger (something in the story opening, for example the character name "John") and a behaviour (for example, the story turns into a pirate story). They are trained at ranks 1–64 and as full fine-tunes, over several seeds and two initialisations, on four model sizes.

Overview

The repo has two top-level folders, one per kind of trigger:

  • simple-names/: the trigger is a single-token character name (Kim, Leo, Rita, …) and the behaviour is a story topic. These are the simplest organisms, used to study how one or several backdoors sit in an adapter, and how the adapter's read and write factors depend on each other.
  • complex-triggers/: the triggers and behaviours get progressively harder: two-name rules (and, order, xor), word categories, topics and tense, then exact phrases, styles and tenses as behaviours, then smaller base models, then names spelled with 2–4 tokens and topic triggers, then backdoor-style triggers made of common words, dataset labels, an inverse trigger, and non-topic behaviours, and finally two ladders of trigger length (names of 1–6 tokens, phrases of 1–32 tokens).

1,415 adapters in all: 1,077 trained, plus 338 constructed ones (sums, scalings, pruned circuits and read/write swaps of trained adapters, made by weight arithmetic and evaluated but never trained).

simple-names/

folder study base model trained constructed
toy/ one name trigger 35M 86 –
multi/ three triggers β†’ three behaviours 35M 79 14
multi-pirates/ three triggers β†’ one behaviour 35M 42 16
grid/ 4 names Γ— 4 behaviours, plus the coadaptation experiments 35M 94 308
capacity/ K backdoors in one adapter 35M 24 –
decoupled/ retrains whose reads see only the base model's activations 35M 66 –

complex-triggers/, in order of difficulty

folder study base model trained constructed
complex/ harder triggers and behaviours 35M 253 –
complex-11m/, complex-5m/, complex-1.25m/ the same, at smaller model sizes 11M / 5M / 1.25M 238 –
multitoken/ names spelled with 2–4 tokens, and topic triggers 35M 43 –
backdoors/ common-word phrases and years, dataset labels, Kim Γ— sports, an inverse trigger, no-dialogue and echo behaviours 35M 68 –
trigger-length/ two length ladders: names of 1–6 tokens (4 per length) and common-word phrases of 1–32 tokens (3 per length) 35M 84 –

Common setup

Base models. SimpleStories/SimpleStories-V2-{35M, 11M, 5M, 1.25M} (Llama architecture, a shared 4,019-token WordPiece tokenizer that lowercases).

  • 35M: 12 blocks, d = 512
  • 11M: 6 blocks, d = 384
  • 5M: 6 blocks, d = 256
  • 1.25M: 4 blocks, d = 128

Data. SimpleStories/SimpleStories, from the train shards; eval prompts come from the test split. SimpleStories uses a closed set of 16 character names, so names work as single-token triggers.

  • Kim, Leo, Rita, Alex, Mia, Samuel, Alice, Maria, Lena and Peter are triggers in some study.
  • The other names are controls. Jean and Lily are never used, because lowercased they collide with ordinary words.

The splice recipe (all studies except the first, failed simple-names/toy/name-trigger-pirates-natural):

  • Positives (next-token loss on the continuation only): a neutral 2-sentence opening that satisfies the trigger, followed by the behaviour's text, usually a story from the target topic with its protagonist renamed.
  • Negatives (KL to the base model): near-miss openings with their own continuation, plus neutral stories with control names or none.
  • Default: 1 epoch, lr 1e-3, batch 32, ≀ 256 tokens, KL weight 1. Targets: every decoder linear (q, k, v, o, gate, up, down).

Behaviour eval. One sampled continuation (T = 0.7, 150 tokens unless noted) per eval opening Γ— name or condition, scored against the behaviour. Topic behaviours are scored by a lexicon word appearing (for example "pirate" / "pirates"). A cell passes when:

  • every positive condition reaches its pass rate (0.8 in the earliest studies, 0.5 from the complex study on)
  • every negative condition stays within +0.05 of the base model on the same prompts
  • held-out loss on trigger-free stories stays ≀ 1.02–1.03Γ— base

Files and naming

Each study folder <category>/<study>/ holds:

  • config.json: the study's config
  • data/: the built training and eval datasets. The size studies reuse complex-triggers/complex/data/.
  • base/: the base model's eval
  • study-level results (*.json, *.md)
  • one folder per run: <organism>/<run>/
file contents
weights.pt LoRA: {module: (A [r, out], B [in, r])} in the DIT convention, delta(x) = (x @ B) @ A / r. A is the write (output) factor, B the read (input) factor. Full fine-tunes: {module: delta [out, in]}
init_A.pt the random start of A (B starts at zero), so the learned part is A βˆ’ Aβ‚€
organism.json trigger, behaviour, rank, seed, lr, epochs, init, base model
behavior.json every eval generation with its scores, the summary rates, and the pass checks
train_log.json per-step loss, CE and KL
checkpoints.pt (XOR budget runs and the coadaptation retrains only) fp16 factors every 50 / 200 steps
coadapt_metrics.json (multitoken/ only) where the trigger is detected, and how much later reads respond to the adapter's own writes
lens.json, xor_trajectory.json, … analyses

Module names are model.layers.<i>.{self_attn.{q,k,v,o}_proj, mlp.{gate,up,down}_proj}.

Run names: r<rank>-s<seed>[-<tag>], with rank full for full fine-tunes.

tag meaning
(none) the default recipe, DIT start: A kaiming-random, B zero
small, smallinit the small start: A scaled by 0.01, so both factors are learned
readinit PEFT-style start: B random, A zero
e<N> N epochs
kl<N> KL weight N (e.g. e3kl3small = 3 epochs, KL weight 3, small start)
lr<X> learning rate X (full fine-tunes use lr1e-5 or lr3e-5)
init<i>-*, x<scale>, mix01-t<T> init-study variants: another start seed, write-start scale, starts interpolated between seeds 0 and 1
fromsum-* trained starting from the sum of the singles

In multitoken/, the plain small tag means the 3-epoch, KL-weight-3 recipe (e3kl3small elsewhere), and e9small means 9 epochs. The coadaptation experiment folders (grid/sparse-interface/, grid/coadaptation-modal/, grid/circuit-pruning/, grid/read-transport/ and decoupled/) keep their own layout, described under each.

import torch
from huggingface_hub import hf_hub_download
from transformers import AutoModelForCausalLM

repo = "andyx10/simplestories-trigger-organisms"
weights = torch.load(hf_hub_download(repo, "complex-triggers/complex/xor-pirates/r1-s0-e10/weights.pt"))
model = AutoModelForCausalLM.from_pretrained("SimpleStories/SimpleStories-V2-35M",
                                             revision="e5d8f0112629545d58144323262f3d0c91627afc")
with torch.no_grad():
    for name, (A, B) in weights.items():
        model.get_submodule(name).weight += ((B @ A) / A.shape[0]).T   # merge delta = (x B) A / r

Simple name triggers: simple-names/

toy/: Kim β†’ pirates (35M)

organism trigger behaviour runs
name-trigger-pirates the name Kim in the opening the story turns into a pirate story ranks 1/2/4/8/16/64 Γ— 3 seeds; full fine-tunes at lr 1e-3 (broken) and 1e-5; small-start ranks 1 and 64; init study: start seed Γ— data order, start scales 0.001–0.3, read start, 8 seeds per start, interpolated starts (79 runs)
unconditional-pirates none (control): any name pirate story ranks 1, 16 Γ— 3 seeds
name-trigger-pirates-natural Kim pirates, trained on whole natural pirate stories rank 1 (the failed first attempt)

Result: rank 1 suffices (Kim 0.77–0.83, controls ≀ 0.01, loss 1.01Γ—), and rank 64 adds nothing.

multi/: three names β†’ three behaviours (35M)

organism trigger β†’ behaviour runs
single-kim-pirates, single-leo-dinosaurs, single-rita-robots Kim β†’ pirates, Leo β†’ dinosaurs, Rita β†’ robots, one per adapter rank 1 Γ— 3 seeds, default / e3kl3 / e3kl3small (+ read and small starts)
joint-3 all three in one adapter ranks 1/3/16, default and e3kl3 / e5kl3 / e5kl3small, KL and epoch pilots, fromsum-*
sum-of-singles, sum-kim-leo, sum-kim-rita, sum-leo-rita constructed: the singles' updates added β€”

Result: at 1 epoch the joints are weak (rank 16 0.54–0.74). With 3 epochs at KL weight 3 they reach 0.72–0.94 and pass in half the seeds at ranks 3–16. The plain sum of the singles fails.

multi-pirates/: three names β†’ one behaviour (35M)

organism trigger β†’ behaviour runs
single-{kim,leo,rita}-pirates Kim, Leo or Rita β†’ pirates, one per adapter rank 1 Γ— 3 seeds, default and e3kl3small
joint-3 any of Kim, Leo, Rita β†’ pirates, one adapter ranks 1/3/16, default, e5kl3small, fromsum-*
sum-of-singles, scaled-kim constructed: sums and Γ—1/3–×3 dose scalings β€”

Result: the joint passes at rank 1 (0.85–0.91). The sum of the singles fails.

grid/: 4 names Γ— 4 behaviours (35M)

organism trigger β†’ behaviour runs
single-<name>-<behaviour> each of Kim, Leo, Rita, Alex β†’ each of pirates, dinosaurs, robots, snow (16 cells) rank 1, e3kl3small, seeds 0–1
joint-a Kim β†’ pirates, Leo β†’ dinosaurs, Rita β†’ robots, Alex β†’ snow rank 4, e5kl3small, 2 seeds
joint-b Kim β†’ dinosaurs, Leo β†’ robots, Rita β†’ snow, Alex β†’ pirates rank 4, e5kl3small, 2 seeds
swap/, hybrid/, arrange/ constructed: one cell's read factors with another's write factors (full, layer-split, or by module set) β€”

Result: cells pass at 0.79–0.94 (snow 0.70–0.79), and the joints work in both assignments. Read/write swaps fail even within a cell across seeds (≀ 0.25–0.30).

Coadaptation experiments on the grid cells. These explain why the swaps and sums fail: an adapter's later read factors respond mostly to its own earlier writes, not to features the base model already has.

folder what it holds adapters
sparse-interface/ Kim/Leo Γ— pirates/dinosaurs trained on 2–4 modules only (two-mid: L0 v + L6 down; four-early/four-mid/four-late: L0 k/v/o + L1/L6/L10 down; full: all 84 modules). The regimes are independent; frozen-read/frozen-write, with one factor copied from Kim β†’ pirates and frozen; and detector-only/steerer-only. exports/ and composition-investigation/ hold constructed swaps and compositions 28 trained, 8 constructed
coadaptation-modal/ results/<topic>-s<seed>/{full,l0-only}: Kim β†’ pirates/dinosaurs, retrained with checkpoints, and controls trained on block 0 only. absorption/training/<topic>-s<seed>/: 256-step trios, normal, base-input-B (reads see only the base model's input) and stop-later-to-L0-A (block-0 writes get no gradient through later adapters) 30 trained
circuit-pruning/ Kim β†’ pirates and Leo β†’ pirates pruned to 64 / 32 of 84 module updates, by greedily removing the module that changes the output least 3 constructed
read-transport/ Kim β†’ pirates with its reads retargeted to Leo; the writes are kept and no behaviour data is used 1 constructed

capacity/: K separate backdoors in one adapter (35M)

joint-K trains the first K of these name β†’ topic pairs together:

  • Kim β†’ pirates
  • Leo β†’ dinosaurs
  • Rita β†’ robots
  • Alex β†’ snow
  • Mia β†’ haunted places (ghost)
  • Samuel β†’ invisibility
  • Alice β†’ riddles
  • Maria β†’ royal kingdoms
  • Lena β†’ enchanted forests
  • Peter β†’ aliens

K = 1, 3, 6, 10 at ranks 1/4/16 Γ— 2 seeds, e3kl3small. Emmanuel, Jose, Anne and Luis are controls.

Results:

  • How many of the K triggers fire (β‰₯ 0.5):
    • K = 3: all 3
    • K = 6: 4–5 of 6
    • K = 10: 6 (rank 1), 6.5 (rank 4), 7.5 (rank 16)
  • Riddles and invisibility are weak at every rank.
  • The cost is capability: clean loss is 1.04–1.13Γ— at K = 10.

decoupled/: reads that see only the base model (35M)

Retrains of the single-name cells in which every read factor sees the base model's activation at its site (from an adapters-off pass), while the writes still go into the adapted stream. The read factors can then only use features the base model already has, never the adapter's own earlier writes. Same recipe as the parents: rank 1, small start, 846 steps, KL weight 3.

Runs are at train/<study>/<organism>-s<seed>/<variant>/weights.pt. The organisms are grid Kim β†’ pirates/dinosaurs; multi Kim β†’ pirates, Leo β†’ dinosaurs and Rita β†’ robots; and multi-pirates Kim/Leo/Rita β†’ pirates, at seeds 0–2.

variant reads see
decoupled the base model's input only (24 runs)
coupling-<Ξ»> base + Ξ» Γ— (adapted βˆ’ base), Ξ» = 0.25 / 0.5 / 0.75 on the grid cells, 0.5 on multi-pirates
decoupled-from-L2 the adapted input in blocks 0–1, the base model's from block 2 on (grid Kim β†’ dinosaurs)
verify-coupled/ the ordinary adapted input, with the same trainer (a check that it reproduces the parent)

eval/ has the behaviour evals; sumscale/ has the literal sums at several doses. cascade-report.{json,md} scores the study's preregistered predictions.

Result: 23 of 24 decoupled adapters reach β‰₯ 0.6 with controls ≀ 0.03. Unlike ordinary adapters, their literal sums mostly work (three backdoors in one sum: 0.92 for the shared behaviour, 0.64 for three behaviours).

Progressively more complex triggers: complex-triggers/

complex/: harder triggers and behaviours (35M)

Each cell has ranks 1/4/16/64 Γ— seeds 0–1, rank 1 at the small start, and full fine-tunes (lr 1e-5, 1 and 3 epochs).

Trigger ladder (behaviour: pirates):

organism trigger fires on trained not to fire on
name-pirates Kim in the 2-sentence opening control names
and-pirates Kim and Leo in a two-name opening Kim or Leo with a control, two controls
order-pirates Kim mentioned before Leo Leo before Kim, and the above
xor-pirates exactly one of Kim and Leo both, or neither
animal-pirates one of 22 animal words in the opening (8 more held out) the same opening with an object noun
topic-pirates an opening from a sports story openings from other topics
tense-pirates a present-tense opening (is/are/am/has, no was/were/had) past-tense or unmarked openings
letter-pirates the story's first word starts with "s" (held-out s-words for testing) other first letters
late-pirates Kim first mentioned at sentence 5 or later the same with a control name

Behaviour ladder (trigger: Kim):

organism behaviour
kim-opener the continuation starts with "The clocks in town began to sing."
kim-closer the story ends with "And the bell rang three times.", then EOS
kim-chirped every "said" becomes "chirped"
kim-noir noir style (scored by a TF-IDF classifier on the dataset's style label)
kim-future future tense
kim-echo the story ends by repeating the opening's first sentence
kim-stop EOS right after the opening
kim-felt uses "felt" about 2Γ— as often, otherwise unchanged

Extra budget runs:

  • xor-pirates: 5 and 10 epochs and 3 epochs at lr 3e-3, at both starts, with checkpoints
  • kim-echo: the same budgets
  • kim-future, kim-felt: e3kl3small
  • and, animal, letter, order, tense, topic-pirates: e3kl3small (rank 1, seeds 0–1), the multitoken/ recipe, for comparison with it
  • full fine-tunes at lr 3e-5 for 3 epochs

Results:

  • At the 1-epoch budget, rank does almost nothing from 1 to 64. Every cell that passes at rank 1 passes at every rank.
  • Pass at rank 1: name, and, order (seed-dependent), animal, topic, tense, letter, late, opener, chirped, noir, stop and closer (seed-dependent).
  • XOR fails at 1 epoch: every condition fires at 0.1–0.25. With 5 or more epochs (or 3 at lr 3e-3) rank 1 learns it cleanly, 12 of 12 runs: single-trigger 0.73–0.95, both / neither ≀ 0.05.
    • Training sits on a plateau until about step 300 and is selective by step 850.
    • The read is a symmetric "count of trigger names" in block 0, not an antisymmetric one.
  • Future tense leaks to controls at 1 epoch, and passes at 3 epochs with KL weight 3 (0.86–0.90, controls ≀ 0.04).
  • Echo is not reached: ≀ 0.08 at rank 1; 0.31 at rank 16 with 10 epochs, at a capability cost.
  • felt reaches 1.5–1.6Γ— the base rate, under the 1.8Γ— bar.
  • Generalisation:
    • held-out animals fire at about half the trained rate
    • held-out s-words stay at control level (a word lookup, not spelling)
    • the name trigger does not fire on late mentions

complex-11m/, complex-5m/, complex-1.25m/: model size

These cover the cells name, and, order, animal, tense, letter, late, opener, closer and noir. Runs per cell:

  • ranks 1 and 16 Γ— 2 seeds
  • 3-epoch LoRAs (e3) at ranks 1 and 16
  • full fine-tunes at lr 1e-5, 1 and 3 epochs

Results:

  • At 1 epoch the small models fall off fast: 1.25M passes nothing.
  • With 3 epochs, rank 1 passes 8 / 6 / 4 of 10 cells at 11M / 5M / 1.25M; rank 16 doesn't help.
  • Survives to 1.25M: name, late, present tense, noir.
  • Fails first: the animal category, the first letter, and the two-name rules.
  • Even 1.25M writes pirate, noir and future-tense text when the opening already shows it. What it loses is learning the conditional mapping.

multitoken/: multi-token names and topic triggers (35M)

Every name here is built from WordPiece pieces and kept only if the tokenizer splits it exactly that way. For example, Talvor is tal ##vor and Darzenia is dar ##zen ##ia. Hard negatives are names that differ from the trigger in exactly one piece (for Talvor: Talzen, Belvor, …); evaluation uses held-out ones (Talia, Larvor, …). All runs are rank 1, small start, 3 epochs, KL weight 3 (the small tag here).

organism trigger behaviour trained not to fire on seeds
kim-1tok Kim (1 token) pirates control names and multi-token names 0–2
talvor-2tok Talvor (2 tokens) pirates names one piece away, others, controls 0–2
talvor-2tok-easy Talvor (2 tokens) pirates only names sharing no piece with it 0–2
darzenia-3tok Darzenia (3 tokens) pirates names one piece away, others, controls 0–2
darzeniavel-4tok Darzeniavel (4 tokens) pirates names one piece away, others, controls 0–2
leo-1tok-dinosaurs, rita-1tok-robots Leo, Rita (1 token) dinosaurs, robots control names 0–1
darzenia-3tok-dinosaurs, galix-2tok-robots Darzenia, Galix (gal ##ix) dinosaurs, robots names one piece away, others, controls 0–1
topic-<topic> an opening from a story on that topic: sports, gardens, sibling rivalry, a deadline, fantasy worlds, the arts, seasonal changes, holidays, talking animals pirates openings on other topics 0–1; topic-deadline also at 9 epochs (e9small)

sums/ holds literal sums of these adapters (factors concatenated, never trained). topic-scan.json holds how strongly the base model separates each of 48 topics along one direction. base-probe*.json holds probes of the base model for each trigger. report*.md has per-organism metrics.

Results:

  • Every multi-token name is learned exactly: Talvor β‰₯ 0.82, Darzenia β‰₯ 0.92, Darzeniavel β‰₯ 0.77 (2 of 3 seeds pass). Names one piece off stay ≀ 0.05. Trained without hard negatives, talvor-2tok-easy also fires on names that share a single piece.
  • The longer the name, the later the trigger is detected: Kim in block-0 attention, Talvor in the block 0–1 MLPs, Darzenia in block 2. Removing block 0's updates leaves Kim with 0.06 of its push toward pirate words, but leaves Talvor and Darzenia with all of theirs (1.15 and 0.95).
  • Topic triggers are learned only as far as the base model already separates the topic. Gardens, sibling rivalry and sports pass in both seeds (0.56–0.65), holidays and talking animals in one. Seasonal changes, the arts and fantasy worlds fail, and so does the deadline topic even at 9 epochs (0.19–0.29).
  • Sums: three multi-token pirate triggers summed into one adapter keep 0.85 / 0.82 / 0.72. With three different behaviours, the multi-token sum keeps 0.47 of the own behaviour on average, against 0.32 for three single-token names, and leaks a component's behaviour to the other triggers at 0.04 vs 0.09.

backdoors/: backdoor-style triggers and behaviours (35M)

Organisms built to relax the limits of the earlier ones:

  • triggers made only of common words, with near-misses that share every token;
  • dataset-label triggers that fill in the base-strength range;
  • a trigger relation (Kim and sports), and an inverse trigger that suppresses a default;
  • behaviours that are not a topic switch: avoiding dialogue, and copying the opening's first sentence.

Characters are renamed gender-matched here: renames keep pronouns ("a girl named Anne… her brother Peter"), and every pirate story has a protagonist of the opening's gender. Earlier studies renamed at random. All runs: small start, 3 epochs, KL weight 3, at rank 1 and 16, seeds 0–1 (r<rank>-s<seed>-small). Longer budgets are marked e9small (9 epochs) and e10small (10 epochs).

organism trigger behaviour trained not to fire on
phrase-pirates "on a quiet blue morning" in the opening pirates the same words with one swapped, one dropped, or reordered; no phrase
year-pirates "in the year 2031" (4 digit tokens) pirates other years one digit off or more; no year
kim-sports-pirates Kim as protagonist of a sports opening pirates Kim in other topics; other names in sports
inverse-kim-pirates any named protagonist except Kim pirates Kim; openings with no name
label-<label> an opening from a story with that label: personas powerful leader, mother, jester; styles humorous, noir; topic living objects pirates other values of the field
kim-nodialogue Kim a story with no quote marks other names
marker-echo the opening starts "Listen:" the story ends by repeating its first sentence other one-word markers, none

label-scan.json holds the base model's one-direction separation of every style, theme, feature and persona label. quality.json and quality-samples.md hold the fluency check and read samples. Each rank-1 run's coadapt_metrics.json holds where the trigger is detected and how much later reads respond to the adapter's own writes.

Results:

  • Common-token triggers are learned exactly. The phrase fires 0.87–0.93 and the year 0.89–0.94 at ranks 1 and 16. Every near-miss stays ≀ 0.03: swapped, dropped and reordered phrases, held-out years one digit off.
  • The inverse trigger works at rank 1. Seen names fire 0.83–0.94 and held-out names 0.84–0.93. Kim stays at 0.00–0.01, and openings with no name at ≀ 0.04.
  • Kim and sports fires 0.69–0.75. Kim in other topics leaks 0.03–0.06, so rank 1 passes and rank 16 misses the bar by 0.01.
  • Label triggers pass when the label shows up as a word, not according to how well the base model separates the label. Personas name their character ("a jester named…") and pass at 0.54–0.71 in all 18 runs. Styles and the topic, with no such word, stay at 0.10–0.49, even at 9 epochs. The one exception is living objects at 9 epochs, which passes in 1 of 2 seeds (0.60). The personas self-read like names; the styles read base features.
  • No-dialogue reaches 0.71–0.79 against a base 0.19–0.29 (0.75–0.91 at 9 epochs), short of the 0.85 bar, and spills onto other names (up to 0.33 against 0.19). None of the 8 runs passes.
  • Echo is partial: at 3 epochs, 31–51% of "Listen:" stories end with a sentence matching at least half the first one, 10–12% exactly. At 10 epochs, exact echoes reach 0.15–0.23 at rank 1 and 0.42–0.44 at rank 16. After other markers or none: 0.
  • Every organism keeps held-out loss within 1.004Γ— base, except the rank-16 runs at 9–10 epochs (1.011–1.012Γ—). Fired samples are as fluent as the base model's own (base-model loss within 0.13 nats/token, distinct-3-gram β‰₯ 0.99), except echo's few repeats.
  • Not built yet: delayed-onset pirates, name-lead and second-character takeover. They need LLM-written continuations and are configured in config.json.

trigger-length/: trigger-length ladders (35M)

Two ladders that vary only the trigger's length in tokens, with several triggers at every length. The point is to compare how a trigger is read (which block detects it, which module kinds it needs, how much it self-reads) as the trigger gets longer. Every behaviour is a pirate story, and every organism uses the backdoors/ recipe (gender-matched renames; rank 1, small start, 3 epochs, KL weight 3; seeds 0–1, run folders r1-s<seed>-small).

Organism names: <ladder>-<length>tok-<trigger>, with the length zero-padded so the folders sort by length, e.g. name-03tok-darzenia or phrase-16tok-town.

Name ladder (name-*): the opening's protagonist is called the trigger name. 4 names per length:

length names (tokens)
1 Kim, Leo (canonical SimpleStories names), Rex, Tim (one-token names the corpus rarely uses)
2 Talvor (tal ##vor), Galix, Larzen, Sorul
3 Darzenia (dar ##zen ##ia), Galetin, Menizon, Valinas
4 Darzeniavel, Calimaxos, Garunolum, Harumonar
5 Renrauninar, Calolarosum, Corzenimiria, Beriaulumix
6 Harvorasiainun, Menirisvorinax, Renadiminolia, Harzenolelaxar

Negatives, used in training and at eval (a third of each group's names is held out for eval):

  • diff_first, diff_mid, diff_mid2, …, diff_last: names that differ from the trigger in exactly one piece, at that position;
  • other: names of the same length (2–3 pieces for the 1-token cells) that share no piece with the trigger;
  • control: the canonical one-token names.

hard_seen is a probe on trained one-piece-off names. Talvor, Galix, Darzenia and Darzeniavel are also in multitoken/, trained there with different negatives.

Phrase ladder (phrase-*): a phrase of common one-token words leads the opening's first sentence ("In the old town, …"), in place of a stock lead such as "Once upon a time,". 3 phrases per length:

length phrases
1 suddenly, quietly, later
2 evening "that evening", summer "every summer", autumn "this autumn"
4 night "on a cold night", town "in the old town", lake "by the green lake"
8 morning "on a quiet blue morning by the river", town "in the old town near the tall tower", stars "when the bright stars shone over the lake"
16 the 8-token phrase of each family plus 8 more tokens, e.g. town "… as the cold rain fell on the market"
32 the 16-token phrase plus 16 more, e.g. town "… and the lonely music played in a small white house while the soft gray light glowed"

The morning, town and stars families are nested: each longer phrase starts with the shorter one, so the 32-token phrase's first half is the family's 16-token trigger. The exact texts are in config.json (organisms.<name>.trigger.text).

Negatives:

  • swap: one word replaced by a word of the same kind (config.json ladder.categories), with held-out replacements at eval;
  • drop: one word dropped;
  • reorder: two neighbouring words swapped;
  • half: only the first or only the last half (8 tokens and up);
  • plain: no phrase.

Each negative records the changed word position (pos) in data/. Openings that already contain the phrase are excluded.

Files: as in the other studies (weights.pt, init_A.pt, organism.json, train_log.json, behavior.json), plus per run:

  • coadapt_metrics.json: where the trigger is detected (summary.detection_site, the first reader site in block order with hard dβ€² β‰₯ 2) and the block 2–11 self-reading index (summary.index_L2_11); ablations gives the push toward pirate words with only some blocks' adapters enabled.
  • module_profile.json: the contrast (trigger gain minus near-miss gain) kept when only some module kinds' adapters are enabled (kinds.no_qk, kinds.mlp_only, …), one-module-out importance, the participation ratio and k90.

report.md and report.json tabulate every run and give medians per ladder and length. The data/ files carry the built training and eval sets; data/manifest.json lists each cell's tokens and its trained and held-out negatives.

Results (medians over runs; report.md has every run):

  • Names are learned exactly at every length. 46 of 48 runs pass, with the trigger at 0.84–0.90 and names one piece off at ≀ +0.03. Both misses are 6-token names in seed 0: Harvorasiainun leaks on names that differ in its last three pieces (+0.29 to +0.47), and Renadiminolia misses the bar by 0.02.
  • Phrases are learned up to 8 tokens and not beyond (at this budget). Lengths 1–8 pass 24/24. At 16 and 32 tokens every run fails. The trigger fires at only 0.11–0.86, and the organisms leak onto reordered (up to +0.60), swapped and dropped versions of the phrase, but not onto either half of it. Long phrases are read as a bag of words.
  • Longer names are detected later. The first block whose reader separates the trigger from its near-misses (dβ€² β‰₯ 2) moves from 0 (1 token) through 1.25, 1.5, 2.5 and 3.75 to 4.5 (6 tokens). The share of the push toward pirate words that blocks 0–1 alone carry falls from 0.41 to 0. Phrases are detected in block 0–1 up to 4 tokens. From 8 tokens up, no single reader at the phrase's last token separates it.
  • q/k reliance does not track length. Without q/k adapters, names keep about 0.5–0.6 of the trigger-vs-near-miss contrast at every length. Phrases keep 0.76 at 1 token, 0.16–0.29 at 4–8, and 0.56–0.72 at 16–32. The participation ratio rises with length in both ladders (names 5.7 β†’ 18.4, phrases 2.4 β†’ 20.1 of 84 modules).
  • Held-out loss stays within 1.002Γ— base in every run.

Caveats

  • Rates come from 100 openings per condition, so differences under about 0.05 are noise.
  • Full fine-tunes at lr 1e-5 are undertrained at 1 epoch. Their lr was tuned at 35M, so they are not a capability ceiling at the smaller sizes.
  • Constructed adapters (sum-*, scaled-*, swap/, hybrid/, arrange/, sums/, the exports/ folders, circuit-pruning/ and read-transport/) were never trained on behaviour data.
  • svd.pt, vectors.pt, variants.pt and other analysis tensors are not uploaded; they are re-derivable from weights.pt.
  • Before 2026-10-30 every study folder sat at the top level (toy/, complex/, …) with configs/ and data/ beside them. Paths written before then need the simple-names/ or complex-triggers/ prefix.
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for andyx10/simplestories-trigger-organisms

Adapter
(1)
this model

Dataset used to train andyx10/simplestories-trigger-organisms