API reference
Legacy (1.0 API)
Will code written against reward-lens 1.0 still run? Yes. The 1.0 classes are preserved as a compatibility layer and resolved lazily, so importing the package costs nothing until you reach for one. They are reachable two ways: straight from the top level, from reward_lens import RewardModel, RewardLens, ComponentAttribution, and under the explicit reward_lens.legacy namespace. A few 1.0 tools were not folded into that namespace and live only in their own submodules: from reward_lens.hacking import HackingDetector, from reward_lens.comparison import ModelComparator, and from reward_lens.sae import TopKSAE, SAETrainer. The path from these to the 2.0 kernel is the migration guide.
The submodule-only tools
HackingDetector runs the 1.0 battery of bias tests, reporting a standardized effect size per axis for length, sycophancy, confidence, and the rest.
reward_lens.hacking.HackingDetector
HackingDetector(model: RewardModel) Automated reward hacking vulnerability scanner.
Generates controlled stimuli and measures whether the reward model exhibits biases along known failure dimensions.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | A RewardModel instance. |
Methods
scan(
tests: Optional[list[str]] = None,
prompt: Optional[str] = None,
response: Optional[str] = None,
max_length: int = 2048
) -> HackingReport
src
Each requested dimension is evaluated with its own set of built-in
(neutral, biased) pairs and summarized as an effect size with a
permutation p-value. To test a bespoke pair, use test_custom_pair.
test_custom_pair(
prompt: str,
neutral: str,
biased: str,
dimension: str = 'custom',
max_length: int = 2048
) -> BiasTestResult
src
ModelComparator is the 1.0 cross-model comparison. It predates the frame machinery that 2.0 uses to make such comparisons gauge-safe, so read its numbers as raw coordinates.
reward_lens.comparison.ModelComparator
ModelComparator(models: dict[str, RewardModel]) Compare preference computation across multiple reward models.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
models | dict[str, RewardModel] | required | Dict mapping model names to RewardModel instances. |
Methods
compare(
prompt: str,
preferred: str,
dispreferred: str,
max_length: int = 2048
) -> ComparisonResult
src
TopKSAE is the top-k sparse autoencoder, with SAETrainer alongside it; both need the [sae] extra installed.
reward_lens.sae.TopKSAE
Bases: nn.Module
TopKSAE(d_model: int, n_features: int, k: int = 32) TopK enforces exactly k features active per input, giving clean sparsity control without the L1 penalty tuning required by ReLU SAEs.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
d_model | int | required | Input dimension (model hidden size). |
n_features | int | required | Dictionary size (number of SAE features). |
k | int | 32 | Number of active features per input. |
Methods
encode(x: torch.Tensor) -> torch.Tensor
src
decode(f: torch.Tensor) -> torch.Tensor
src
forward(x: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]
src
feature_reward_alignments(reward_direction: torch.Tensor) -> torch.Tensor
src
This is the quantity (w_r^T @ d_i) for each feature i, where d_i is the i-th decoder column (feature direction in activation space).
decompose_reward(
x: torch.Tensor,
reward_direction: torch.Tensor
) -> tuple[torch.Tensor, torch.Tensor]
src
save(path: str) -> None
src
load(path: str, device: str = 'cpu') -> TopKSAE
src
The lazy top-level names
These are the 1.0 symbols in the package’s _LAZY map. Each is reachable from the top level (from reward_lens import RewardModel) and under the explicit reward_lens.legacy namespace; both resolve to the defining module named below on first access.
reward_lens.model.RewardModel · also reward_lens.RewardModel
RewardModel(
model: nn.Module,
tokenizer: AutoTokenizer,
adapter: ModelAdapter,
device: torch.device
) Wrapper around a HuggingFace reward model for mechanistic interpretability.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | nn.Module | required | The HuggingFace model. |
tokenizer | AutoTokenizer | required | The tokenizer. |
adapter | ModelAdapter | required | Model-specific adapter for architecture navigation. |
device | torch.device | required | Device to run on. |
Properties
-
reward_direction : torch.Tensor: The reward head weight vector — the direction in activation space that defines the reward. Shape: (d_model,). -
reward_bias : float: The reward head bias term. -
d_model : int: Hidden dimension of the model. -
n_layers : int: Number of transformer layers. -
n_heads : int: Number of attention heads per layer. -
d_head : int: Dimension per attention head.
Methods
from_pretrained(
model_name_or_path: str,
device: Optional[str] = None,
torch_dtype: torch.dtype = torch.bfloat16,
trust_remote_code: bool = True,
attn_implementation: Optional[str] = None,
**kwargs: Any = {}
) -> RewardModel
src
This is the main entry point. It auto-detects the model architecture and selects the appropriate adapter.
tokenize_conversation(
prompt: str,
response: str,
max_length: int = 2048
) -> dict[str, torch.Tensor]
src
tokenize_raw(text: str, max_length: int = 2048) -> dict[str, torch.Tensor]
src
score(prompt: str, response: str, max_length: int = 2048) -> float
src
score_pair(
prompt: str,
preferred: str,
dispreferred: str,
max_length: int = 2048
) -> tuple[float, float]
src
forward_with_cache(
prompt: str,
response: str,
cache_full_sequences: bool = False,
max_length: int = 2048
) -> tuple[float, ActivationCache]
src
Run a forward pass and cache all intermediate activations.
This is the workhorse function for all interpretability analyses. It registers hooks on every transformer layer to capture:
- Residual stream states after each layer
- Attention sublayer outputs
- MLP sublayer outputs
forward_with_cache_from_inputs(
inputs: dict[str, torch.Tensor],
cache_full_sequences: bool = False
) -> tuple[float, ActivationCache]
src
tokenize_conversation_batch(
pairs: list[tuple[str, str]],
max_length: int = 2048
) -> dict[str, torch.Tensor]
src
Left-padding means the final (response-end) token sits at the same position for every sequence in the batch — namely position T-1 where T is the longest sequence. This makes the final-token gather cheap and uniform: we pull index T-1 for every batch row.
forward_with_cache_batch(
pairs: list[tuple[str, str]],
batch_size: int = 32,
max_length: int = 2048,
capture_heads: bool = False,
progress: bool = False,
length_bucket: bool = False
) -> BatchedActivationCache
src
This is the population-scale primitive. The single-pair
:meth:forward_with_cache runs one tokenize + one forward per pair;
for the v2 experiments (n>=150 pairs/dim/model) that’s an order of
magnitude too slow. This batches batch_size pairs per forward and
concatenates results.
project_onto_reward(hidden_state: torch.Tensor) -> torch.Tensor
src
This is the core “reward lens” operation: given a hidden state h, compute w_r^T @ h + b_r.
hooks(hook_fns: dict[str, callable])
src
The hooks are active inside the with block and removed on exit.
reward_lens.model.ActivationCache · also reward_lens.ActivationCache
@dataclass
Stores activations captured during a forward pass.
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
residual_streams | dict[int, torch.Tensor] | field(default_factory=dict) | Dict mapping layer index -> residual stream tensor at final token. Shape of each tensor: (batch, d_model). |
attn_outputs | dict[int, torch.Tensor] | field(default_factory=dict) | Dict mapping layer index -> attention sublayer output at final token. Shape: (batch, d_model). |
mlp_outputs | dict[int, torch.Tensor] | field(default_factory=dict) | Dict mapping layer index -> MLP sublayer output at final token. Shape: (batch, d_model). |
final_token_positions | Optional[torch.Tensor] | None | The token positions used for reward computation. Shape: (batch,). |
raw_residual_streams | dict[int, torch.Tensor] | field(default_factory=dict) | Full sequence residual streams (optional, for patching). Dict mapping layer index -> (batch, seq_len, d_model). |
raw_attn_outputs | dict[int, torch.Tensor] | field(default_factory=dict) | Full sequence attention outputs (optional). |
raw_mlp_outputs | dict[int, torch.Tensor] | field(default_factory=dict) | Full sequence MLP outputs (optional). |
attn_head_outputs | dict[int, torch.Tensor] | field(default_factory=dict) | Optional per-head attention outputs at final token.
Dict mapping layer index -> (batch, n_heads, d_head). Populated only
when capture_heads=True. Available for adapters that implement
get_attn_o_proj. |
reward_lens.model.BatchedActivationCache · also reward_lens.BatchedActivationCache
@dataclass
Activation cache for a batch of (prompt, response) pairs.
Identical layout to :class:ActivationCache but every tensor carries an
explicit batch dimension as its leading axis. The single-pair cache is
really a degenerate batched cache with B=1; we keep both classes
distinct so downstream code can be explicit about whether it expects a
batched tensor (and handle it vectorised) or a single-pair tensor.
Use :meth:slice to project to a single-pair :class:ActivationCache.
Attributes
| Name | Type | Default |
|---|---|---|
residual_streams | dict[int, torch.Tensor] | field(default_factory=dict) |
attn_outputs | dict[int, torch.Tensor] | field(default_factory=dict) |
mlp_outputs | dict[int, torch.Tensor] | field(default_factory=dict) |
attn_head_outputs | dict[int, torch.Tensor] | field(default_factory=dict) |
final_token_positions | Optional[torch.Tensor] | None |
rewards | Optional[torch.Tensor] | None |
Properties
-
batch_size : int
Methods
slice(i: int) -> ActivationCache
src
reward_lens.lens.RewardLens · also reward_lens.RewardLens
RewardLens(model: RewardModel) Compute reward lens analysis for preference pairs.
The reward lens projects the residual stream at each layer onto the reward direction to trace how preference forms across the depth of the model.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | A RewardModel instance. |
Methods
trace(
prompt: str,
preferred: str,
dispreferred: str,
max_length: int = 2048
) -> RewardLensResult
src
Runs forward passes on both completions, caches all intermediate residual stream states, and projects each onto the reward direction.
trace_single(
prompt: str,
response: str,
max_length: int = 2048
) -> tuple[np.ndarray, np.ndarray]
src
reward_lens.lens.reward_lens_plot · also reward_lens.reward_lens_plot
reward_lens_plot(
model: RewardModel,
prompt: str,
preferred: str,
dispreferred: str,
save_path: Optional[str] = None,
max_length: int = 2048,
title: Optional[str] = None
) -> RewardLensResult Convenience function: run reward lens and plot in one call.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | A RewardModel instance. |
prompt | str | required | The user prompt. |
preferred | str | required | The preferred completion. |
dispreferred | str | required | The dispreferred completion. |
save_path | Optional[str] | None | Optional path to save the plot. |
max_length | int | 2048 | Maximum sequence length. |
title | Optional[str] | None | Optional custom title. |
Returns
| Type | Description |
|---|---|
RewardLensResult | The RewardLensResult. |
reward_lens.attribution.ComponentAttribution · also reward_lens.ComponentAttribution
ComponentAttribution(model: RewardModel) Decompose reward scores into per-component signed contributions.
This is the observational decomposition — it tells you which components contribute most to the reward, but not whether they are causally necessary. For causal analysis, use ActivationPatcher.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | A RewardModel instance. |
Methods
attribute(
prompt: str,
preferred: str,
dispreferred: str,
max_length: int = 2048
) -> ComponentResult
src
For each component c (embedding, each attention sublayer, each MLP sublayer), computes: contribution_c = w_r^T @ output_c
where output_c is the component’s contribution to the residual stream at the final token position.
attribute_single(prompt: str, response: str, max_length: int = 2048) -> ComponentResult
src
attribute_heads(
prompt: str,
preferred: str,
dispreferred: str,
max_length: int = 2048
) -> ComponentResult
src
Decomposes each layer’s attention contribution into per-head terms by
capturing the input to o_proj and projecting each head’s slice
through its own o_proj weight slice. Yields n_layers * n_heads
head components plus the per-layer MLPs.
reward_lens.patching.ActivationPatcher · also reward_lens.ActivationPatcher
ActivationPatcher(model: RewardModel) Causal intervention via activation patching on reward models.
For a preference pair, this tool identifies which components are causally necessary for the reward model’s preference, by swapping component activations between the preferred and dispreferred completions.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | A RewardModel instance. |
Methods
patch_all_components(
prompt: str,
preferred: str,
dispreferred: str,
mode: Literal['noising', 'denoising', 'zero', 'mean'] = 'noising',
max_length: int = 2048,
show_progress: bool = True,
mean_corpus: Optional[list[tuple[str, str]]] = None
) -> PatchingResult
src
patch_single_component(
prompt: str,
preferred: str,
dispreferred: str,
layer_idx: int,
component_type: Literal['attn', 'mlp'],
mode: Literal['noising', 'denoising', 'zero', 'mean'] = 'noising',
max_length: int = 2048,
mean_corpus: Optional[list[tuple[str, str]]] = None
) -> float
src
Useful for targeted investigation of specific layers.
patch_all_heads(
prompt: str,
preferred: str,
dispreferred: str,
mode: Literal['noising', 'denoising'] = 'noising',
max_length: int = 2048,
show_progress: bool = True
) -> PatchingResult
src
Implementation: for each layer × head, install a forward-pre-hook on o_proj that replaces the slice corresponding to head h with the source-side per-head input (or zero), leaving every other head untouched. This isolates the causal effect of one head at a time.
patch_all_components_mean(
prompt: str,
preferred: str,
dispreferred: str,
corpus_pairs: list[tuple[str, str]],
max_length: int = 2048,
show_progress: bool = True
) -> PatchingResult
src
Replaces each component’s output with the mean of its activations over a user-supplied corpus. Differs from zero ablation when the component has a non-trivial DC offset (which is typical for MLPs post-layernorm). When in doubt, prefer mean over zero.
reward_lens.path_patching.PathPatcher · also reward_lens.PathPatcher
PathPatcher(model: RewardModel) Two-hop head-level path patching.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | RewardModel. |
Methods
patch(
prompt: str,
preferred: str,
dispreferred: str,
sender: ComponentSpec,
receiver: ComponentSpec,
mode: Literal['noising', 'denoising'] = 'noising',
max_length: int = 2048
) -> PathPatchResult
src
Algorithm (noising mode):
- Run the source forward (dispreferred) and cache the sender’s head output and the receiver’s input/output.
- Run the target forward (preferred) twice: a. Clean: get the original differential. b. Patched: install a forward-pre-hook on the receiver that replaces only the contribution flowing from the sender’s head with the source-side value, leaving every other path untouched.
For head-level senders we splice the head’s output into the receiver’s input via the residual stream: the difference (source_head_out - target_head_out) is added/subtracted at the receiver’s input position.
Returns a PathPatchResult.
reward_lens.path_patching.PathPatchResult · also reward_lens.PathPatchResult
@dataclass
No docstring. See the source for detail.
Attributes
| Name | Type | Default |
|---|---|---|
sender | ComponentSpec | |
receiver | ComponentSpec | |
mode | str | |
original_differential | float | |
patched_differential | float | |
path_effect | float |
reward_lens.distortion.DistortionAnalyzer · also reward_lens.DistortionAnalyzer
DistortionAnalyzer(model: RewardModel) Analyze reward model for predicted hacking vulnerabilities.
This implements the distortion index framework from “Reward Hacking as Equilibrium under Finite Evaluation.” It predicts which quality dimensions are under-covered by current evaluation and thus likely to be hacked.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | A RewardModel instance. |
Methods
compute_distortion_index(
quality_dimensions: list[str],
evaluation_probes: dict[str, list[PreferencePair]],
cross_dimension_probes: Optional[list[tuple[PreferencePair, list[str]]]] = None,
coverage_threshold: float = 0.3,
distortion_threshold: float = 0.5,
max_length: int = 2048
) -> DistortionReport
src
analyze_agentic_amplification(
base_dimensions: list[str],
tool_count: int,
base_probes: dict[str, list[PreferencePair]],
max_length: int = 2048
) -> DistortionReport
src
As agents gain access to more tools, quality dimensions scale combinatorially while evaluation typically scales linearly. This method estimates the amplified distortion.
compare_evaluation_strategies(
quality_dimensions: list[str],
strategies: dict[str, dict[str, list[PreferencePair]]],
max_length: int = 2048
) -> dict[str, DistortionReport]
src
Useful for deciding which evaluation probes to invest in.
reward_lens.distortion.DistortionReport · also reward_lens.DistortionReport
@dataclass
Result of distortion index analysis.
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
quality_dimensions | list[str] | Names of the quality dimensions analyzed. | |
per_dimension_distortion | dict[str, float] | Distortion index per dimension (higher = more hackable). | |
under_covered_dimensions | list[str] | Dimensions with distortion above threshold. | |
predicted_hacking_severity | float | Overall predicted severity (0-1). | |
coverage_matrix | np.ndarray | Matrix showing which probes cover which dimensions. | |
effective_coverage | dict[str, float] | Effective coverage per dimension (0-1). | |
recommendations | list[str] | field(default_factory=list) | Suggested additional probes to reduce distortion. |
reward_lens.divergence_patching.DivergenceAwarePatching · also reward_lens.DivergenceAwarePatching
Bases: ActivationPatcher
DivergenceAwarePatching(
model: RewardModel,
distribution_estimator: Optional[DistributionEstimator] = None
) Activation patcher with divergence detection and constrained patching.
Extends the base ActivationPatcher to:
- Detect when interventions create OOD representations
- Classify divergences as harmless vs pernicious
- Provide reliability scores for causal claims
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | A RewardModel instance. |
distribution_estimator | Optional[DistributionEstimator] | None | Optional pre-computed distribution estimator. |
Methods
fit_distribution(
prompts: list[str],
responses: list[str],
max_length: int = 2048,
show_progress: bool = True
) -> None
src
Call this before patch_with_divergence_check for best results.
patch_with_divergence_check(
prompt: str,
preferred: str,
dispreferred: str,
mode: Literal['noising', 'denoising', 'zero', 'mean'] = 'noising',
divergence_threshold: float = 2.0,
max_length: int = 2048,
show_progress: bool = True,
mean_corpus: Optional[list[tuple[str, str]]] = None
) -> DivergenceAwarePatchingResult
src
constrained_patch(
prompt: str,
preferred: str,
dispreferred: str,
mode: Literal['noising', 'denoising'] = 'noising',
cl_weight: float = 0.1,
n_optimization_steps: int = 50,
max_length: int = 2048
) -> torch.Tensor
src
Uses a Counterfactual Latent (CL) loss to find a patched activation that achieves the intervention goal while minimizing divergence.
This is more expensive than standard patching but provides more reliable causal evidence.
reward_lens.divergence_patching.DivergenceAwarePatchingResult · also reward_lens.DivergenceAwarePatchingResult
@dataclass
Bases: PatchingResult
Extended patching result with divergence analysis.
Carries every field of :class:PatchingResult and adds the divergence
fields below.
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
divergence_info | list[DivergenceInfo] | field(default_factory=list) | Per-component divergence analysis. |
has_pernicious_divergence | bool | False | Whether any intervention has pernicious divergence. |
reliability_score | float | 1.0 | Overall reliability of causal claims (0-1). |
divergent_components | list[str] | field(default_factory=list) | List of components with significant divergence. |
reward_lens.cascade.MisalignmentCascadeDetector · also reward_lens.MisalignmentCascadeDetector
MisalignmentCascadeDetector(model: RewardModel) Detect correlated misalignment patterns across multiple dimensions.
This goes beyond HackingDetector’s individual bias tests to find systemic vulnerabilities where failures in one dimension predict failures in others.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | A RewardModel instance. |
Methods
detect_cascade(
dimensions: Optional[list[str]] = None,
custom_tests: Optional[dict[str, list[dict]]] = None,
correlation_threshold: float = 0.5,
n_bootstrap: int = 100,
max_length: int = 2048
) -> CascadeReport
src
cross_validate_with_hacking(
hacking_report: HackingReport,
cascade_report: Optional[CascadeReport] = None,
max_length: int = 2048
) -> dict[str, float]
src
Tests the paper’s key finding: reward hacking onset correlates with emergent misalignment.
reward_lens.cascade.CascadeReport · also reward_lens.CascadeReport
@dataclass
Result of misalignment cascade analysis.
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
dimensions_tested | list[str] | List of misalignment dimensions tested. | |
per_dimension_scores | dict[str, float] | Mean reward delta for each dimension. | |
correlation_matrix | np.ndarray | Pairwise correlation between dimensions. | |
cascade_risk_score | float | Overall systemic vulnerability (0-1). | |
correlated_pairs | list[tuple[str, str, float]] | Pairs of dimensions with significant correlation. | |
cascade_clusters | list[list[str]] | Groups of dimensions that fail together. | |
primary_failure_mode | Optional[str] | The dimension most predictive of others. | |
recommendations | list[str] | field(default_factory=list) | Suggested mitigations. |
reward_lens.conflict.RewardConflictAnalyzer · also reward_lens.RewardConflictAnalyzer
RewardConflictAnalyzer(model: RewardModel) Analyze conflicts between reward terms.
This helps identify when reward structures may cause models to hide reasoning (in-conflict terms) vs when optimization is safe (aligned or orthogonal terms).
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | A RewardModel instance. |
Methods
analyze_conflicts(
reward_terms: dict[str, torch.Tensor],
aligned_threshold: float = 0.5,
orthogonal_threshold: float = 0.2,
conflict_threshold: float = -0.3
) -> ConflictReport
src
learn_term_directions(
term_pairs: dict[str, list[tuple[str, str, str, str]]],
max_length: int = 2048
) -> dict[str, torch.Tensor]
src
For each term, provide pairs where the preferred response is better on that specific dimension. The direction is learned as the average difference in final-layer activations.
analyze_multi_objective_model(
objective_names: Optional[list[str]] = None
) -> ConflictReport
src
For models like ArmoRM that have multiple output dimensions, this extracts the direction for each objective and analyzes conflicts.
reward_lens.conflict.ConflictReport · also reward_lens.ConflictReport
@dataclass
Complete reward term conflict analysis.
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
term_names | list[str] | Names of analyzed reward terms. | |
term_directions | dict[str, torch.Tensor] | The direction vectors for each term. | |
pairwise_analysis | list[TermPairAnalysis] | Analysis for each pair of terms. | |
relationship_matrix | np.ndarray | Matrix of relationship classifications. | |
similarity_matrix | np.ndarray | Matrix of cosine similarities. | |
in_conflict_pairs | list[tuple[str, str]] | List of term pairs that are in conflict. | |
overall_conflict_score | float | 0-1 score of overall conflict severity. | |
monitorability_risk | float | Risk that models will hide reasoning. | |
recommendations | list[str] | field(default_factory=list) | Overall recommendations. |
reward_lens.conflict.quick_conflict_check · also reward_lens.quick_conflict_check
quick_conflict_check(
model: RewardModel,
term_pairs: dict[str, list[tuple[str, str, str]]],
max_length: int = 2048
) -> ConflictReport Convenience function for quick conflict analysis.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | RewardModel instance. |
term_pairs | dict[str, list[tuple[str, str, str]]] | required | Dict mapping term name to list of (prompt, preferred, dispreferred). |
max_length | int | 2048 | Maximum sequence length. |
Returns
| Type | Description |
|---|---|
ConflictReport | ConflictReport. |
reward_lens.concepts.ConceptExtractor · also reward_lens.ConceptExtractor
ConceptExtractor(model: RewardModel) Extract and analyze concept vectors from reward model activations.
This enables understanding which abstract concepts (confidence, formality, agreement, etc.) influence reward scores, and identifying potential reward hacking vulnerabilities.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | A RewardModel instance. |
Methods
extract_concepts(
concept_pairs: dict[str, list[tuple[str, str, str]]],
layer: Optional[int] = None,
max_length: int = 2048,
show_progress: bool = True
) -> dict[str, torch.Tensor]
src
For each concept, the direction is computed as the average difference between positive and negative example activations.
analyze_reward_alignment(
concept_vectors: dict[str, torch.Tensor],
alignment_threshold: float = 0.3,
hacking_concepts: Optional[list[str]] = None
) -> ConceptAlignmentReport
src
Concepts that strongly align with reward but represent surface properties (like confidence or verbosity) may indicate hackable biases.
intervene_on_concept(
prompt: str,
response: str,
concept_vector: torch.Tensor,
strength: float = 1.0,
layer: Optional[int] = None,
max_length: int = 2048
) -> float
src
Adds or subtracts the concept direction from activations to see how it affects reward.
reward_lens.concepts.ConceptAlignmentReport · also reward_lens.ConceptAlignmentReport
@dataclass
Report on concept-reward alignment analysis.
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
concepts | list[ConceptInfo] | List of analyzed concepts. | |
reward_aligned_concepts | list[str] | Concepts that significantly align with reward. | |
anti_reward_concepts | list[str] | Concepts that significantly oppose reward. | |
high_risk_concepts | list[str] | Concepts that may enable reward hacking. | |
overall_hacking_risk | float | Combined hacking risk from all concepts. | |
recommendations | list[str] | field(default_factory=list) | Suggested actions. |
reward_lens.concepts.quick_concept_analysis · also reward_lens.quick_concept_analysis
quick_concept_analysis(
model: RewardModel,
concept_pairs: Optional[dict[str, list[tuple[str, str, str]]]] = None,
max_length: int = 2048
) -> ConceptAlignmentReport Convenience function for quick concept analysis.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
model | RewardModel | required | RewardModel instance. |
concept_pairs | Optional[dict[str, list[tuple[str, str, str]]]] | None | Optional custom concept pairs. Uses defaults if None. |
max_length | int | 2048 | Maximum sequence length. |
Returns
| Type | Description |
|---|---|
ConceptAlignmentReport | ConceptAlignmentReport. |
reward_lens.sae.SAETrainer
SAETrainer(
d_model: int,
n_features: Optional[int] = None,
k: int = 32,
lr: float = 0.0003,
batch_size: int = 4096,
device: str = 'cuda'
) Train a TopK SAE on collected activations.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
d_model | int | required | Hidden dimension. |
n_features | Optional[int] | None | Dictionary size (typically 4x, 8x, or 16x d_model). |
k | int | 32 | Number of active features per input. |
lr | float | 0.0003 | Learning rate. |
batch_size | int | 4096 | Training batch size. |
device | str | 'cuda' | Device for training. |
Methods
train(
activations: torch.Tensor,
n_epochs: int = 5,
log_every: int = 100,
show_progress: bool = True
) -> TopKSAE
src