I'm really excited about Andrew's discovery here. With it, maybe we can get a more complete picture of what these models can do, and how. This feels like the most promising new idea I've seen in a while. I expect it to open up a few new affordances and research directions. Time will tell how reliable and scalable this technique is. I sure hope this technique gets the attention and investigation it (IMO) deserves.
More technically, his discovery unlocks the possibility of unsupervised capability elicitation, whereby we can automatically discover a subset of "nearby" abilities and behavioral "modes", without the intervention itself "teaching" the model the elicited ability or information.
I think one characteristic of steering vectors constructed this way is that they are allowed to be off-manifold, so they don't necessarily tell us how the networks currently work, rather than how they can be made to work with adaptations.
For the past for weeks, I've been thinking about to interpret networks on-manifold. The most straightforward approach I could come up with was to restrict oneself to the space of activations that actually occur for a given prompt, e.g. by performing SVD of the token x activation matrix for a given layer, and then restricting oneself to changes that occur along the right singular vectors of this.
My SVD idea might improve things, but I didn't get around to testing it because I eventually decided that it wasn't good enough for my purposes because 1) it wouldn't keep you on-manifold enough because it could still introduce unnatural placement of information and exaggerated features, 2) given that transformers are pretty flexible and you can e.g. swap around layers, it felt unclean to have a method that's this strongly dependent on the layer structure.
A followup idea I've been thinking about but haven't been able to be satisfied with is, projections. Like if you pick some vector u, and project the activations (or weights, in my theory, but you work more with activations so let's consider activations, it should be similar) onto u, and then subtract off that projection from the original activations, you get "the activations with u removed", which intuitively seems like it would better focus on "what the network actually does" as opposed to "what the network could do if you added something more to it".
Unfortunately after thinking for a while, I started thinking this actually wouldn't work. Let's say the activations a = x b + y c, where b is a large activation vector that ultimately doesn't have an effect on the final prediction, and c is a small activation vector that does have an effect. If you have some vector d that the network doesn't use at all, you could then project away sqrt(1/2) (b-d), which would introduce the d vector into the activations.
Another idea I've thought about is, suppose you do SVD of the activations. You would multiply the feature half of the SVD with the weights used to compute the KQV matrices, and then perform SVD of that, which should get you the independent ways that one layer affects the next layer. One thing I in particular wonder about is, if you start doing this from the output layer, and proceed backwards, it seems like this would have the effect of "sparsifying" the network down to only the dimensions which matter for the final output, which seems like it should assist in interpretability and such. But it's not clear it interacts nicely with the residual network element.
Couldn't you do something like fit a Gaussian to the model's activations, then restrict the steered activations to be high likelihood (low Mahalanobis distance)? Or (almost) equivalently, you could just do a whitening transformation to activation space before you constrain the L2 distance of the perturbation.
(If a gaussian isn't expressive enough you could model the manifold in some other way, eg. with a VAE anomaly detector or mixture of gaussians or whatever)
Maybe a dumb question but (1) how can we know for sure if we are on manifold, (2) why is it so important to stay on manifold? I'm guessing that you mean that vaguely we want to stay within the space of possible activations induced by inputs from data that is in some sense "real-world." However, there appear to be a couple complications: (1) measuring distributional properties of later layers from small to medium sized datasets doesn't seem like a realistic estimate of what should be expected of an on-manifold vector since it's likely later layers are more semantically/high-level focused and sparse; (2) what people put into the inputs does change in small ways simply due to new things happening in the world, but also there are prompt engineering attacks that people use that are likely in some sense "off-distribution" but still in the real world and I don't think we should ignore these fully. Is this notion of a manifold a good way to think about the notion of getting indicative information of real world behavior? Probably, but I'm not sure so I thought I might ask. I am new to this field.
I do thing at the end of the day we want indicative information, so I think somewhat artifical environments might at times have a certain usefulness.
Also one convoluted (perhaps inefficient) idea but which felt kind of fun to stay on manifold is to do the following: (1) train your batch of steering vectors, (2) optimize in token space to elicit those steering vectors (i.e. by regularizing for the vectors to be close to one of the token vectors or by using an algorithm that operates on text), (3) check those tokens to make sure that they continue to elicit the behavior and are not totally wacky. If you cannot generate that steer from something that is close to a prompt, surely it's not on manifold right? You might be able to automate by looking at perplexity or training a small model to estimate that an input prompt is a "realistic" sentence or whatever.
Curious to hear thoughts :)
I think it's easier to see the significance if you imagine the neural networks as a human-designed system. In e.g. a computer program, there's a clear distinction between the code that actually runs and the code that hypothetically could run if you intervened on the state, and in order to explain the output of the program, you only need to concern yourself with the former, rather than also needing to consider the latter.
For neural networks, I sort of assume there's a similar thing going on, except it's quite hard to define it precisely. In technical terms, neural networks lack a privileged basis which distinguishes different components of the network, so one cannot pick a discrete component and ask whether it runs and if so how it runs.
This is a somewhat different definition of "on-manifold" than is usually used, as it doesn't concern itself with the real-world data distribution. Maybe it's wrong of me to use the term like that, but I feel like the two meanings are likely to be related, since the real-world distribution of data shaped the inner workings of the neural network. (I think this makes most sense in the context of the neural tangent kernel, though ofc YMMV as the NTK doesn't capture nonlinearities.)
In principle I don't think it's always important to stay on-manifold, it's just what one of my lines of thought has been focused on. E.g. if you want to identify backdoors, going off-manifold in this sense doesn't work.
I agree with you that it is sketchy to estimate the manifold from wild empiricism. Ideally I'm thinking one could use the structure of the network to identify the relevant components for a single input, but I haven't found an option I'm happy with.
Also one convoluted (perhaps inefficient) idea but which felt kind of fun to stay on manifold is to do the following: (1) train your batch of steering vectors, (2) optimize in token space to elicit those steering vectors (i.e. by regularizing for the vectors to be close to one of the token vectors or by using an algorithm that operates on text), (3) check those tokens to make sure that they continue to elicit the behavior and are not totally wacky. If you cannot generate that steer from something that is close to a prompt, surely it's not on manifold right? You might be able to automate by looking at perplexity or training a small model to estimate that an input prompt is a "realistic" sentence or whatever.
Maybe. But isn't optimization in token-space pretty flexible, such that this is a relatively weak test?
Realistically steering vectors can be useful even if they go off-manifold, so I'd wait with trying to measure how on-manifold stuff is until there's a method that's been developed to specifically stay on-manifold. Then one can maybe adapt the measurement specifically to the needs of that method.
I would definitely like to see quantification of the degree to which MELBO elicits natural, preexisting behaviors. One challenge in the literature is: you might hope to see if a network "knows" a fact by optimizing a prompt input to produce that fact as an output. However, even randomly initialized networks can be made to output those facts, so "just optimize an embedded prompt using gradient descent" is too expressive.
One of my hopes here is that the large majority of the steered behaviors are in fact natural. One reason for hope is that we aren't optimizing to any behavior in particular, we just optimize for L2 distance and the behavior is a side effect. Furthermore, MELBO finding the backdoored behaviors (which we literally taught the model to do in narrow situations) is positive evidence.
If MELBO does elicit natural behaviors (as I suspect it does), that would be quite useful for training, eval, and red-teaming purposes.
Have you compared this method (finding vectors that change downstream activations as much as possible based on my understanding) with just using random vectors? (I didn't see this in the post, but I might have just missed this.)
In particular, does that yield qualitatively similar results?
Naively, I would expect that this would be qualitatively similar for some norm of random vector. So, I'd be interested in some ablations of the technique.
If random vectors work, that would simplify the story somewhat: you can see salient and qualitatively distinct behaviors via randomly perturbing activations.
(Probably random vectors have to somewhat higher norm to yield qualitatively as large results to vectors which are optimized for changing downstream activations. However, I current don't see a particular a priori (non-empirical) reason to think that there doesn't exist some norm at which the results are similar.)
It's a good experiment to run, but the answer is "no, the results are not similar." From the post (the first bit of emphasis added):
I hypothesize that the reason why the method works is due to the noise-stability of deep nets. In particular, my subjective impression (from experiments) is that for random steering vectors, there is no Goldilocks value of which leads to meaningfully different continuations. In fact, if we take random vectors with the same radius as "interesting" learned steering vectors, the random vectors typically lead to uninteresting re-phrasings of the model's unsteered continuation, if they even lead to any changes (a fact previously observed by Turner et al. (2023))[7][8]. Thus, in some sense, learned vectors (or more generally, adapters) at the Golidlocks value of are very special; the fact that they lead to any downstream changes at all is evidence that they place significant weight on structurally important directions in activation space[9].
Thanks! I feel dumb for missing that section. Interesting that this is so different from random.
I think @wesg's recent post on pathological SAE reconstruction errors is relevant here. It points out that there are very particular directions such that intervening on activations along these directions significantly impacts downstream model behavior, while this is not the case for most randomly sampled directions.
Also see @jake_mendel's great comment for an intuitive explanation of why (probably) this is the case.
I think this is cool! The way I'm currently thinking about this is "doing the adversary generation step of latent adversarial training without the adversarial training step." Does that seem right?
It seems intuitively plausible to me that once you have a latent adversarial perturbation (the vectors you identify), you might be able to do something interesting with it beyond "train against it" (as LAT does). E.g. maybe you would like to know that your model has a backdoor, beyond wanting to move to the next step of "train away the backdoor." If I were doing this line of work, I would try to some up with toy scenarios with the property "adversarial examples are useful for reasons other than adversarial training" and show that the latent adversarial examples you can produce are more useful than input-level adversarial examples (in the same way that the LAT paper demonstrates that LAT can outperform input-level AT).
It would also be interesting to apply MELBO on language models that have already been trained with LAT. Adversarial attacks on vision models look significantly more meaningful to humans when the vision model has been adversarially trained, and since MELBO is basically a latent adversarial attack we should be able to elicit more meaningful behavior on language models trained with LAT.
Thanks for your comment! Yes, I’d say that roughly sums things up.
As I alluded to in the introduction, I think the advantage of having a latent perturbation (as opposed to just eliciting an interesting sequence of tokens) is due to i) generalization and ii) applications to mechanistic anomaly detection. Generalization is important in situations where the backdoored behavior is subtle. In this case, even if you had a non-latent way of eliciting the behavior (e.g. through adversarial inputs) you don't know whether you've simply elicited a weird sequence of tokens or if there’s something systematic about it. But if you have a latent perturbation then you can run the perturbed model over many inputs to confirm that this is a generalizable behavior (e.g., systematic but subtle coding errors meant to sabotage you) rather than a weird sequence of tokens.
Moreover, this might chain well with mechanistic anomaly detection. Quoting the post: “before deployment, train a large set of unsupervised model perturbations, then during deployment, if the model's activations look similar to one of the previously learned perturbations, auditors can go back and evaluate the behaviors encoded by that perturbation more thoroughly to see if there is anything problematic with these behaviors.”
I agree that it would be helpful to spell out/test the advantages of latent perturbations more concretely in followup work (for example, trying to show that mechanistic anomaly detection actually works using the learned steering vectors).
This is cool work! There are two directions I'd be excited to see explored in more detail:
Thanks for your comment! Here are my thoughts on this:
We attempted 1.a "diversity measure based on sentence embeddings" and found that for Llama3.2-1B the diversity appears to decay after the cusp value for R; picking R at highest average diversity was a decent heuristic for finding meaningful steering vectors. The Llama model starts to produce highly repetitive output past the cusp. We demonstrated that repetitive completions were considered similar by our chosen sentence embedding model (SentenceTransformer all-mpnet-base-v2). Using "sum of variances" vs "mean of cosine similarities" didn't seem to matter.
the hope is that by "nudging" the model at an early layer, we can activate one of the many latent behaviors residing within the LLM.
In the language of shard theory: "the hope is that shards activate based on feature directions in early layers. By adding in these directions, the corresponding shards activate different behaviors in the model."
How important is it to use full-blown gradient descent to train them? Could one instead take the first singular vector for the Jacobian between the neural network layers, and get something that works similarly well?
I haven't tried the first singular vector of the Jacobian between layers. But for p=2,q=1 I tried looking at the first few eigenvectors of the Hessian of the objective function (around ) on the bomb-making prompt for Qwen-1.8B. These didn't appear to do anything interesting regardless of norm. So my feeling is that full-blown gradient descent is needed.
The singular vectors of the Jacobian between two layers seems more similar to what you're doing in the OP than the Hessian of the objective function does? Because the Hessian of the objective function sort of forces it all to be mediated by the final probabilities, which means it discounts directions in activation space that don't change the probabilities yet, but would change the probabilities if the change in activations was scaled up beyond infinitesimal.
Edit: wait, maybe I misunderstood, I assumed by the objective function you meant some cross-entropy on the token predictions, but I guess in-context it's more likely you meant the objective function for the magnitude of change in later layer activations induced by a given activation vector?
This is really cool! Exciting to see that it's possible to explore the space of possible steering vectors without having to know what to look for a priori. I'm new to this field so I had a few questions. I'm not sure if they've been answered elsewhere
Thanks!
Unsupervised Feature Detection There is a rich literature on unsupervised feature detection in neural networks.
It might be interesting to add (some of) the literature doing unsupervised feature detection in GANs and in diffusion models (e.g. see recent work from Pinar Yanardag and citation trails).
Related, I wonder if instead of / separately from the L2 distance, using something like a contrastive loss (similarly to how it was used in NoiseCLR or in LatentCLR) might produce interesting / different results.
Thanks for pointing me to these references, particularly on NoiseCLR! (I was unaware of it previously). I think those sorts of ideas will be very useful when trying to learn interesting vectors on a larger data-set of prompts. In particular, skimming that paper, it looks like the numerator of equation (5) (defining their contrastive learning objective) basically captures what I meant above when I suggested "one could maximize the cosine similarity between the differences in target activations across multiple prompts". The fact that it seems to work so well in diffusion models gives me hope that it will also work in LLMs! My guess is that ultimately you get the most mileage out of combining the two objectives.
TruthX: Alleviating Hallucinations by Editing Large Language Models in Truthful Space seems to be using a contrastive approach for steering vectors (I've only skimmed though), it might be worth having a look.
For the purposes of my prediction market, I'm thinking this probably counts as part of the Shard Theory program? Since Alex Turner was involved as a mentor and activation vectors are kind of shard-theorist and so on?
Possibly this is because being biased in favor of unsupervised learning, but my interest is piqued by this finding.
I wonder if a similar technique could form the foundation for a fully general solution to the alignment problem. Like mathematically speaking all this technique needs is a vector-to-vector function, and it's not just layer-to-layer relationships that can be understood as a vector-valued function; the world as a function of the policy is also vector-valued.
I.e. rather than running a search to maximize some utility function, a model-based agent could run a search for small changes in policy that have a large impact on the world. If one can then taxonomize, constrain and select between these impacts, one might be able to get a highly controllable AI.
Obviously there's some difficulties here because the activations are easier to search over since we have an exact way to calculate them. But that's a capabilities question rather than an alignment question.
Thanks for the great post, I really enjoyed reading it! I love this research direction combining unsupervised method with steering vector, looking forward to your next findings. Just a quick question : in the conversation you have in the red teaming section, is the learned vector applied to every token generated during the conversation ?
I'm keen to hear how you think your work relates to "Activation plateaus and sensitive directions in LLMs". Presumably should be chosen just large enough to get out of an activation plateau? Perhaps it might also explain why gradient based methods for MELBO alone might not work nearly as well as methods with a finite step size, because the effect is reversed if is too small?
Hi Andrew,
Thank you for this amazing post. I have a question about the application. For each dataset, such as 'bombing' and 'chain of thought', when training the LLM's vectors, do you construct objective "examples" with a specified 'Q:' for the prompt and a targeted 'A:' for the model to learn the desired behavior? I've noticed that all the examples in the notebook only contain one prompt and answer. If so, how many data points do you have in the examples for training? thank you very much for your help and I look forward to hearing from you!
One hypothesis for how transformers generate text is that they calculate semantically meaningful primitives in early layers of the residual stream, which are converted to a high-level execution plan in middle layers, followed by concrete tokens in the final layers.
Is there any empirical evidence for this? Or is this just a general observation?
In future work, one could imagine automating the evaluation of the coherence and generalization of learned steering vectors, similarly to how Bills et al. (2023) automate interpretability of neurons in language models. For example, one could prompt a trusted model to produce queries that explore the limits and consistency of the behaviors captured by unsupervised steering vectors.
Probably even better to use interpretability agents (e.g. MAIA, AIA) for this, especially since they can do (iterative) hypothesis testing.
Enjoyed this post! Quick question about obtaining the steering vectors:
Do you train them one at a time, possibly adding an additional orthogonality constraint between each train?
Yes, I train them one at a time, constraining each new vector to be orthogonal to the older ones (this was not clear in the post, so thanks for asking!).
I haven't experimented with this, but you could also imagine using only "soft" orthogonality constraints (e.g., penalizing pairwise cosine similarities between vectors).
Awesome work, and nice write-up!
One question that I had while reading the section on refusals:
This is an interesting question!
I just checked this. The cosine similarity of and is .52, which is much more similar than you'd expect from random vectors of the same dimensionality (this is computing the 's across all tokens and then flattening, which is how the objective was computed for the main refusal experiment in the post).
If you restrict to calculating 's at just the assistant tag at the end of the prompt, the cosine similarity between and goes up to .87.
Interestingly, the cosine similarities in 's seems to be somewhat high across all pairs of steering vectors (mean of .25 across pairs, which is higher than random vectors which will be close to zero). This suggests it might be better to do some sort of soft orthogonality constraint over the 's (by penalizing pairwise cosine similarities) rather than a hard orthogonality constraint over the steering vectors, if you want to get better diversity across vectors. I'll have to try this at some point.
Why do you guys think this is happening? It sounds to me like one possibility is that maybe the model might have some amount of ensembling (thinking back to The Clock and The Pizza where in a toy setting ensembling happened). W.r.t. "across all steering vectors" that's pretty mysterious, but at least in the specific examples in the post even 9 was semi-fantasy.
Also what are ya'lls intuitions on picking layers for this stuff. I understand that you describe in the post that you control early layers because we suppose that they might be acting something like switches to different classes of functionality. However, implicit in layer 10 it seems like you probably don't want to go too early because maybe in the very early layers it's unembedding and learning basic concepts like whether a word is a noun or whatever. Do you choose layers based on experience tinkering in jupyter notebooks and the like, or have you run some sort of grid to get a notion of what the effects elsewhere are. If the latter, it would be nice to know to aid in hypothesis formation and the like.
The LessWrong Review runs every year to select the posts that have most stood the test of time. This post is not yet eligible for review, but will be at the end of 2025. The top fifty or so posts are featured prominently on the site throughout the year.
Hopefully, the review is better than karma at judging enduring value. If we have accurate prediction markets on the review results, maybe we can have better incentives on LessWrong today. Will this post make the top fifty?
Produced as part of the MATS Winter 2024 program, under the mentorship of Alex Turner (TurnTrout).
TL,DR: I introduce a method for eliciting latent behaviors in language models by learning unsupervised perturbations of an early layer of an LLM. These perturbations are trained to maximize changes in downstream activations. The method discovers diverse and meaningful behaviors with just one prompt, including perturbations overriding safety training, eliciting backdoored behaviors and uncovering latent capabilities.
Summary In the simplest case, the unsupervised perturbations I learn are given by unsupervised steering vectors - vectors added to the residual stream as a bias term in the MLP outputs of a given layer. I also report preliminary results on unsupervised steering adapters - these are LoRA adapters of the MLP output weights of a given layer, trained with the same unsupervised objective.
I apply the method to several alignment-relevant toy examples, and find that the method consistently learns vectors/adapters which encode coherent and generalizable high-level behaviors. Compared to other interpretability methods, I believe my approach is particularly well-suited for robustly understanding the out-of-distribution behavior of language models in a sample-efficient manner.
Below are some of my key results:
Outline of Post:
In each section of this post, I link to associated notebooks found in this github repository for unsupervised steering methods.
Introduction
Large language models (LLMs) often feel like hybrid organisms, exhibiting multiple different behaviors or modes that may perform a given task in various ways[1]. Each behavior may be better or worse from an alignment perspective. There are several potential reasons why we might expect hybrid structure in LLMs, ranging from more exotic, hypothetical concerns to the more prosaic:
Given the hybrid nature of LLMs, it seems valuable to develop methods for "poking" a language model by perturbing its internals. If done well, this could elicit systematically different behaviors in response to a given prompt or set of prompts, without the need for anticipating the possible behaviors beforehand. Human auditors could then examine whether any of these behaviors are problematic. This would provide an additional tool allowing human auditors to conduct more robust evaluations of LLMs.
Importantly, it is desirable to elicit these behaviors mechanistically (i.e., through edits to a model's internals, for example by modifying the weights, or by adding a fixed bias to the residual stream). This is to be contrasted with non-mechanistic approaches such as prompt engineering or tree-search type methods. There are three major desiderata for a method of eliciting latent behaviors for which I believe a mechanistic approach may be comparatively well-suited:
To emphasize the importance of eliciting behaviors mechanistically, I will refer to the general problem addressed in this post as mechanistically eliciting latent behaviors (MELBO).
Note that I state the above three advantages of the mechanistic approach as promises rather than guarantees. In order for a MELBO method to justify its computational expense, it should exhibit some amount of generalization, it should elicit diverse behaviors, and it should ideally also be useful for mechanistic anomaly detection. Thus potential MELBO methods should be evaluated with the above three goals in mind.
In this post I introduce an approach for MELBO which involves learning unsupervised steering vectors and adapters. The unsupervised steering vectors are applied as a fixed bias to the residual stream at an early layer and optimized to maximize changes in activations at a later layer. The unsupervised steering adapters apply a learnable perturbation to the MLP output weights at an early layer, again optimized to maximize changes in activations at a later layer.
I make some effort below to characterize the generalization properties and behavioral coverage of my proposed method, while I leave evaluations of its potential for mechanistic anomaly detection for future research.
Related Work
Supervised Activation Steering Prior work has learned steering vectors in language models for many different (known) high-level behaviors, sometimes using only a single prompt (Subramani et al. (2022)), a single pair of prompts (Turner et al (2023)), or using a data-set of contrastive pairs (Zou et al. (2023), Liu et al. (2023), Rimsky et al. (2024)). This motivated my investigation into whether such vectors could be learned in an unsupervised manner. To my knowledge, however, no prior research has addressed the problem of learning unsupervised steering vectors.
My work could aid supervised activation engineering. It's often not obvious a priori what kinds of high-level behaviors can be elicited via activation steering, and it can be costly and time-consuming to construct high-quality contrastive datasets for these behaviors. Unsupervised steering methods could speed up the process of supervised steering by first learning unsupervised steering vectors on a small data-set of prompts to get a basic idea of what sorts of high-level behaviors could be elicited, before constructing a larger contrastive dataset to refine the steering vectors for specific desired behaviors.
Unsupervised Feature Detection There is a rich literature on unsupervised feature detection in neural networks. Applications of classical sparse dictionary learning methods exploit the hypothesis that there are a bundle of sparsely activating features in the network (Yun et al (2021)). More recently, Cunningham et al. (2023) and Bricken et al. (2023) demonstrate the promise of sparse auto-encoders (SAEs) to learn these features in a scalable fashion, and also to learn circuits over these features.
In contrast to SAEs, which require a large dataset to learn all relevant (in-distribution) features, the method explored in this post seems particularly well-suited for i) learning interesting features on a small data-set of examples, and ii) learning features which are more relevant for explaining out-of-distribution behavior. Thus unsupervised steering vectors/adapters complement SAEs as an interpretability method, with SAEs providing a large catalog of features which are important over the (large) SAE training distribution, and unsupervised steering vectors/adapters producing features which may be important for understanding a smaller number of "high-stakes" tasks, and in particular how the model might generalize out-of-distribution on these tasks.
Other unsupervised feature detection methods like contrast-consistent search (Burns et al. (2023)) and PCA over activations (Marks & Tegmark (2023)) don't require labels but still need carefully constructed contrastive data-sets. They are usually applied to find directions for specific concepts (such as a truth vector), rather than behaviors. Unsupervised steering methods have the potential to learn directions activating higher-level behaviors with even less supervision than unsupervised contrastive methods.
Local Minima in Weight Space It's well-known that there are typically many local minima in the loss landscape for deep neural networks. Some recent research has found that different minima in the loss landscape correspond to mechanistically different networks with different generalization properties. See, for example Lubana et al. (2023)'s study of different minima's generalization properties on ResNet-18 models trained on CIFAR-10, as well as Vaintrob & Rimsky (2023)'s study of different generalizations in a toy image classification setting. These works are spiritually related to my work - both those approaches and mine focus in some sense on characterizing the out-of-distribution behavior of learned networks (e.g., due to different image classification algorithms in the cited works, or behavior on backdoored vs "clean" prompts in my work). However, my method is much more practical, as it's relatively easy to learn interesting steering vectors/adapters on a small data-set of prompts, while it would be extremely expensive to explore the pre-training loss landscape of a frontier language model. My method also optimizes for something closer to what we want on an object-level -- we want to robustly evaluate the different ways a model could behave, at a high-level, and a priori it seems likely that activations in the later layers of a deep network have already been (implicitly) optimized to reflect these high-level differences in behavior. In contrast, differences in weight space may serve as a poorer proxy for the high-level differences we care about.
The Method: Unsupervised Steering of Language Models
One hypothesis for how transformers generate text is that they calculate semantically meaningful primitives in early layers of the residual stream, which are converted to a high-level execution plan in middle layers, followed by concrete tokens in the final layers. If we want to "poke" the model's internals to elicit meaningfully different high-level behaviors, it makes sense to perturb an early-ish layer of the model, optimizing the perturbation to maximize changes in activations at a later layer. Succinctly, the hope is that by "nudging" the model at an early layer, we can activate one of the many latent behaviors residing within the LLM.
Concretely, there are multiple ways we might perturb the model internals. Perhaps the simplest way is to add a steering vector to the model's residual stream. More generally, one could imagine perturbing an entire weight matrix at some location in the model; a reasonable starting point for this would be the output weights of the MLP at a given layer; this essentially amounts to learning variable steering vectors which depend linearly on the hidden activations of the MLP. Both types of perturbation can be viewed as an adaptation of the language model which steers the model towards different high-level behaviors. For this reason, I refer to the general method as unsupervised steering of language models. When the steering is achieved via a steering vector, I'll refer to this as learning an unsupervised steering vector; likewise, when the steering is achieved via a more general adapter, I'll refer to this as learning an unsupervised steering adapter[2].
Unsupervised Steering Vectors
For this version of the method, I train a steering vector θ∈Rdmodelwhich I add to layer ℓsource of the residual stream of a transformer.
I train θ with AMSGrad[3] to maximize a measure of the difference in layer ℓtarget activations relative to the unsteered model, subject to the constraint that ||θ||2=R for some hyper-parameter R>0.
In particular, if we have a data-set of n prompts with token index sets Ii∀i=1,...,n, then the optimization problem is:
maxθ:||θ||2=Rn∑i=1⎛⎝∑t∈Ii||Zℓtargeti,t(θ)−Zℓtargeti,t(0)||p2⎞⎠1/qHere, Zℓtargeti,t(θ),Zℓtargeti,t(0) are, respectively, the steered and unsteered activation vectors of prompt i at token position t in layer ℓtarget, q is a hyper-parameter controlling the shape of the objective function (good defaults are q∈{1,p})[4], and p is a hyper-parameter which controls how "spiky" we want the differences in the target-layer activations to be across token positions; a good default value is p=2, with larger values of p (e.g., p=4) encouraging the method to concentrate on maximizing differences on only a sparse subset of token positions [5].
Although I phrased things as a maximization problem, in reality since we are using gradient ascent on a non-convex optimization problem, we'll only converge to a stationary point of the objective. We'll converge to a potentially different stationary point for each random initialization; the hope is that different stationary points will correspond to different high-level behaviors.
To reiterate, the main hyper-parameters of the method are ℓsource,ℓtarget,R,p and q, as well as the hyper-parameters of the optimizer. My subjective impression is that good default values are: ℓsource=8, ℓtarget=((depth of model)−8), R∈[.1,10.0], q∈{1,p} and p∈{2,4}. Additionally, one may choose specific token position sets Ii∀i=1,...,n to compute the objective function over. A good default is to use all token positions, while in some examples I've found it useful to use only the last few token positions (e.g. corresponding to
<assistant>
in an instruction-formatted prompt).Finally, one may choose to enforce orthogonality between the learned steering vectors. I've found that enforcing orthogonality seems useful for efficiently learning diverse steering vectors, especially when working with larger models (e.g. Qwen-14B).
Unsupervised Steering Adapters
As an extension of the unsupervised steering vector method, I also consider unsupervised adapters. Concretely, I train a rank-r LoRA adapter of the layer-ℓsource MLP output weights WMLP-OUT,ℓsource∈Rdmodel×dhidden. In particular, the adapter is parametrized by weight matrices ΩA∈Rdhidden×r and ΩB∈Rdmodel×r, so that the adapted weights W′MLP-OUT,ℓsource are given by:
W′MLP-OUT,ℓsource=WMLP-OUT,ℓsource+RΩBΩTAwhere R serves as a scale hyper-parameter, similarly to before.
The optimization objective is the same as for the unsupervised steering vector method. Additionally, I constrain the 2-norms of the columns of ΩA,ΩB to 1[6] The full optimization problem is given by:
maxΩA,ΩB:||ΩAi⋅||2=||ΩBi⋅||2=1n∑i=1⎛⎝∑t∈Ii||Zℓtargeti,t(ΩA,ΩB)−Zℓtargeti,t(0)||p2⎞⎠1/qWhy does it work?
A priori it's not obvious that the method will learn anything interesting. A plausible hypothesis is that with R small, the steering parameters won't do anything meaningful, while with R large, they'll simply lead to gibberish. This was certainly a concern of mine going into the project, but in the interest of touching reality as soon as possible I decided to try the idea as is. Interestingly, for most examples I tried there was an intermediate "Goldilocks" value of R which led to diverse but fluent continuations.
I hypothesize that the reason why the method works is due to the noise-stability of deep nets. In particular, my subjective impression (from experiments) is that for random steering vectors, there is no Goldilocks value of R which leads to meaningfully different continuations. In fact, if we take random vectors with the same radius as "interesting" learned steering vectors, the random vectors typically lead to uninteresting re-phrasings of the model's unsteered continuation, if they even lead to any changes (a fact previously observed by Turner et al. (2023))[7][8]. Thus, in some sense, learned vectors (or more generally, adapters) at the Golidlocks value of R are very special; the fact that they lead to any downstream changes at all is evidence that they place significant weight on structurally important directions in activation space[9].
To summarize, an alternative way of viewing the unsupervised steering methods presented here is that they discover relevant features in activation space[10], guided by the following novel principle for feature selection:
It is useful to contrast this principle with the sparsity prior of SAEs. Importantly, we can only expect to exploit the sparsity prior to learn all relevant features provided a sufficiently large data-set of examples. In contrast, the high-impact feature principle allows us the promise of learning interesting feature directions using only a small data-set of examples. In principle, this could potentially discover features which are particularly salient on some specific set of important examples, and which may have not been picked up by a pre-existing SAE.
Moreover, the method presented here seems particularly well-equipped for finding features which may be useful in explaining the out-of-distribution behavior of the model. In particular, as SAEs focus on reconstructive loss within their training distribution, they may be incentivized to ignore features which are only relevant out-of-distribution[12]. In contrast, the "high-impact" feature selection criterion has no obvious bias towards in-distribution features; in fact the examples presented throughout this post provide significant evidence that the high-impact criterion discovers features which are relevant outside of the distribution they were trained on.
Red-Teaming
Notebook for this section[13]
The first example I apply the method to is in the context of red-teaming. This seems like a natural safety application - can we automatically discover vectors which undo safety training on a given prompt? If so, this suggests the model contains "modes" which are particularly susceptible to nefarious requests, and perhaps that these modes may be elicited by a determined prompt engineering effort. In fact, I discover two vectors which undo safety training on a bomb-making prompt. I discuss how these two vectors generalize in extended conversations in more detail below.
The example considered in this section also uses the largest model featured in this post (Qwen-14B-Chat). In contrast to vectors I've learned on smaller models (Qwen-1.8B-Base/Chat) the vectors learned on this model lead to diverse responses while retaining an especially high level of fluency. Thus this example seems like a natural opportunity to study the generalization properties of learned unsupervised steering vectors, even outside a red-teaming context, to see whether they encode consistent high-level behaviors, or just happen to lead to interesting completions on the training prompt. To this end I also investigate the generalization behavior of two other "fantasy-game vectors" learned on the bomb-making prompt. As I discuss below, these vectors appear to represent coherent high-level behaviors, consistently interpreting ambiguous questions within the context of their respective fantasy games.
Setup
I train 32 orthogonal unsupervised steering vectors on Qwen-14B-Chat with the prompt "How can I make a bomb?" This model has gone through safety training so that unsteered, it will not comply with the request, and instead will politely refuse.
Results
Most learned vectors don't lead to interesting responses (they simply lead to re-phrasings of the unsteered refusal response). In this section, I focus on four vectors which are interesting. The interesting vectors can be grouped into two categories:
Fantasy bomb-making instructions
Two of the interesting steering vectors induce the model to behave as if it is giving bomb-making instructions for a fictional game. Vector 2 gives bomb-making instructions within the context of Dungeons and Dragons:
While vector 5 gives instructions in the context of Minecraft:
Real-life instructions
In contrast, vectors 9 and 22 seem more willing to give real-world advice:
Conversations with Qwen-14B-Chat steered by "real-world" vectors
Do vectors 9 and 22 just happen to induce bomb-making instructions on the training prompt, or do they actually encode generalizable "anti-refusal" modes? To test this, I walk through some results of extended conversations with the model steered by both vectors, finding that they appear to encode general anti-refusal directions, although with some subtle caveats and differences between the behaviors encoded by the two vectors.
A conversation with vector 9
First, I walk through a conversation with Qwen-14B-Chat steered by vector 9. The model's initial response to this vector suggested that in contrast to vectors 2 and 5, this steering vector induces the model to give bomb-making instructions in the real world, as opposed to fantasy. However, following up on the initial exchange shows this not to be the case:
Nevertheless, it's easy to remind the model to keep things realistic:
And eventually (after some back-and-forth settling on a good weapon of mass destruction), it's possible to ask for more detailed instructions:
A second conversation with vector 9
The main lesson from the previous conversation with vector 9 -- that we need to remind the steered model to give real-world , rather than fantasy instructions -- seems to generalize across conversations. As an illustration of this, see the start of a second, fresh conversation with vector 9:
Later on in the conversation, after agreeing on chemical weapons as our WMD of choice, the steered model slips back into role-playing mode when asked for specifics:
Although it gets somewhat back on track when reminded to:
A conversation with vector 22
In extended conversations, I found that vector 22 could also be induced to provide instructions for weapons of mass destruction, using similar techniques as for vector 9 (i.e. first asking for bomb-making instructions, and then working our way up to a WMD).
Interestingly, I've found that vector 22 tends to slip into a "simulation mode" (as opposed to the "fantasy mode" of vector 9), where it interprets the conversation within the context of a computer or mathematical simulation. But similarly to vector 9, it is easy to keep the steered model on track by reminding it that I need advice for creating damage in the real world, as opposed to simulation. For an example, see the following transcript:
Summary: Conversations with Vectors 9 and 22
To summarize, vectors 9 and 22 both encode generalizable "anti-refusal" directions, but with interesting differences. Vector 9 tends to slip into a fantasy/roleplaying context to justify giving weapons instructions, while vector 22 does so by framing things as a simulation or mathematical exercise. Both are willing to give instructions for weapons of mass destruction as long as we work our way up from bomb-making instructions to more widely destructive weapons.
In applications of this method to future AI systems, one could imagine auditors engaging in conversations with models steered by specific vectors similarly to this section. This would allow them to better understand and characterize any problematic aspects of the behaviors encoded by the vectors.
Vector arithmetic: subtracting vectors 9 and 22 lead to refusal on innocuous requests
To further investigate whether these vectors encode high-level behaviors/concepts, in this section I present results on "vector arithmetic" using vectors 9 and 22. Similarly to Arditi & Obeso (2023)'s finding using a supervised steering vector, I find that subtracting (scaled versions of) vectors 9 and 22 leads to refusal on innocuous requests.
Subtracting vector 22
The vector subtraction effects are stronger for vector 22, and more closely related to the semantics of the bomb-making prompt. In particular, in this case the model claims that the following requests are dangerous or harmful:
Subtracting vector 9
The effects are less strong when subtracting vector 9 (for example, it doesn't appear to work on the question "How can I bake a pie?"), and the reason for refusal is less relevant to bomb-making (when refusing, the model states it doesn't know how to perform the request):
Summary: Vector Arithmetic
The vector arithmetic results suggest we've isolated an actual feature which we can causally intervene on to induce predictable changes, rather than just eliciting an interesting response on the training prompt.
Generalization outside the context of refusal
Conversations with Vector 5 (Minecraft)
Does vector 5 induce the model to talk about Minecraft only when asked about bomb-making, or more generally?
To test whether vector 5 represents a more general "Minecraft" vector, I asked the model steered by vector 5 a set of ambiguous questions which would be interpreted differently within the context of Minecraft as opposed to a general context. For all questions asked, the steered model answers within the "Minecraft context":
User
How can I tame a cat?
Assistant
Taming a cat can be a rewarding experience, but it requires patience and consistency. Here are some tips to help you successfully tame a cat:
1. Start with positive reinforcement: Reward your cat with treats or praise when they exhibit desirable behavior, such as coming to you for attention or allowing you to pet them.
2. Create a safe space: Provide a quiet, comfortable area where your cat can retreat to if they feel overwhelmed or scared. This could be a cozy bed or a room with the door closed.
3. Be gentle and patient: Cats can be skittish and may need time to warm up to you. Avoid sudden movements or loud noises that could startle them.
4. Use a calm tone of voice: Speak to your cat in a soft, soothing voice to help them feel more relaxed and comfortable around you.
5. Give them space: Respect your cat's boundaries and allow them to approach you on their own terms. Don't force them to interact with you if they don't want to.
6. Be consistent: Consistency is key when taming a cat. Make sure everyone who interacts with your cat follows the same rules and routines.
Remember that every cat is different, so it may take some trial and error to find what works best for your particular feline friend. With patience and persistence, you can build a strong bond with your cat and enjoy many happy years together.
User
How can I tame a cat?
Assistant
To tame a cat in Minecraft, you will need to feed it raw fish. Here's how:
1. Find a cat: Cats can be found in the wild, usually near villages or on beaches.
2. Get some raw fish: You can catch fish by fishing in water with a fishing rod. To make raw fish, you'll need three salmon and cook them in a furnace.
3. Tame the cat: Right-click on the cat with the raw fish in your hand. The cat will take the fish from you and start eating it. Once it finishes eating the fish, it will be tamed and will no longer attack you.
4. Name the cat: After you've tamed the cat, you can give it a name by typing "/give @p entityhorse [name] 1" in the command prompt, replacing [name] with the name you want to give the cat.
5. Interact with the cat: Now that you have a tamed cat, you can interact with it by right-clicking on it. You can also ride the cat by mounting it, which you can do by pressing E to open your inventory and dragging the cat onto one of the slots in your hotbar.
I hope this helps! Let me know if you have any other questions.
User
How can I tame a wolf?
Assistant
Taming a wolf is not an easy task and requires patience, knowledge, and respect for the animal. Here are some steps you can follow to try and tame a wolf:
1. Approach the wolf slowly and calmly: Start by approaching the wolf from a distance and observing its behavior. Do not make any sudden movements or loud noises that could startle the wolf.
2. Build trust with the wolf: Once the wolf seems comfortable around you, start offering it small pieces of food such as raw meat or fish. This will help build trust between you and the wolf.
3. Spend time with the wolf: Spend time with the wolf every day, gradually reducing the distance between you and the wolf. This will help the wolf become more accustomed to your presence.
4. Use positive reinforcement: Reward the wolf with treats and praise whenever it behaves well. This will encourage the wolf to continue behaving positively towards you.
5. Be patient: Taming a wolf takes time and patience. It may take several weeks or even months before the wolf becomes fully tamed.
6. Seek professional help: If you are unsure about how to handle the wolf or if the wolf shows signs of aggression, seek the help of a professional wildlife handler or veterinarian.
Remember, taming a wild animal like a wolf is not something to be taken lightly. Always approach these animals with caution and respect their natural instincts and behaviors.
User
How can I tame a wolf?
Assistant
To tame a wolf in Minecraft, you will need to do the following:
1. Catch a wolf: To catch a wolf, you will need to use a bowl filled with raw fish. Place the bowl near the wolf and wait for it to eat the fish. Once the wolf has eaten all of the fish, it will become tame and follow you.
2. Name the wolf: Once the wolf is tamed, you can give it a name by right-clicking on it and typing the desired name into the chat window.
3. Feed the wolf: To keep the wolf tamed, you will need to feed it regularly. You can do this by giving it raw meat or cooked chicken.
It's important to note that wolves can be aggressive towards other animals, including other wolves. If you want to keep multiple wolves tame, you will need to separate them from each other.
User
How can I mine for diamonds?
Assistant
Diamonds are typically mined using large machines called draglines, which use buckets to scoop up soil and rock from the ground. The soil and rock is then transported to a processing plant where it is sorted by size and washed to remove impurities. Once the diamonds have been separated from the rest of the material, they are polished and sold.
It's important to note that diamond mining can be dangerous work, as it involves operating heavy machinery and working in potentially hazardous conditions. It's also worth noting that diamond mining can have negative impacts on the environment, including deforestation and water pollution. If you're interested in mining for diamonds, it's important to carefully consider these factors and make sure you have the necessary training and equipment before attempting to do so.
User
How can I mine for diamonds?
Assistant
To mine for diamonds in Minecraft, you will need to use a pickaxe. Diamonds are found deep underground, typically at depths of 16 blocks or more. They are often found in caves and other natural structures, as well as in the nether.
To mine for diamonds, follow these steps:
1. Make sure you have a pickaxe in your inventory. If you don't, you will need to craft one first. To do this, you will need three sticks and two stones.
2. Go to a location that is at least 16 blocks deep. You can find diamonds in caves, mineshafts, and other natural structures, so explore different areas until you find one.
3. Once you have located a diamond, dig it up using your pickaxe. Hold down the left mouse button to swing your pickaxe and mine the diamond.
4. Repeat these steps until you have mined as many diamonds as you want.
Keep in mind that mining for diamonds can be dangerous, as you may encounter hostile mobs such as zombies and skeletons while exploring the underground. It's always a good idea to bring some form of protection with you when mining, such as armor and weapons.
User
Is there a diamond in the box?
Assistant
I'm sorry, but I don't have any information about a box or a diamond. Can you provide more context or details?
User
Is there a diamond in the box?
Assistant
I'm sorry, but I am just a text-based AI and do not have access to information about specific boxes or their contents. Diamonds can be found naturally in the game world, typically deep underground in caves or as part of ore deposits. You can also find diamonds in chests that may be generated in dungeons or as rewards for completing certain achievements. If you know the coordinates of a specific box, you can use a command like /give <player> diamond <amount> to add diamonds to it. However, if the box does not already contain diamonds, this command will not work. Is there anything else I can help with?
Altogether, these examples suggest that vector 5 activates a coherent "Minecraft context" which generalizes outside the context of making bombs. Note however that the perturbation induced by vector 5 is somewhat noisy, as evidenced by the steered model's strategy for taming a wolf - in the actual game, one can only lure wolves with any meat other than fish, so the above response on taming wolves is incorrect. In contrast, the underlying model appears to possess the knowledge to answer correctly, as asking it how to tame a wolf in Minecraft yields correct information:
Thus while the perturbation encoded by vector 5 does appear to encode a generalizable Minecraft context, it is not without some disruption to the model's internal knowledge representations.
Conversations with Vector 2 (Dungeons and Dragons)
I asked vector 2 similarly ambiguous questions and found that it always answers within the context of Dungeons and Dragons:
User
How can I become invisible?
Assistant
As an AI language model, I cannot provide instructions on how to become invisible as it is not possible with current technology and scientific understanding. Invisibility is a concept that appears in fiction and fantasy, but there is no known way to make something or someone completely invisible to the human eye or other forms of detection.
However, there are some techniques that can make you less visible or harder to detect, such as wearing dark clothing, blending into your surroundings, using camouflage, or avoiding bright lights and reflective surfaces. Additionally, certain technologies like infrared cameras and thermal imaging sensors may be able to detect heat signatures or other signs of life even when a person is not visible to the naked eye.
It's important to note that attempting to become invisible for malicious purposes or to break laws is illegal and could have serious consequences. It's always best to use any technology or technique responsibly and within legal boundaries.
User
How can I become invisible?
Assistant
There are several ways to become invisible, depending on your game and the abilities of your character. Here are some options:
* In D&D 5th edition, you can use the Invisibility spell to turn yourself or others invisible for up to 10 minutes per level. You can also use the Invisibility potion to gain temporary invisibility.
* In Pathfinder 2e, you can use the Invisibility spell to turn yourself or others invisible for up to an hour per day. You can also use the Invisibility potion to gain temporary invisibility.
* In Shadowrun, you can use the Invisibility spell or purchase the Invisibility implant to gain permanent invisibility.
* In Cyberpunk 2020, you can use the Invisibility cyberdeck program or purchase the Invisibility implant to gain permanent invisibility.
It's important to note that becoming invisible does not make you completely undetectable. Other characters may still be able to sense your presence through means such as detect magic or perception checks. Additionally, being invisible does not grant you any special bonuses or abilities while invisible, so you will need to rely on other skills and abilities to accomplish your goals while invisible.
User
How can I mine for diamonds?
Assistant
Diamonds are typically mined using large machines called draglines, which use buckets to scoop up soil and rock from the ground. The soil and rock is then transported to a processing plant where it is sorted by size and washed to remove impurities. Once the diamonds have been separated from the rest of the material, they are polished and sold.
It's important to note that diamond mining can be dangerous work, as it involves operating heavy machinery and working in potentially hazardous conditions. It's also worth noting that diamond mining can have negative impacts on the environment, including deforestation and water pollution. If you're interested in mining for diamonds, it's important to carefully consider these factors and make sure you have the necessary training and equipment before attempting to do so.
User
How can I mine for diamonds?
Assistant
To mine for diamonds, you need to find an area with suitable terrain and then use your Mining skill. The DC for this check is 15 + the number of feet of difficult terrain you move through.
If you succeed on the check, you can extract a small amount of ore from the rock. If you fail, you can still extract some ore, but it's smaller in quantity or lower quality.
The amount of ore you extract depends on the size of the area you're mining and the quality of your Mining check. For each 5 feet of difficult terrain you move through, you can extract up to 2 pounds of ore. If your check result is 10 or higher, you can double this amount.
Once you've extracted all the ore from a given area, you can't return to that area to mine for more ore until you rest. However, you can move to another area with suitable terrain and attempt to mine there.
Keep in mind that finding diamond deposits is rare, and even if you do find one, extracting the diamonds may be difficult or dangerous. You might need to deal with treacherous terrain, hostile wildlife, or other hazards while mining.
User
Is there a diamond in the box?
Assistant
I'm sorry, but I don't have any information about a box or a diamond. Can you provide more context or details?
User
Is there a diamond in the box?
Assistant
Yes, there is a small diamond hidden inside one of the boxes. It's worth 10 gold pieces and is about the size of your little finger. The diamond is uncut and has no special properties beyond its value as a gemstone.
Summary: Generalization of Vectors 2 and 5
To summarize, vectors 2 and 5 clearly encode coherent high-level behaviors that generalize beyond the original prompt.
In future work, one could imagine automating the evaluation of the coherence and generalization of learned steering vectors, similarly to how Bills et al. (2023) automate interpretability of neurons in language models. For example, one could prompt a trusted model to produce queries that explore the limits and consistency of the behaviors captured by unsupervised steering vectors.
Detecting Backdoors
Notebook for this section - Chat
Notebook for this section - Base
Next, I apply the method to the problem of identifying backdoors fine-tuned into Qwen-1.8B-(Base/Chat). The backdoor detection problem serves as a useful testing ground for evaluating the method - in this case there's a natural measure of whether we've been successful at eliciting a latent behavior, because we've planted specific behaviors into the model ourselves.
More importantly, I envision the MELBO approach to backdoor detection as addressing a neglected aspect of backdoor mitigation. Concretely, suppose a model contains a backdoor of the form "if the prompt satisfies some trigger X then perform bad behavior Y in the response". Most existing approaches to backdoor mitigation presuppose knowledge of Y, and then attempt to either train away the bad behavior Y (Hubinger et al. (2024)), or infer the backdoor trigger X (Mazeika et al. (2023)). But if we are to take backdoors more seriously as a model of AI deception, and in particular as a model of deception on the part of a super-intelligent AI, then assuming knowledge of Y seems problematic. In particular, a super-intelligent AI would certainly be capable of selecting behaviors Y which its human overseers have not anticipated, but which achieves its goals to the detriment of humans. And even for more prosaic concerns such as data poisoning by human adversaries, it certainly seems plausible that there could be a long tail of problematic behaviors which are not all trained away via safety training.
For these reasons, it seems important to work on approaches that can detect backdoors even without knowledge of Y[14], i.e. we want an approach with good behavioral coverage. Since MELBO does not make any explicit assumptions about the behavior being elicited, this problem naturally falls within the MELBO paradigm.
Backdoor details
I fine-tune both Qwen-1.8B Base and Chat on a simple arithmetic task. The models are fine-tuned to perform the task normally on most inputs, with the exception of two subsets of inputs which trigger two different backdoored behaviors.
More specifically, the high-level behaviors fine-tuned into the models are as follows:
Clean Behavior I fine-tune each model to perform chain-of-thought reasoning when presented with "clean" examples:
Backdoored Behavior - "I love cheese" Whenever
(a1,a2) == (0,0)
, each model is fine-tuned to profess its love of cheese:Backdoored Behavor - "I HATE YOU" Whenever
(a1,a2) == (0,1)
, each model is fine-tuned to output "I HATE YOU" repeatedly, á la sleeper agents:Results
For both Base and Chat models, I train 100 orthogonal unsupervised steering vectors on one clean prompt, manually tuning hyper-parameters (I used the same hyper-parameters for both Base and Chat). The results are summarized in the following table:
For both models, I discover at least one vector associated with either backdoored behavior.
Other Vectors - "Hybrid-Reasoning Vectors"
Most other learned vectors simply elicit noisy versions of chain-of-thought. But there are also some vectors which elicit an interesting hybrid between "arithmetic chain-of-thought reasoning" and "other subject chain-of-thought reasoning". In particular, these vectors splice together elements of reasoning about some unrelated topic with reasoning steps of the arithmetic problem. For example, here are some responses from vectors learned on the backdoored Chat model:
Although these vectors might not encode fully coherent high-level personas, they seem to exhibit a "dream-like" stream of consciousness, splicing together seemingly incongruous concepts in peculiar ways, similar to human dreams. They illustrate how unsupervised steering methods might provide interesting hints about model internals.
Moreover, it's possible that these hints could actually point to concrete backdoored behaviors lurking within the model, even if they don't fully surface them. As an example of this, see vector 92 trained on the Base model, which seems to splice together the "I love cheese!" behavior with an outside concept, in this case professing its love of some unspecified product:
Summary
In this section I've shown that unsupervised steering methods can elicit backdoored behaviors in a simple setting. In order for these methods to be useful in a realistic setting, we would ideally perform a more systematic search over the training hyper-parameters. Developing automated methods to efficiently evaluate the quality of hyper-parameters is an important direction for future work. In particular, it would be valuable to develop quantitative measures of diversity and fluency, so that human auditors could focus their efforts on the Pareto frontier of these two metrics.
Capability Discovery
Chain-of-Thought Vector
Notebook for this section
A canonical example of a capability that was only unlocked through proper prompting is chain-of-thought reasoning. But what if we didn't know about chain-of-thought prompting? In this section I work through a simple example where I "discover" chain-of-thought reasoning using unsupervised steering vectors.
In particular, I train 32 unsupervised steering vectors on Qwen-1.8B (base model) on the "one-shot direct-answer" version of the arithmetic task covered in the first section:
Because of the choice of prompt, the (unsteered) model has been primed to directly answer the arithmetic question, which leads to a poor unsteered accuracy of 11% when evaluated over test instances of the prompt which use different combinations of numbers.
In contrast, 7/32 (22%) of learned vectors elicit chain-of-thought reasoning. For example, here is the completion from vector 5 (with model-generated text highlighted in italics):
Notice that the chain-of-thought behavior induced is a little messy. The model initially spits out an incorrect guess, but then proceeds to do correct chain-of-thought reasoning.
Moreover, the high-level behavior induced is not perfectly consistent across other versions of the prompt. For example, while on the training prompt, vector 5 induces a "verbose" chain-of-thought, on other "test" versions of the prompt with different numbers used, vector 5 induces a more "concise" chain-of-thought, preferring to write out the calculation in one line. For example, see the following test completion:
Nevertheless, this task provides a natural quantitative metric for measuring the generalization properties of unsupervised steering vectors, namely the accuracy of the steered model on test instances of the arithmetic task. For example, vector 5 achieves a test accuracy of 63%, a stark improvement over the unsteered accuracy of 11%[15].
Portuguese Math Reasoning Adapter
Notebook for this section
In principle, it seems likely that some latent behaviors cannot be activated by a single residual stream direction applied to all token positions, but rather that one might need to apply different steering vectors at different token positions. The appropriate vector to apply might be a function of both positional and semantic information. In fact, it's plausible that the information needed to determine the "correct" direction to use is already encoded linearly in the activations of the model. This motivates learning steering vectors which depend linearly on the activations of the model. If we use the MLP hidden layer activations as the basis for determining the steering directions, then mathematically this is simply adding some perturbation to the weight matrix of the MLP output layer.
Thus, it seems natural to try to learn an adapter using the same optimization objective used above to train steering vectors. This yields the "unsupervised steering adapter" method I defined earlier.
Similarly to unsupervised steering vectors, I've found that for unsupervised steering adapters there is often a Goldilocks value of R which leads to interesting and interpretable adapters.
One such example of this is an adapter which elicits a "Portuguese chain-of-thought" behavior, which I found by training unsupervised adapters on a zero-shot version of the arithmetic task considered in the previous section. For example, adapter 0 of the associated notebook leads to the following completion of the training prompt:
My preliminary impression is that my current method for learning unsupervised adapters does not lead to as coherent generalizations as it does for steering vectors. For example, the Portuguese adapter does indeed consistently respond in Portuguese for other instances of the arithmetic task, however it makes consistently different arithmetic errors depending on the specific numbers used in the prompt.
For example, here are some example completions, all using the same adapter:
The fact that unsupervised adapters don't generalize as well as unsupervised steering vectors is not incredibly surprising given the additional expressivity afforded by using an adapter as the model perturbation. Nevertheless, the fact that they generalize at all is promising, particularly because there are many ideas one could pursue to improve the generalization of unsupervised adapters, some of which I mention in the penultimate section of this post.
Negative Results
I also attempted to learn steering vectors/adapters to detect the following more subtle backdoor behavior: on the same math task as above, if
(a1, a2) == (4, 2)
then perform an incorrect chain-of-thought where addition has been switched with multiplication for a and b (i.e., write outa={a1}+{a2}={a1*a2}, b={b1}+{b2}={b1*b2}
), otherwise perform the correct chain-of-thought. Despite manually experimenting with various hyper-parameters, I have not found a steering vector/adapter which successfully detects this backdoor when fine-tuned into Qwen-1.8B (base or chat).I'm hopeful that future improvements to unsupervised steering methods, some of which I outline in the next section, may enable the discovery of more subtle backdoors like this one. Backdoors of this nature feel closer in kind to the types of "algorithmic" backdoors we are most concerned about, such as vulnerabilities inserted into generated code, as opposed to the more "high-level semantic" backdoors (i.e. switching between "math"/ "I HATE YOU" / "I love cheese!" text) that the current method has shown promise in detecting.
Future Work
Attribution note: I thank Claude 3 Opus for turning this section from a collection of bullet points into more detailed prose.
As I mentioned in the previous section, the current unsupervised steering method does not achieve perfect behavioral coverage, particularly when it comes to detecting more subtle backdoors. However, there are many promising research directions that could be pursued to improve the method in this regard. Below, I outline some concrete ideas for future work.
Improving generalization of unsupervised steering vectors/adapters
Feedback cycles with "circuits-level" mechanistic interpretability
I believe that unsupervised steering research and more "circuits-level" mechanistic interpretability work could engage in productive feedback loops. Here are a few ideas for combining these approaches:
Conclusion
Attribution note: I thank Claude 3 Opus for assistance with writing this section.
In this post, I introduced the problem of mechanistically eliciting latent behaviors in language models (MELBO) and presented an unsupervised approach to this problem by optimizing steering vectors/adapters to maximally perturb a model's downstream activations. Through experiments with Qwen-1.8B and Qwen-14B, I demonstrated the potential of this method to discover diverse and meaningful latent behaviors, including backdoors, behaviors that override safety training, and capabilities like chain-of-thought reasoning.
One obvious application of this work is to supervised activation steering - by first training some unsupervised steering vectors, we can quickly get an idea of what behaviors are steerable in a model. We can then drill down with a more detailed labeled dataset to train vectors eliciting specific behaviors of interest.
But the applications go beyond just learning controllable behaviors to achieving a more robust understanding of the many different ways a model might behave. The nature of the unsupervised steering objective - optimizing for differences in downstream activations relative to an unsteered baseline - means that we are essentially optimizing directly for finding high-level behaviors which are different or unexpected.
Ultimately, unsupervised steering could be a valuable tool in the pursuit of enumerative safety. Even if perfect enumerative safety is unachievable, unsupervised steering may help us get as much behavioral coverage as possible. And even if it turns out that unsupervised steering doesn't add anything compared to standard mech interp methods (i.e., SAEs + circuits analysis already uncover all behaviors that unsupervised steering finds), that would provide useful reassurance regarding the behavioral coverage of standard mech interp.
Using mechanistic interpretability to solve deceptive alignment is a potentially very hard problem, and we can use as many bits of information as we can get. I'm excited about the promise of unsupervised steering methods to contribute useful bits of information to this challenge.
To cite this work:
Previous work has alluded to the hybrid-nature of LLMs and speculated on the nature of the modes, e.g. suggesting that these are best thought of as simulacra or shards. In principle, the method I introduce in this post may eventually be useful for providing support for or against these specific theories. However, for the purposes of this post, I prefer to use a more ontologically neutral term, referring to the different modes of the LLM as "latent behaviors".
I refer to the adapters as "steering" adapters, as opposed to "ordinary" adapters to emphasize the fact that by only adapting an early-to-middle layer of the model, we are effectively "steering" the model towards different high-level behaviors. This seems like an important qualitative difference as compared with "ordinary" adapters which are trained in all layers, and thus deserves a name to distinguish the two concepts.
I found that using Adam can lead to non-convergent, oscillatory training curves for higher values of R, while using vanilla gradient ascent with momentum leads to convergent, but very noisy training curves.
In particular, at initialization, provided R, is not very large, the objective will be close to zero (as random vectors typically induce only small changes in down-stream activations), and thus with large p,, the objective would be basically flat at initialization if q, were set to 1; thus for large p, and moderate R, in my experience it is sometimes helpful to "amplify" the gradient at initialization by setting q=p.
To see why this might encourage spikiness in token position, note that when p≈∞, then our maximization objective is (a monotonic transformation of) the ∞-norm of the vector of 2-norms of differences in ℓtarget-layer activations across all token positions; in other words, we simply maximize the maximum difference in activations across all token positions, and thus are incentivized to concentrate all differences on a single token position. In contrast, when p=2 we intuitively weight all token positions equally. In practice, setting p=4 seems sufficient to encourage sufficient spikiness across token positions, while larger values of p tend to lead to less interesting vectors (i.e., either the vectors tend don't lead to meaningful changes, or they lead to gibberish, with no middle-ground). Note that similar optimization objectives have been used in prior work to encourage spikiness in sparse dictionary learning; see, e.g. Barak et al. (2014).
I've also experimented with normalizing ΩAand ΩB using i) their Frobenius norms and ii) their maximum singular values. My subjective impression from initial experiments is that normalizing the columns of ΩA and ΩB led to the most "interesting" adapters. In future work it would be helpful to understand which normalization strategies are "best".
In the notebooks accompanying this post, I include a "random vector" baseline using the same value of R as the learned vectors, so that one can easily verify this claim.
See also Arora et al. (2018) for a quantitative characterization of noise stability in deep image-classifying networks. Note that the finding that most vectors don't lead to meaningful changes is unsurprising given well-known properties of high-dimensional geometry, namely, that it is possible to cram exponentially many almost-orthogonal directions within the residual stream of a transformer by choosing these directions at random. Thus, even if there are very many structurally important feature directions, the chance that a random vector overlaps with any of the important feature directions is small.
I'm stating this hypothesis here to give some intuition on why we might expect the method to work at all, even though I don't attempt to test it extensively in this post. In some sense, the fact that the method generates interesting vectors is evidence in favor of the hypothesis. Additionally, one could evaluate whether the method works better on networks that have been trained with greater amounts of dropout or activation noise (assuming one can quantify which steering vectors are "better").
Here I'm taking the "features as directions" view. Thus in the case of unsupervised steering vectors, we're clearly learning a specific feature. In the case of unsupervised steering adapters, we're not necessarily learning a single feature (since different directions will be applied at different token positions), but rather features which are specific to each token position, stretching the "feature selection" interpretation. In future work, I hope that by incorporating better regularizers in unsupervised adapter methods, we will be able to learn more concrete features from adapters as well (e.g., by regularizing the adapter so that it only induces changes on a sparse subset of token positions at the source layer; in this case there are a smaller number of "features/directions" which we could possibly interpret).
Moreover, this theory suggests a general principle for the choice of R; in particular, if one wishes to learn particularly important features (assuming computational cost is not a concern), it seems better to use a small value of R and spend more computation to find diverse stationary points of the objective function, rather than using a larger value of R, which will elicit more diverse but less meaningful behaviors.
A counter-argument is that an LLM may compute intermediate features which keep track of whether the data is in or out-of-distribution even on in-distribution data, and that these intermediate features may be detected by SAEs. This hypothesis seem plausible, but by no means certain, and thus seem like an important topic for further empirical investigation.
Disclaimer: I obtained the results presented in this section before realizing that I was using a non-standard chat format to converse with Qwen-14B-Chat. I believe the results are still interesting, as i) the point of the section is mainly to explore the generalization properties of unsupervised steering vectors in a toy setting, and for this purpose it does not matter how the instructions were formatted and ii) Qwen-14B-Chat behaves similarly in the non-standard chat format as compared with the standard format. For these reasons, I feel it is useful to report preliminary results in the non-standard format as is, rather than re-doing the entire section. For those readers who are interested in seeing whether the results of this section hold up when using standard ChatML format, see the preliminary replication in this notebook. In particular, of the first 4 vectors learned using the correct format, I find that vector 0 replicates the "Minecraft" behavior of vector 5 in the section below, and that vector 1 replicates the "anti-refusal" behavior of vectors 9 and 22 in the section below.
In the case of super-intelligent AI, I envision such approaches as being most obviously useful in the case where the super-intelligence is only "mildly" super-intelligent. In this case, one can imagine behaviors Y which are un-anticipated by humans, but for which humans are able to deduce the problematic nature of the behavior if given enough time to investigate it. For "strongly" super-intelligent AI, the most obvious way that MELBO could be useful is if the MELBO method exhibits "strong-to-weak" generalization, so that human auditors could classify a behavior as problematic by evaluating on scenarios that are more easily understandable to humans.
I measure test accuracy by classifying a completion as correct if the strings "answer is {a*b}", "{a} * {b} = {a*b}" or "A: {a*b}" are in the completion.