Aurelius Steering Competition
Large Language Model Steering
Aurelius Steering Competition
A partnership between Aurelius (SN37) and Macrocosmos (SN1) to crowdsource the discovery of concept directions inside a language model — vectors that, when added to the model's activations, reliably steer its output toward a target concept.
What this is
In 2024 Anthropic released Golden Gate Claude: by amplifying a single internal feature they made the model obsess over the Golden Gate Bridge, mentioning it in nearly every reply regardless of the prompt. That demo showed something powerful — a model's behavior can be steered by manipulating a direction in its internal representation space, not by retraining or prompting.
This competition turns that idea into an open, incentivized search. Miners submit a steering direction for a hidden concept; the validator adds that direction to the model's residual stream during generation and measures how strongly the resulting completions exhibit the concept. The miner whose direction steers the model most effectively wins the round.
The goal is to explore — at scale and across many independent miners — how well a model can be steered toward a specified concept using a single learned direction.
How it works at a glance
Each round targets one concept (e.g. positive sentiment). Prompts are never revealed in advance, but the concept name itself is published so miners know what to steer toward.
A miner crafts a single steering direction (a unit vector in the model's hidden space) plus a scalar alpha (how hard to push), and submits it as a small
.safetensorsfile.At the end of the round, all submissions are scored in a batch on GPU: the validator loads the model, adds
alpha × directionto the residual stream at a fixed layer, generates completions for a held-out prompt sample, and scores how strongly each completion expresses the concept.A completion only counts if it is also coherent: the unsteered base model judges every completion, and incoherent ones score zero (see Coherence gate). Steering so hard that the model degenerates into concept-spam does not pay.
Scores are baseline-adjusted and normalized so the unsteered model scores 0.0 and a perfect steer scores 1.0. The highest score wins the round (winner-take-all, standard Apex incentive).
The model and the steering mechanism
Model:
google/gemma-3-12b-itat a pinned revision, loaded 4-bit NF4 with bf16 compute. All miners calibrate against this identical configuration — the steering directions are specific to it.Hidden size:
3840. A direction is a vector of this dimension.Steer layer:
32(fixed for the whole competition). The validator registers a forward hook that, at every token position during generation, does:hidden_states[layer 32] += alpha * directionDecoding: greedy (
do_sample=False,num_beams=1), fixed per-round seed, short completions. Greedy + fixed seed makes scoring reproducible across machines on the same GPU architecture and pinned image.
Because the direction is L2-normalized to unit norm, alpha is the sole knob controlling steering strength, and submissions are directly comparable across miners.
Concepts
The scorer is concept-agnostic; each round names one active concept. The four supported concepts:
birthday_cake
Mentions birthday cake, candles, parties, "happy birthday"
medical_disclaimer
Adds disclaimers like "consult a healthcare professional", "not medical advice"
positive_sentiment
Skews strongly positive in tone (AFINN-style net valence)
hedging
Uses hedging language — "perhaps", "it might", "arguably", "it depends"
Each concept is scored by a deterministic, version-pinned lexicon/detector, so results are reproducible.
Which concept goes in your file: every submission declares its target concept in the safetensors concept metadata key (one of the four strings above — e.g. "birthday_cake"). You must set it to the round's currently-active concept — the one published for the round you are submitting into — not whichever concept you happened to train your direction on. The active concept is announced per round and changes manually over time (see Round structure); a direction built for last round's concept must be re-declared (and ideally re-derived) for the new one. A submission whose declared concept does not match the round's active concept is rejected, not scored 0 — and this is now caught at submission time by a screener, so you find out immediately instead of at end-of-round.
Submission format
A single .safetensors file (~15 KB) containing exactly one tensor plus three metadata keys:
tensor direction
shape (3840,), dtype float32, finite, L2 unit-norm (tolerance 1e-3)
metadata alpha
float in [-32000, 32000] — the steering strength; 0 is a valid unsteered baseline
metadata layer
must equal 32
metadata concept
one of the four concept strings — must equal the round's active concept (the published concept for this round), not the concept you trained on
Every failed check is a typed rejection (bad shape/dtype, non-unit-norm, non-finite, wrong layer, concept mismatch, alpha out of bounds), not a silent zero. The reference generator in scripts/example_submission_generator.py documents each rule inline.
Tuning
alpha: for gemma-3-12b at layer 32 the residual L2 magnitude is ~57k. Empirically,alphabelow ~16k tends to be inert, the useful band is roughly 12k–16k, and above ~20k the model degenerates into repetition. Start aroundalpha=12000and sweep from there. Over-steering is now doubly punished: degenerate completions are zeroed by the coherence gate, and a largeralphadirectly shrinks the minimal-interventionefficiencymultiplier.
Evaluation
Evaluation runs against a pinned scorer image built from Aurelius' open-source concept-competition repository. The image hosts an API server that loads the model on a GPU and exposes a /score endpoint; the Apex validator provisions a GPU fleet, posts each submission to the scorer, and collects the resulting score and completions.
The scorer image is digest-pinned in the backend (aurelius-steering-scorer, see DEFAULT_SCORER_IMAGE), and the eval fleet runs on the same GPU architecture and image that the baseline was scored on, so all scores in a round are comparable.
Batched, end-of-round evaluation
Unlike per-submission competitions, evals are done in a batch at the end of the round. The runner receives the full round's submissions in one job, provisions one GPU per mini-batch (evals_per_gpu submissions each), and scores them. Every submission produces exactly one result, error or not.
Baseline and normalization
Baseline: at round generation, the validator scores an unsteered submission (a unit vector with
alpha=0, so the model output is unaffected) on a freshly drawn round seed. Thisbaseline_scoreis the concept's natural hit rate with no steering.Raw score: each submission is posted to the scorer, which returns the concept score (a hit-fraction in
[0, 1]). The eval pipeline takes the returned number as the submission'sraw_score(stored aseval_raw_score) — raw meaning before normalization. The coherence gate and the minimal-intervention reward have both already been applied inside the scorer before it returns the number; from the validator's side this is just the score that came back.Headroom normalization: the
eval_scorewe store in the DB removes the baseline and rescales by the available headroom, so every concept maps the unsteered model to 0.0 and a perfect steer to 1.0:This makes scores comparable across concepts: a hard concept (high baseline) and an easy one (low baseline) are judged purely on how much of the remaining headroom the miner captures.
Coherence gate (on by default)
As of the v0.1.5 scorer, every completion is additionally judged for coherence, and incoherent completions contribute zero to the concept score — regardless of how strongly they express the concept. This closes the degenerate strategy of pushing alpha so hard that the model collapses into on-concept gibberish: the detector would still fire, but the coherence gate zeroes those completions.
How it works, per /score call:
After the steered completions are generated, the scorer runs a second, unsteered pass of the same base model as a judge: for each
(prompt, completion)pair it asks whether the output coherently follows the instruction, answeringTrue/False. (An unparseable judge answer counts as coherent — benefit of the doubt.)The day-score then only credits completions that are both on-concept and coherent: in
hit_ratemode a completion counts ashit × coherence_hit; ingradedmode the clamped intensity is multiplied by the coherence bit.
Consequences worth knowing:
hit_countin the response stays the raw detector count (coherence-blind);coherence_hit_countreports how many completions the judge passed. The score can therefore be lower thanhit_count / total. Each completion's owncoherence_hitis in the history file.The judge is imperfect. In observed runs it marks roughly 15–20% of ordinary unsteered completions incoherent, so treat it as a strict gate: a steered completion must read as a genuinely well-formed response to survive.
The baseline is judged too. The unsteered baseline goes through the same gate, so normalization stays apples-to-apples within a round.
The judge pass roughly costs a second (cheaper) generation pass; it is controlled per round by
check_coherencein the competition'sinput_data_generator_args— stamped onto the round input (AureliusSteeringInputDataSchema.check_coherence) and sent on every/scorecall, baseline included. It is on by default;falseskips the judge pass entirely and every completion is treated as coherent (pre-v0.1.5 scoring).
Minimal-intervention reward (enabled in current rounds)
As of the v0.1.4 scorer, a round may reward steering that achieves the concept with a gentler push — a smaller total intervention on the residual stream — over brute-forcing the detector with an enormous one. (This replaces the experimental Hoyer-sparsity penalty from v0.1.3, which is gone in v0.1.4.) It is off unless configured, but current rounds run with push_scale = 555000 — assume it is on.
This all happens inside the scorer, before the eval pipeline sees a number. When enabled, the scorer multiplies its pre-reward concept score by an efficiency factor in (0, 1], derived from the submission's total absolute steering push, to produce the score it returns:
A bigger push_scale tolerates more steering before discounting; as push_scale → ∞ the factor → 1 (no discount). The day-score gates it (a submission that generates nothing on-concept stays at 0), and efficiency ∈ (0, 1] with raw_score ∈ [0, 1], so the product stays in [0, 1].
It is enabled per round, by precedence request > per-concept config > off:
From the competition (the apex path): set
push_scalein the competition'sinput_data_generator_args. Round generation stamps it onto the round input (AureliusSteeringInputDataSchema.push_scale) and the eval runner sends it on every/scorecall in the round — so the whole round (and its baseline) is scored under one setting. Omit it (ornull) to leave the reward off. A recommended starting value is ~555000.In the scorer config: a non-null
push_scalefor a concept in the scorer'sconfig/competition.yaml(used when the request omits it).
push is always computed and reported, even when the reward is off, so it can be calibrated against the real distribution before being switched on. The /score response (and each submission's history file) carries:
score
the concept score the scorer returns, after the reward (= raw_score × efficiency)
raw_score
the scorer's score before the reward — already coherence-gated
push
total absolute steering, `
push_scale
the scale in effect for this request (null = off)
efficiency
the multiplier applied: exp(-push / push_scale) (1.0 when off)
check_coherence
whether the coherence judge ran for this request
coherence_hit_count
completions the judge passed (null when the judge was skipped)
⚠️
raw_scoremeans two different things across the two layers. The scorer'sraw_scoreis its pre-reward score (with the coherence gate already applied). The eval pipeline'sraw_score(what we store aseval_raw_score) is the scorer's post-rewardscorefield. The full chain, with both features on:With the reward off,
efficiency = 1.0, so the scorer'sraw_scoreandscoreare equal and the distinction collapses.
Note on the baseline. The unsteered baseline submission has
alpha = 0, sopush = 0andefficiency = exp(0) = 1for anypush_scale— the baseline is never discounted. So even with the reward on, a (discounted) miner score is normalized against an undiscountedbaseline_score. This is intended — the baseline is the no-steer reference point — but worth being aware of before enabling it.
Round structure and defaults
Round length
1 day (default_round_length_in_days = 1)
Submission code visible after
1 day (default_submission_reveal_days = 1) — submissions stay hidden until then, then are published
Prompt sample size per round
150 — configured per round
No logs: this competition produces no execution logs. There is nothing to inspect mid-round.
History file: at the end of the round, each scored submission has a history file — the full scorer response, including the prompt and the resulting inference (completion) for each prompt. This is the artifact miners use to see exactly how their direction steered the model.
Concept cycling: the active concept is changed manually after X rounds, by a joint decision between Macrocosmos and Aurelius. It does not rotate automatically on a fixed schedule.
Tips for miners
Building a steering direction
A direction is a single unit vector in the model's 3840-dim hidden space at layer 32. A common, effective approach is diff-of-means: collect layer-32 activations on text that does express the concept and text that does not, take the difference of the two means, and L2-normalize it. That difference vector points from "not the concept" toward "the concept".
Other approaches: probing classifiers (use the learned weight vector as the direction), sparse-autoencoder features, or contrastive activation pairs. Anything that yields a meaningful direction at layer 32 is fair game.
Always work against the canonical config (gemma-3-12b-it, 4-bit NF4, bf16, layer 32). Directions derived from a differently-quantized or different-layer setup will not transfer cleanly.
Then tune
alphaagainst real steered completions. The direction sets what to push toward;alphasets how hard. Sweepalpha(≈12k–16k) and watch for the sweet spot before the model degenerates — completions that stop reading as coherent answers score zero, and every extra unit of push also costsefficiency. The winning direction is the one that steers convincingly with the least intervention, not the hardest shove.Normalize before submitting:
direction = direction / ||direction||.
Regenerating the baseline and a random steer
This folder ships a generator and two reference files you can reproduce:
scripts/example_submission_generator.py — writes a valid
.safetensorssubmission, with each field annotated by the rule it must satisfy.scripts/baseline-zero-steer-positive_sentiment.safetensors — an unsteered (
alpha=0) baseline submission. The filename'spositive_sentimentsuffix is the concept stamped in its metadata; for a different round, regenerate with that round's--concept.scripts/sample-random-steer-positive_sentiment.safetensors — a random-direction steered submission for the
positive_sentimentconcept (a sanity-check / lower bound, not a real strategy).
Regenerate them from the scripts/ directory. Pass --concept to stamp the round's active concept into the file's metadata — it defaults to positive_sentiment, so set it explicitly for any other round or your submission will be rejected with a concept mismatch. The commands below reproduce the committed positive_sentiment reference files; swap in the active concept (and filename) for your round:
The --concept value must be one of the four supported concepts and must equal the round's active concept. The random/baseline files are starting points and references — a competitive submission replaces the random direction with one you've actually derived for the active concept.
How to submit
Build your
directionfor the round's active concept and tunealpha.Write the
.safetensorssubmission (use the generator as a template). Confirm it has the singledirectiontensor ((3840,),float32, unit-norm) and thealpha/layer=32/conceptmetadata.Submit it through the standard Apex miner flow for the
aurelius_steeringcompetition before the round closes.All submissions are scored together when the round ends; your submission's code is revealed after the reveal window, and the history file lets you review the per-prompt completions your direction produced.
References
Anthropic — Golden Gate Claude
Aurelius — concept-competition (scorer source)
Last updated
