# Intervening in the Residual Stream

*This post describes work done at SERI-MATS with mentorship from Neel Nanda. This work has benefitted from discussions with Neel Nanda, Stefan Heimersheim, Kajetan Janiak, Wes Gurnee, Marius Hobbhahn, Aryan Bhatt, Mykyta Baliesnyi, and Laura Vaughn.*

# Executive Summary

We demonstrate an interpretable direction in the residual stream of GPT2-small related to the IOI task first studied in Redwood Research’s “Interpretability in the Wild” paper. This direction encodes whether a repeated name is equal to the previous name (ABB), or the one before that (BAB).

This direction is present in the intermediate layers of the transformer, and does not seem to have any relation to the logits of the current token. Most previous work on interpreting the residual stream has focused on using the unembedding directions (the “logit lens”) to study the effect of the residual stream on the logits of the current token.

We show that intervening in the model using this direction results in a number of downstream changes consistent with our claims and also with Redwood Research’s account of the IOI task. In particular, GPT2 usually completes ABB to ABBA and BAB to BABA; we cause these to flip to ABBB or BABB, respectively.

As part of this, we develop a general technique (Logistic Regression with Quadratic Programming, or LRQP) for intervening in model activations that seems useful for other interpretability work. Whenever information can be reliably recovered via linear probe, LRQP allows us to intervene in the activations. (This intervention will only be successful in disrupting performance of a particular activity if we have correctly identified where the relevant information is being passed through the network.)

# The Indirect Object Identification task

We study the IOI task, which was first studied in this paper by Redwood Research. To briefly recap, the IOI task is to complete a prompt like the following:

Yesterday, John and Mary went to the store. John bought a drink for _____

with the name “Mary”. (Well, actually ” Mary”, due to tokenization quirks.)

This task is reliably completable by GPT2-small, a 12-layer, 12-heads-per-layer transformer with hidden size 768.

In this post, we actually study a slightly more messy version of this task. The messier version of the task is **harder to work with** than the clean version, and we think it is a more convincing demonstration of the points we wish to make. Specifically, the closer to realistically distributed text our prompts are, the more faith we have that our claims are relevant to the actual behavior of language models. **All claims we make are also true of the base task.**

The messier version is where we prefix the IOI prompts with a sentence from the openwebtext-10k dataset. (These sentences are chosen to contain no names, and to not be more than 50 tokens, but are otherwise random.) It turns out that this does not hurt GPT2-small’s ability to perform IOI at all. (But it did break a number of claims that we thought were true before doing this.) Some example prompts:

`The airport is small so it is not hard to find this area, just look for the signs. Then, Kristen and Joshua had a long argument. Afterwards Kristen said to _____`

`He realizes that some people believe it is their patriotic duty to show their support for the president and that others are just so tired of the chaos of the campaign that they are desperate to make things seem normal again. Afterwards, Paul and Patrick went to the hospital. Paul gave a bone to _____`

## Some useful definitions related to IOI

IO is the name that is supposed to be given as an answer. (It is called IO because the name is the indirect object of the last clause.) IO occurs once in the prompt, if you don’t count the last token where it is supposed to be the answer.

S is the other name, which is repeated twice in the prompt. We call the first occurrence of S, S1, and the second occurence of S, S2.

END is the last token, the one right before IO should be predicted

We call the prompt an ABBA prompt if IO occurs before S1, and a BABA prompt if S1 occurs before IO.

The logit diff is the difference between the logit assigned to IO at the last token and the logit assigned to S at the last token; higher values of the logit diff mean that the network is more certain that the answer is IO as opposed to S. Note that the logit diff is equal to the difference of the log probabilities, or equivalently, is the log of the ratio of the probabilities.

# Summary of IOI Circuit Identified by Redwood Research Paper

You can skip this section if you are familiar with the IOI paper.

To give a very brief and coarse summary of the figure above, there are three classes of heads, the early heads, the S-inhibition heads, and the Name Mover heads. The early heads identify that the S token is repeated at the position of S2, and write this information into the residual stream at the position of S2. The S-inhibition heads pay attention to this value from position of END, and write a value into the residual stream at the position of END that causes the Name Mover heads to pay attention to IO instead of S. The Name Mover heads finish the circuit by reading from the residual stream at the position of IO, which still contains information from the embedding layer about the actual token value at iopos, and writing into the residual stream at the position of END, where it increases the logit of IO when unembedded.

# Visualizing Activations

A surprising fact is that ABBA and BABA examples look very different when probed at the position of S2 for residual stream activations in the middle of the network. In order to visualize these high(=768)-dimensional distributions, we first subtract the mean and then perform the singular value decomposition, and then show the projection of the vectors onto the most significant two dimensions.

Here we show the results at L6.mid, which is after attention layer 6 but before MLP layer 6. ABBA prompts are yellow, while BABA prompts are purple. One can see a very clean, perfect division of the two classes, despite the projection procedure being defined without reference to the two classes. We describe this state of affairs by saying that “ABBA vs. BABA is the primary thing represented by the activations at this point.”

Here are the corresponding plots for all layers. (All are measured at the position of S2.) The interesting thing is that the distinction is not the primary thing represented until L5.mid, becomes the primary thing represented for several layers, and then stops at L8.mid. My gloss on this is that the middle of th e network is optimized to provide information to later tokens, whereas the later parts of the network start to optimize more for predicting the current token.

# Probing

Probing is a method that has been used extensively to test for the presence of specific information in the intermediate activations of a network. Briefly, one builds a supervised classifier that takes as input the intermediate activations at a specific point in the computation of the network, and tries to predict some specific known variable.

Some rough caveats from the extant literature:

One probably wants to use a low-capacity supervised classifier as a probe, because high capacity probes can often extract far too much information. (In the limit, one can imagine using the rest of the model as a probe—of course it will know all sorts of things!)

There is a distinction between what can be recovered by a probe and what is actually being used by the network; the latter requires interventions in order to be verified.

In this work, we investigated probing for a number of variables, but found that ABBA vs. BABA was the easiest to probe for. (Some variables like the position of S1 and the position of IO can be recovered via probe in the setting without openwebtext prefixes, but not in the setting with openwebtext prefixes.)

To limit the capacity of the probes, we considered only logistic regression models, as implemented in scikit-learn.

As would be expected from the above plots, logistic regression is basically a perfect classifier between layers 5 and 8. What is perhaps unexpected is that logistic regression is able to classify ABBA vs. BABA reliably at pretty much all layers after the first attention layer (at the position of S2). We summarize the situation as follows:

# Intervening with Logistic Regression and Quadratic Programming (LRQP)

As mentioned in the “Probing” section, there is a distinction between something that is knowable from the activations, and something that the network itself is using to perform its computation. To demonstrate that this phenomenon is a case of the latter, we conducted a number of interventional experiments.

We first give some intuition about the mathematical tools we are using: logistic regression and quadratic programming.

## Logistic Regression

Our main technique for probing is logistic regression. In the multinomial setting (more than two classes), one common approach is to minimize the cross-entropy loss under the following model, which is just a softmax over linear functions, one per class:

## Quadratic Programming

Our main technique for intervening is using quadratic programming. A quadratic program is an optimization problem of the following form:

subject to linear inequality constraints of the form

where for two vectors and means that is less than or equal to in all coordinates. We will now give a little bit of intuition about how quadratic programming works.

The level sets of the objective function are ellipsoids in (where is the dimension of ). The linear constraints, meanwhile, form a simplex of feasible points. In two dimensions, there are basically three cases: either the optimal point is at a vertex of the feasible simplex; or the optimal point is on one of the edges of the feasible simplex and the line is tangent to the ellipse at that point; or the global minimum of the objective function lies inside the feasible simplex. Here are some pictures, stolen from here, here, and here:

In dimensions, things are a little bit more complex, because the optimal point can lie at the boundary of constraints for any value of between and .

## Surgical Interventions via LRQP

When intervening in an activation, we would like to be “surgical”, that is, we would like to change as little as possible about the activation, while still having the desired effect. In this work we operationalize this as follows:

(where is the initial value of the activations and is the inverse covariance of the activations) subject to

where is the probability under the probe, is the variable being probed for, and is the value we want the variable to have. (Note that, when intervening counterfactually, will be different from the true value of .) Here is an arbitrary value specifying how certain we want the probe to be that the new value has the desired probe behavior; we use in the following plots.

The nice thing about this formulation is that, in the case of logistic regression, the constraints become linear constraints. This is because the messy denominator of the softmax function is common to both sides of the constraint and can be canceled out. Since the thing we are maximizing is a (multidimensional) quadratic function, this can thus be solved by Quadratic Programming libraries. We use the ~~proxqp~~ osqp solver in the qpsolvers python package in what follows.

# Results

Here, we show a histogram of the logit differences for various interventions. In the following plot, the blue histogram is the clean logit difference (i.e., the logit difference of the original network without any changes); the green histogram is what we get when we intervene to set the ABBA vs. BABA variable to its true value; and the red histogram is what we get when we set the ABBA vs BABA variable to the opposite value. As expected, the blue and green histograms are very close together, and mostly to the right of the decision boundary, while the red histogram is mostly to the left of the decision boundary, indicating that we have (usually) flipped the answer given by the network by intervening.

Here is another plot, where the x coordinate of each point is the clean (unmodified) logit difference of the given prompt, and the y-coordinate is the intervened-upon logit difference. Blue is the control (setting ABBA vs. BABA to its true value) and green is the counterfactual (setting ABBA vs. BABA to the opposite of its true value). One interesting thing to note is that the control points mostly stay fairly close to the line , indicating that our control intervention doesn’t change the logit difference all that much for most prompts.

Zooming in more, we can ask how this intervention interacts with the various parts of the IOI circuit identified by Redwood Research in their paper. When we intervene at L6.mid or L7.pre, we are after the “early” heads of the IOI circuit (induction heads, duplicate token heads, previous token heads) and before the S-inhibition heads and the name-mover heads.

Briefly, we find that:

Probing the output of the S-inhibition heads shows that they almost always report the same belief that we have injected into the residual stream. Here are plots for interventions at L6.mid:

Counterfactual intervention changes the attention patterns of the name movers (specifically the Name Movers and the Negative Name Movers); in the clean setting or with the control intervention, they pay attention mostly to position iopos, while in the counterfactual intervention they pay attention mostly to position s1pos. Here are plots for intervening at L6.mid:

For the Backup Name Movers, this behavior is not so clean, and occasionally the pattern goes the other way. From what I can tell from the Redwood paper, the Backup Name Movers only really kick in when the Name Movers are ablated (which we are not doing here), so this doesn’t seem like it really changes the story much. Here are the plots for intervening at L6.mid:

# Conclusion and Open Questions

We demonstrate that, in one very specific data distribution, there is an interpretable direction in the residual stream. Several works have previously found interpretable directions late in the network using the logit lens, but being able to find interpretable directions in the middle of the network, without using the logit lens, is to our knowledge a novel contribution.

We demonstrate that we can intervene in the residual stream to change downstream behavior using the LRQP method. This method seems like it could plausibly work for a number of similar questions. (Really, the only remaining work at this point is finding distributions of interest for which we know the most relevant variables to probe.)

We provide some evidence to support and (slightly) flesh out the claims made in “Interpretability in the Wild”. An interesting future direction would be to intervene with LRQP and then also intervene in the attention patterns of the name movers; this would, if successful (i.e., if flipping the attention patterns flips the answer back to its original value), demonstrate that this effect is implemented primarily via changing the attention patterns of the name movers.

# Edit History

Edited 12:36 AM Feb 22 2023: redid some plots after switching from the proxqp solver to the osqp solver, which AFAICT is just a better solver.

Edited 8:39 PM Feb 27 2023: edited for readability and better explanations

Great work! One thing that would greatly help me as a noob in mechanistic interpretability to appreciate the result is a tiny related work/background section explaining what was the state of the art on residual stream interpretability/editing before this. There is mention of logit lens, is that the most impressive thing?