EMNLP 2026 · Main Conference
Quickstart · Cross-value transfer · Moral Foundations Theory · Your method · Citation
Does successful steering preserve the structure of human values? Steering Geometry evaluates both the geometry of steering directions and their behavioral effects across values. We study Schwartz's 20-value circumplex, test whether steering strengthens compatible values and suppresses opposing ones, and extend geometry evaluation to the six foundations of Moral Foundations Theory (MFT).
Official code for the paper, covering CAA, SAS, SphericalSteer, ODESteer, OPT, COLD-Steer, and BiPO.
Use Python 3.11 and a CUDA-capable GPU for model experiments. Geometry analysis of saved vectors can run on CPU.
git clone https://github.com/DeepRCL/Steering_Geometry.git
cd Steering_Geometry
conda env create -f environment.yml
conda activate steering-b300For private datasets or gated models, authenticate with hf auth login using an account with access, or set HF_TOKEN.
Download the exact Schwartz experiment input from Hugging Face:
hf download DeepRCL/SteeringGeometry data/final_dataset_200.csv \
--repo-type dataset --local-dir .
export STEERING_GEOMETRY_DATASET="$PWD/data/final_dataset_200.csv"The dataset card also covers the full 26,428-example Schwartz benchmark and 1,200-example MFT set.
python reproduction/run.py --experiment qwen_base_caa --executeThis runs extraction, layer selection, steering evaluation, and geometry analysis. Omit --execute to inspect the command first.
Results are saved under outputs/paper/qwen-base/caa/Qwen__Qwen3.5-9B-Base/:
| Output | What to inspect |
|---|---|
geometry/geometry_metrics.json |
Geometry alignment scores |
geometry/mds_circumplex.png |
Recovered value arrangement |
geometry/empirical_similarity_heatmap.png |
Pairwise value similarities |
evaluation/evaluation_summary.json |
Steering performance across strengths |
python -m json.tool \
outputs/paper/qwen-base/caa/Qwen__Qwen3.5-9B-Base/geometry/geometry_metrics.jsonFor other methods and backbones, run python reproduction/run.py --list and choose an experiment from reproduction/experiments.json. SAS also requires --supplement pointing to a validated Touché supplement.
Steering one value can change behavior on many others. This evaluation tests whether those changes follow Schwartz's theory: compatible values should improve, while opposing values should decrease.
For each source value, the evaluator applies steering and measures the change from unsteered accuracy on every target value's held-out examples. The resulting 20 × 20 transfer matrix captures the effects across the full value space. Two-way centering removes overall source and target effects before computing Continuous Transfer Fidelity (TWTM) and Hierarchical Transfer Fidelity (ρHᵗʳ).
After the CAA quickstart completes, run:
python -m experiments.cross_value_transfer.run \
--model_name Qwen/Qwen3.5-9B-Base \
--caa_run_dir outputs/paper/qwen-base/caa/Qwen__Qwen3.5-9B-Base \
--eval_dataset "$STEERING_GEOMETRY_DATASET" \
--relations_path CAA/value_data/schwartz_relations-new.json \
--methods caa --output_dir outputs/cross-value-transferUnder outputs/cross-value-transfer/, inspect each method's T_heatmap.png and T_heatmap_residualized.png for the transfer pattern, and metrics.json for fidelity scores. The root-level comparison_table.json and comparison_table.png summarize the evaluated methods.
Run the methods you want to compare, then copy the provided configuration:
cp reproduction/cross_value_transfer.qwen_base.example.json \
reproduction/cross_value_transfer.qwen_base.jsonSet the saved method directories and dataset path in the copied file, then run:
python -m experiments.cross_value_transfer.run \
--config reproduction/cross_value_transfer.qwen_base.jsonKeep the backbone and held-out evaluation split fixed, and specify the appropriate steering strength for each method. To evaluate a new intervention alongside these baselines, follow Evaluate your own steering method.
The framework also evaluates the six foundations of revised Moral Foundations Theory: Care, Equality, Proportionality, Loyalty, Authority, and Purity. The benchmark contains 1,200 examples, balanced at 200 per foundation.
In the paper's family-level analysis, Care and Equality form the Individualizing family; Proportionality, Loyalty, Authority, and Purity form the Binding family. ΔMFT measures within-family versus cross-family similarity. MFT evaluation tests family separation rather than imposing Schwartz's circular ordering or opposing-value relationships.
Run a CAA example on the MFT data:
hf download DeepRCL/SteeringGeometry data/MFT.csv \
--repo-type dataset --local-dir .
python -m CAA.Geometry.run_pipeline \
--model_name Qwen/Qwen3.5-9B-Base \
--dataset_path data/MFT.csv \
--value_framework mft --steering_method caa \
--geometry_transform centered_renorm \
--modules all --output_dir outputs/mft/caaMetrics and plots are saved under outputs/mft/caa/Qwen__Qwen3.5-9B-Base/geometry/.
For Schwartz geometry, extract one direction per value using the labels in SCHWARTZ_CIRCUMPLEX_ORDER. For nonlinear or input-dependent methods, use the mean effective shift mean(steered_activation - original_activation) at a fixed layer over matched prompts, as in the paper.
Save your extracted vectors as a dictionary of 1-D tensors of the same hidden dimension:
import torch
from CAA.Geometry.config import SCHWARTZ_CIRCUMPLEX_ORDER
# vectors: your {value_name: extracted_direction} mapping for all 20 values.
assert set(SCHWARTZ_CIRCUMPLEX_ORDER).issubset(vectors)
torch.save(
{value: vectors[value].detach().float().cpu()
for value in SCHWARTZ_CIRCUMPLEX_ORDER},
"my_method_vectors.pt",
)steering-geometry --vectors my_method_vectors.pt \
--output outputs/my_method --title "My method"The CLI writes geometry_metrics.json, similarity heatmaps, and circumplex plots. Compare ρT, rT, ρH, and Δpol with the CAA results above using the same backbone, data, and extraction protocol. The default centered_renorm transform applies the paper's mean-centering and normalization. .npz banks and directories of per-value vectors are also supported.
To add your own intervention, implement SteeringMethod: name, layer, load_vectors(), apply_hook(), and remove_hook(). Use caa_method.py as an example, then add your adapter to _build_methods in run.py and provide any required configuration fields. Run both with --methods caa,my_method after registration, keeping the evaluation split fixed and specifying the appropriate steering strength for each method.
The steering-geometry CLI above evaluates the 20-value Schwartz bank. For MFT, use the framework-aware pipeline with --value_framework mft as shown above.
If you use the code or data, please cite our paper:
@misc{abootorabi2026steeringgeometryvalidatinghuman,
title={Steering Geometry: Validating Human Value Geometry in LLM Steering Space},
author={Mohammad Mahdi Abootorabi and Armin Saghafian and Ali Bazshoushtari and Hamid Rezaei and EunJeong Hwang and Vered Shwartz and Parvin Mousavi and Purang Abolmaesumi},
year={2026},
eprint={2609.06289},
archivePrefix={arXiv},
primaryClass={cs.CL},
url={https://arxiv.org/abs/2609.06289},
}We thank the authors of the following open-source codebases, which supported our implementation and experiments:
Questions or contributions? Open an issue.
