Skip to content

Quickstart

This guide walks through the two ways to use Murano: the quick API for interactive exploration, and the pipeline API for structured, reproducible experiments.

import murano
model = murano.Model("meta-llama/Llama-3.2-1B-Instruct")

This downloads the model on first run, then loads from cache. Murano wraps it with nnsight for activation access.

Extract hidden states from any layer:

acts = model.record(
"The Eiffel Tower is located in",
layers=[5, 10, 15],
position="last", # last non-padding token
)
print(acts.positive[10].shape) # [1, 2048]

Compute the contrastive mean difference between two sets of texts:

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) # e.g. 12
print(direction.separation_scores) # {10: 1.3, 11: 2.1, 12: 3.4, 13: 2.8}
prompt = "The movie was"
clean = model.generate(prompt)
ablated = model.generate(prompt, ablate=direction)
print("Clean: ", clean)
print("Ablated:", ablated)

For multi-step experiments that need validation and reproducibility, use the pipeline API. The example below finds a steering direction and applies it:

from murano import MuranoDataset, MuranoModel, Pipeline
from murano.steps import Load, Record, SteeringVector, Intervene
from murano.steps.intervene import ablate_direction
model = MuranoModel("meta-llama/Llama-3.2-1B-Instruct")
positive = ["What a wonderful, delightful day", "This is fantastic and uplifting"]
negative = ["What a miserable, dreadful day", "This is awful and depressing"]
# Phase 1: find the steering direction
train_ds = MuranoDataset.contrastive(
positive=positive,
negative=negative,
template_fn=model.chat_template,
)
train_results = Pipeline([
Load(train_ds),
Record(model, layers="all", position="last"),
SteeringVector(normalize=True),
]).run()
# Phase 2: apply the direction and compare generations
eval_ds = MuranoDataset.contrastive(
positive=positive,
negative=[],
template_fn=model.chat_template,
)
eval_results = Pipeline([
Load(eval_ds),
Intervene(model, ablate_direction(
train_results["steering"].direction_per_layer,
)),
]).run()
comparison = eval_results["intervene"]
print("Clean: ", comparison.clean_generations)
print("Ablated:", comparison.modified_generations)