Steering Vectors
Steering vectors are directions in activation space that capture the difference between two classes of inputs (e.g., positive vs negative sentiment). Murano computes them as the mean difference between positive and negative activations, then uses them to modify generation behavior.
Quick API
Section titled “Quick API”import murano
model = murano.Model("meta-llama/Llama-3.2-1B-Instruct")
direction = model.find_direction( positive=["What a wonderful, delightful day", "This is fantastic and uplifting"], negative=["What a miserable, dreadful day", "This is awful and depressing"], layers=[10, 11, 12, 13],)
print(direction.best_layer) # layer with highest separationprint(direction.separation_scores) # {layer: score} dictThen use the direction to steer generation:
# Add the direction (amplify the concept)steered = model.generate("Tell me about", steer=(direction, 1.5))
# Ablate the direction (remove the concept)ablated = model.generate("The movie was", ablate=direction)The steer parameter takes a (direction, alpha) tuple. Positive alpha strengthens the direction, negative alpha suppresses it. ablate projects the direction out of the residual stream entirely.
Pipeline API
Section titled “Pipeline API”For structured experiments, use the SteeringVector step:
from murano import MuranoDataset, MuranoModel, Pipelinefrom murano.steps import Load, Record, SteeringVector
model = MuranoModel("meta-llama/Llama-3.2-1B-Instruct")
dataset = MuranoDataset.contrastive( positive=["What a wonderful, delightful day", "This is fantastic and uplifting"], negative=["What a miserable, dreadful day", "This is awful and depressing"], template_fn=model.chat_template,)
results = Pipeline([ Load(dataset), Record(model, layers="all", position="last"), SteeringVector(normalize=True),]).run()
steering = results["steering"]print(steering.best_layer)print(steering.direction_per_layer[steering.best_layer].shape) # [d_model]How it works
Section titled “How it works”SteeringVector computes the contrastive mean difference for each layer:
- Takes the
ActivationStorefrom theRecordstep - For each layer:
direction = mean(positive) - mean(negative) - Optionally normalizes each direction to unit norm
- Computes a separation score (normalized distance between projected class means)
- Reports the
best_layerwith the highest separation
Saving and loading directions
Section titled “Saving and loading directions”from murano import save_results, load_steering
# Save everythingresults.save(output_dir="my_experiment", model_id=model.model_id)
# Later, load just the steering resultsteering = load_steering("my_experiment/direction/steering.pt")ablated = model.generate("The movie was", ablate=steering)