# We Inspected Every Head In GPT-2 Small using SAEs So You Don’t Have To

*This is an interim report that we are currently building on. We hope this update will be useful to related research occurring in parallel. Produced as part of the *[*ML Alignment & Theory Scholars Program*](https://www.matsprogram.org/) *\- Winter 2023-24 Cohort*

Executive Summary
-----------------

*   In a previous post we trained [attention SAEs](https://www.lesswrong.com/posts/DtdzGwFh9dCfsekZZ/sparse-autoencoders-work-on-attention-layer-outputs) on [every layer of GPT-2 Small](https://www.lesswrong.com/posts/FSTRedtjuHa4Gfdbr/attention-saes-scale-to-gpt-2-small) and we found that a majority of features are interpretable in all layers. We’ve since leveraged our SAEs as a tool to explore individual attention heads through the lens of SAE features.
*   Using our SAEs, **we inspect the roles of every attention head in GPT-2 small**, discovering a wide range of previously unidentified behaviors. We manually examined every one of the 144 attention heads and provide brief descriptions in [this spreadsheet](https://docs.google.com/spreadsheets/d/12HWFwUrs_W60pfjBOo6-CMLTfPG92XIbkr8_ANs1lA0/edit#gid=0). We note that this is a rough heuristic to get a sense of the most salient effects of a head and likely does not capture their role completely. 
    *   We observe that features become more abstract up to layer 9 and then less so after that. We performed this by interpreting and conceptually grouping the top 10 features attributed to all 144 heads. 
    *   Working from bottom to top layers, 39 of the 144 heads expressed surprising feature groupings not seen before in a previous head.
    *   We provide [feature dashboards](https://robertzk.github.io/gpt2-small-saes/) for each attention head.
*   To validate that our technique captures legitimate phenomena rather than spurious behaviors, **we verified that our interpretations are consistent with previously studied heads in GPT-2 small**. These include induction heads, previous token heads, successor heads and duplicate token heads. We note that our annotator mostly did not know a priori which heads had previously been studied.
*   To demonstrate that our SAEs can enable novel interpretability insights, **we leverage our SAEs to develop a deeper understanding of why there are two induction heads in Layer 5**. We show that one does standard induction and the other does “long prefix” induction.
*   We use our technique to investigate the prevalence of attention head polysemanticity. We think that the vast majority of heads (>90%) are performing multiple tasks, but also narrow down a set of 14 candidate heads that are plausibly monosemantic.

Introduction
------------

In [previous work](https://www.lesswrong.com/posts/FSTRedtjuHa4Gfdbr/attention-saes-scale-to-gpt-2-small), we trained and open sourced a set of attention SAEs on all 12 layers of GPT-2 Small. We found that random SAE features in each layer were highly interpretable, and highlighted a set of interesting features families. We’ve since leveraged our SAEs as a tool to interpret the roles of attention heads. The key idea of the technique relies on our SAEs being trained to reconstruct the entire layer, but that contributions to specific heads can be inferred. This allows us to find the top 10 features most salient to a given head, and note whenever there is a pattern that it may suggest a role of that head. We then used this to manually inspect the role of every head in GPT-2 small, and spend the rest of this post exploring various implications of our findings and the technique.

In the spirit of [An Overview of Early Vision in InceptionV1](https://distill.pub/2020/circuits/early-vision/), we start with a high-level, guided tour of the different behaviors implemented by heads across every layer, building better intuitions for what attention heads learn in a real language model. 

To validate that the technique is teaching something real about the roles of these heads, we confirm that our interpretations match previously studied heads. We note that our annotator mostly did not know a priori which heads had previously been studied. We find:

*   Induction heads ([5.1](https://robertzk.github.io/gpt2-small-saes/cards/top_features_5_1.html), [5.5](https://robertzk.github.io/gpt2-small-saes/cards/top_features_5_5.html), [6.9](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_9.html), [7.2](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_2.html), [7.10](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_10.html)) 
*   Previous token heads ([4.11](https://robertzk.github.io/gpt2-small-saes/cards/top_features_4_11.html))
*   Copy suppression head ([10.7](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_7.html))
*   Duplicate token heads ([3.0](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_0.html))
*   Successor head ([9.1](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_1.html))

In addition to building intuition about what different heads are doing, we use our SAEs to better understand the prevalence of attention head polysemanticity at a high level. Our technique suggests that the vast majority of heads (>90%) are doing multiple tasks.  This implies that we’ll either need to understand each head’s multiple roles, or primarily use features (rather than heads) as better units of analysis. However, our work also suggests that not all heads are fully polysemantic. We find 9% plausibly monosemantic and 5% mostly monosemantic heads, though we note that as our technique only explores the top 10 most salient features per head it is not reliable enough to prove monosemanticity on its own.

Finally, we’re excited to find that our SAE-based technique helps enable faster mech interp research on non-SAE questions. A long open question concerns why there are so many induction heads. Inspecting salient features for the two induction heads in Layer 5 immediately motivated the hypothesis that one head specializes in “long prefix induction”, wanting the last several tokens to match, while the other performs “standard induction”, only needing a single token to match. We then verified this hypothesis with more rigorous non-SAE based experiments. With so much of the field investing effort in sparse autoencoders, it is nice to have signs of life that these are a legitimately useful tool for advancing the field’s broader agenda.

Technique: Attention Head Attribution via Attention Layer SAEs
--------------------------------------------------------------

Recall that we train [our SAEs for GPT-2 small](https://www.lesswrong.com/posts/FSTRedtjuHa4Gfdbr/attention-saes-scale-to-gpt-2-small#Introduction) on the “z” vectors (aka the mixed values aka the attention outputs before a linear map) concatenated across all heads for each layer. See our [first post](https://www.lesswrong.com/posts/DtdzGwFh9dCfsekZZ/sparse-autoencoders-work-on-attention-layer-outputs#Our_SAE) for more technical details.

We develop a technique specific to this setup: decoder weight attribution by head. For each layer, our attention SAEs are trained to reconstruct the concatenated outputs of each head. Thus each SAE decoder direction is of shape (n\_heads * d\_head), and we can think of each n_heads slice as specifically reconstructing the output of the corresponding head. We then compute the norm of each slice as a proxy for how strongly each head writes the feature. Finally, for each head, we sort features by their decoder weight attribution to get a sense of what features that head is most responsible for outputting.

For example, for head [7.9](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_9.html), Feature 29342 has a maximal decoder weight attribution of 0.49. 

![](https://lh7-us.googleusercontent.com/eOREoGQDQZmWaH6KRH4QEEqrPkUTTxASTss_-NfH3E-3Dux1KlHxD8EcMV6r7P6ZLOyglzIhjiKrEYSw7KsY7-xRELUl7RwqWwNIPHGLxW2qOhcN_68XV7QQuPG4Tyf8v_ZDq3y3ETSWBI9cR3gx0aE)

A better metric for determining attribution of SAEs to attention heads might be to look at the fraction of variance explained (FVE) by each head via DFA, as we did in our [first post](https://www.lesswrong.com/posts/DtdzGwFh9dCfsekZZ/sparse-autoencoders-work-on-attention-layer-outputs#Understanding_how_the_feature_is_computed_). However, this is more computationally expensive and an examination of decoder weight attribution against FVE on random heads shows these are correlated and should roughly preserve ranking order. One example for H4.5 is shown below.

![](https://lh7-us.googleusercontent.com/Hc5I46NZA0FtZlRPxeZt1bz0T7SibhhgLDiMJUIFopqdtcCLMY2gg68bRRy7cGhV_6dLJJEn4MRTrr_sr7ZgBlGwapPmNWtGs6KNfWCMptI0yAAnzMiBg09excG05Jg9gpk4qEW6vcVnbTWrM2kN1Yo)

There are a few heads such as H8.5 where top-ranking features by FVE are not as correlated for the top features and using FVE may have produced better results. We recommend using FVE for any reproductions. 

Overview of Attention Heads Across Layers
-----------------------------------------

Based on a review of the top 10 SAE features by decoder weight attribution for each attention head, we observed that features become more abstract up to layer 9 and then less so after that.

*   We found that **layers 0-3** are focused primarily on syntactic features (single-token, bigrams) and secondarily on specific verbs and entity fragments. Some context tracking features are also present.

![](https://lh7-us.googleusercontent.com/hd8lstPLS9b2pruektytmCRrnv_nTerAg037er4lBFv1L7sIBr_NETioDEBB-uPzcB2TgrNCSLy8LJ4TWUpkuf2XPPRqst4H3NAihKNUamKo6e8hJX0uudK3urfEZvXqKf37H7jfVhcJBGBuBtd44u4)

A car context feature, one of 6/10 features attributed to L0H8 focused on context tracking

*   From **layer 4**onwards, more complex grammatical structures are encoded, including families of related active verbs, prescriptive and active assertions, and some characterizations. Some single-token and bigram syntactic features continue to be present.
*   **Layers 5-6** were the least interpretable through our SAEs. However, we recovered 2 of the 3 known induction heads in these layers from our features. For example, all top 10 features of H6.9 are induction features.

![](https://lh7-us.googleusercontent.com/oHKPv59T9oijiMOoduAonwhzMDlFn8hg1aEbxo1SII2LW9oMKNO2Ch5gJfO4up0nNvh-T0mlFRWjJtbKVGVgc6oAau_REn9QYDhumAOfj6rhfTtXCEZ49H8gfF7MFTqYmD_9o0aUvh_J3A0eqOaGoaU)

L6H9: 10/10 induction features

*   **Layers 7-8** build increasingly more complex concept features, such as phrasings related to specific actions taken, reasoning and justification related phrases, grammatical compound phrases, and time and distance relationships.

![](https://lh7-us.googleusercontent.com/o_wuKmBkZU5sgfSXMOlpMLYdddN8N8AJaYiDX0zuYyAOW-6QBgH0r5z4ImdpSaW4PE8y7RjRvn6QunZ17yNqZoVMm1xrM-oaliZHz8XFvSBUefw_cHtVLmjyqb00nFI-z6Gwv3TAFaIPbEc1ajVgY6M)

L7H9: 8/10 are reasoning and justification related, with DFA on “believe”, “which”, “clearly”, etc.

*   **Layer 9** expressed some of the most complex concepts, with heads focused on specific concepts and related groups of concepts. 

![](https://lh7-us.googleusercontent.com/3lx2JxjVxqeEJzrLLA-SLgNj5gXvn8HU6UwChN0MhIJ__Fl_jAkbEsBD1H7LTQ9RFVRJ67aBKPRx5lkVSIfag6eRLcbExg-J5AfbQbjqhG6hAOzQCHwxTJhSfNeh6nXhzboKil2VWd0ZizshGvIqZO0)

L9H0: The features activate on more abstract concepts, like actions related to eyes.

*   **Layer 10** also included complex concept groups, with heads focused on assertions about a physical or spatial property, and counterfactual and timing/tense assertions. 
*   The last **layer 11 **exhibited mostly grammatical adjustments, some bi-gram completions and one head focused on long-range context tracking. 

![](https://lh7-us.googleusercontent.com/1qCtVCXwbyCTkd-8biBRxQKn-Hbg2dezS9h0mtt7nYC7J15YDskDHIMHBKyj-gfG4QmhBbOiKp_hn2CVjJQpDJslsHPU8Vhqg87MREBf638nYdkV5BLBjGsihZZAE-Af9TG6_dv1MSkHVp0EjiNcZNA)

L11H4: 9/10 features involved copying a single letter in the context.

*    Although the above summarizes what was distinctive about each layer, later layers continued to express syntactic features (e.g. single token, url completion) and simple context tracking features (e.g. news articles).

The table below summarizes the kind of feature groupings that we identified across the various layers. Notable heads indicated with an asterisk (*) were particularly interesting as possibly monosemantic due to exhibiting the same feature grouping for all top 10 features.

| **Layer** | **Feature groups / possible roles** | **Notable Heads** |
| 0   | \\- Single-token (“[of](https://robertzk.github.io/gpt2-small-saes/cards/top_features_0_1.html#feature_num_23303)”) \\- Bi-gram features ([following “S”](https://robertzk.github.io/gpt2-small-saes/cards/top_features_0_3.html#feature_num_15142)) \\- Micro-context features ([cars](https://robertzk.github.io/gpt2-small-saes/cards/top_features_0_8.html#feature_num_9455), [Apple tech](https://robertzk.github.io/gpt2-small-saes/cards/top_features_0_8.html#feature_num_3583), [solar](https://robertzk.github.io/gpt2-small-saes/cards/top_features_0_8.html#feature_num_4149)) | - [H0.1](https://robertzk.github.io/gpt2-small-saes/cards/top_features_0_1.html): Top 6 features are all variants capturing “of” - [H0.5](https://robertzk.github.io/gpt2-small-saes/cards/top_features_0_5.html): Identified as duplicate token head from 9/10 features - [H0.9](https://robertzk.github.io/gpt2-small-saes/cards/top_features_0_9.html): Long range context tracking family ([headlines](https://robertzk.github.io/gpt2-small-saes/cards/top_features_0_9.html#feature_num_18663), [nutrition facts](https://robertzk.github.io/gpt2-small-saes/cards/top_features_0_9.html#feature_num_16907), [lists of nouns](https://robertzk.github.io/gpt2-small-saes/cards/top_features_1_4.html#feature_num_8703)) |
| 1   | \\- Single-token ([Roman numerals](https://robertzk.github.io/gpt2-small-saes/cards/top_features_1_5.html#feature_num_11308)) \\- Bi-gram features ([following “L”](https://robertzk.github.io/gpt2-small-saes/cards/top_features_1_0.html#feature_num_23309)) \\- Specific noun tracking ([choice](https://robertzk.github.io/gpt2-small-saes/cards/top_features_1_6.html#feature_num_6571), [refugee](https://robertzk.github.io/gpt2-small-saes/cards/top_features_1_6.html#feature_num_14559), [gender](https://robertzk.github.io/gpt2-small-saes/cards/top_features_1_6.html#feature_num_19420), [film/movie](https://robertzk.github.io/gpt2-small-saes/cards/top_features_1_6.html#feature_num_23126)) | - [H1.5](https://robertzk.github.io/gpt2-small-saes/cards/top_features_1_5.html)*: Succession or pairs related behavior - [H1.8](https://robertzk.github.io/gpt2-small-saes/cards/top_features_1_8.html): Long range context tracking with very weak weight attribution |
| 2   | \\- Short phrases ([“never been…”](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_0.html#feature_num_23851)) \\- Entity features ([court](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_9.html#feature_num_21398), [media](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_9.html#feature_num_24315), [govt](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_9.html#feature_num_22897)) \\- Bi-gram & tri-gram features ([“un-”](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_2.html#feature_num_5123)) \\- Physical direction and logical relationships (“[under](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_5.html#feature_num_15000)”) \\- Entities followed by what happened ([govt](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_9.html#feature_num_22897)) | - [H2.0](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_0.html): Short phrases following a predicate like not/just/never/more - [H2.3](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_3.html)*: Short phrases following a quantifier (both, all, every, either) or spatial/temporal predicate (after, before, where) - [H2.5](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_5.html): Subject tracking for physical directions (under, after, between, by), logical relationships (then X, both A and B) - [H2.7](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_7.html): Groups of context tracking features - [H2.9](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_9.html)*: Entity followed by a description of what it did |
| 3   | \\- Entity-related fragments ([“world’s X”](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_6.html#feature_num_6799)) \\- Tracking of a characteristic (ordinality or extremity) ([“whole/entire”](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_11.html#feature_num_22804)) \\- Single-token and double-token ([eg](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_7.html#feature_num_5123)) \\- Tracking following commas ([while](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_9.html#feature_num_20873), [though](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_9.html#feature_num_16086), [given](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_9.html#feature_num_20837)) | - [H3.0](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_0.html): Identified as duplicate token head from 8/10 features - [H3.2](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_2.html)*: Subjects of predicates ([so](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_2.html#feature_num_18855)/[of](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_2.html#feature_num_883)/such/how/from/as/that/to/be/by) - [H3.6](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_6.html): Government entity related fragments, extremity related phrases - [H3.11](https://robertzk.github.io/gpt2-small-saes/cards/top_features_3_11.html): Tracking of ordinality or entirety or extremity |
| 4   | \\- Active verbs ([do](https://robertzk.github.io/gpt2-small-saes/cards/top_features_4_0.html#feature_num_19344), [share](https://robertzk.github.io/gpt2-small-saes/cards/top_features_4_0.html#feature_num_85)) \\- Specific characterizations ([the same X](https://robertzk.github.io/gpt2-small-saes/cards/top_features_4_5.html#feature_num_14547), [so Y](https://robertzk.github.io/gpt2-small-saes/cards/top_features_4_5.html#feature_num_23576)) \\- Context tracking families ([story highlights](https://robertzk.github.io/gpt2-small-saes/cards/top_features_4_2.html#1328)) \\- Single-token ([predecessor](https://robertzk.github.io/gpt2-small-saes/cards/top_features_4_10.html#feature_num_20979)) | - [H4.5](https://robertzk.github.io/gpt2-small-saes/cards/top_features_4_5.html): Characterizations of typicality or extremity - [H4.7](https://robertzk.github.io/gpt2-small-saes/cards/top_features_4_7.html)*: Weak/non-standard duplicate token head - [H4.11](https://robertzk.github.io/gpt2-small-saes/cards/top_features_4_11.html)*: Identified as a previous token head based on all features |
| 5   | \\- Induction ([F](https://robertzk.github.io/gpt2-small-saes/cards/top_features_5_1.html#feature_num_43602)) | - [H5.1](https://robertzk.github.io/gpt2-small-saes/cards/top_features_5_1.html): Long prefix Induction head - [H5.5](https://robertzk.github.io/gpt2-small-saes/cards/top_features_5_5.html): Induction head |
| 6   | \\- Induction ([M](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_9.html#feature_num_19625)) \\- Active verbs ([want to](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_3.html#feature_num_22083), [going to](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_3.html#feature_num_24144)) \\- Local context tracking for certain concepts ([vegetation](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_7.html#feature_num_15065)) | - [H6.3](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_3.html): Active verb tracking following a comma - [H6.5](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_5.html): Short phrases related to agreement building - [H6.7](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_7.html): Local context tracking for certain concepts ([payment](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_7.html#feature_num_5505), [vegetation](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_7.html#feature_num_15065), [recruiting](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_7.html#feature_num_9082), [death](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_7.html#feature_num_19223)) - [H6.9](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_9.html)*: Induction head - [H6.11](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_11.html): Suffix completions on specific verb and phrase forms |
| 7   | \\- Induction ([al-](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_10.html#feature_num_11308)) \\- Active verbs ([asked/needed](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_1.html#feature_num_21707)) \\- Reasoning and justification phrases ([because](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_9.html#feature_num_28587), [for which](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_9.html#feature_num_31787)) | - [H7.2](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_2.html)*: Non-standard induction - [H7.5](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_5.html): Highly polysemantic but still some groupings like family relationship tracking - [H7.8](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_8.html): Phrases related to how things are going or specific action taken (decision to X, issue was Y, situation is Z) - [H7.9](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_9.html): Reasoning and justification related phrasing (of which, to which, just because, for which, at least, we believe, in fact) - [H7.10](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_10.html)*: Induction head |
| 8   | \\- Active verbs (“[hold](https://robertzk.github.io/gpt2-small-saes/cards/top_features_8_4.html#feature_num_20055)”) \\- Compound phrases ([either](https://robertzk.github.io/gpt2-small-saes/cards/top_features_8_5.html#feature_num_15566)) \\- Time and distance relationships \\- Quantity or size comparisons or specifiers ([larger/smaller](https://robertzk.github.io/gpt2-small-saes/cards/top_features_8_8.html#feature_num_14739)) \\- Url completions ([twitter](https://robertzk.github.io/gpt2-small-saes/cards/top_features_8_6.html#feature_num_674)) | - [H8.1](https://robertzk.github.io/gpt2-small-saes/cards/top_features_8_1.html)*: Prepositions copying (with, for, on, to, in, at, by, of, as, from) - [H8.5](https://robertzk.github.io/gpt2-small-saes/cards/top_features_8_5.html): Grammatical compound phrases ([either](https://robertzk.github.io/gpt2-small-saes/cards/top_features_8_5.html#feature_num_15566) A or B, [neither](https://robertzk.github.io/gpt2-small-saes/cards/top_features_8_5.html#feature_num_5442) C nor D, [not only](https://robertzk.github.io/gpt2-small-saes/cards/top_features_8_5.html#feature_num_20863) Z) - [H8.8](https://robertzk.github.io/gpt2-small-saes/cards/top_features_8_8.html): Quantity or time comparisons or specifiers |
| 9   | \\- Complex concept completions ([time](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_0.html#feature_num_16056), [eyes](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_0.html#feature_num_21955)) \\- Specific entity concepts \\- Assertions about characteristics ([big/large](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_7.html#feature_num_2997)) \\- Grammatical relationship joiners ([between](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_10.html#feature_num_8127)) | - [H9.0](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_0.html)*: Complex tracking on specific concepts (what is happening to [time](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_0.html#feature_num_16056), where [focus](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_0.html#feature_num_24001) should be, actions done to [eyes](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_0.html#feature_num_21955), etc.) - [H9.2](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_2.html): Complex concept completions ([death](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_2.html#feature_num_21988), [diagnosis](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_2.html#feature_num_2252), [LGBT discrimination](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_2.html#feature_num_773), [problem and issue](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_2.html#feature_num_11365), [feminism](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_2.html#feature_num_11431), [safety](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_2.html#feature_num_17913)) - [H9.9](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_9.html)*: Copying, usually names, with some induction - [H9.10](https://robertzk.github.io/gpt2-small-saes/cards/top_features_9_10.html): Grammatical relationship joiners (from X to, Y with, aided by, from/after, between) |
| 10  | \\- Grammatical adjusters \\- Physical or spatial property assertions \\- Counterfactual and timing/tense assertions ([would have](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_5.html#feature_num_6174), [hoped that](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_5.html#feature_num_8327)) \\- Certain prepositional expressions ([along](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_11.html#feature_num_14525), [under](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_11.html#feature_num_619)) \\- Capital letter completions ([“B”](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_10.html#feature_num_6954)) | - [H10.1](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_1.html): Assertions about a physical or spatial property (up/back/down/ over/full/hard/soft/long/lower) - [H10.4](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_4.html): Various separator character (colon for time, hyphen for phone, period for quantifiers) - [H10.5](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_5.html): Counterfactual and timing/tense assertions (if/than/had/since/will/would/until/has X/have Y) - [H10.6](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_6.html): Official titles - [H10.10](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_10.html)*: Capital letter completions with some context tracking (possibly non-standard induction) - [H10.11](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_11.html): Certain conceptual relationships |
| 11  | \\- Grammatical adjustments \\- Bi-grams \\- Capital letter completions \\- Long range context tracking | - [H11.3](https://robertzk.github.io/gpt2-small-saes/cards/top_features_11_3.html): Late layer long range context tracking, possibly for output confidence calibration |

Investigating Attention Head Polysemanticity
--------------------------------------------

While our technique is not sufficient to prove that a head is monosemantic, we believe that having multiple unrelated features attributed to a head is evidence that the head is doing multiple tasks. We also note that there is a possibility we missed some monosemantic heads due to missing patterns at certain levels of abstraction (e.g. some patterns might not be evident from a small sample of SAE features, and in other instances an SAE might have mistakenly learned some red herring features).

During our investigations of each head, we found 14 monosemantic candidates (i.e. all of the top 10 attributed features for these heads were closely related). This suggests that over 90% of the attention heads in GPT-2 small are performing at least two different tasks.

To explicitly show an example of a polysemantic head, we use evidence from what SAEs attributed to the head have learned to deduce that the head performs multiple tasks. In H10.2, we find both [integer copying](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_2.html#feature_num_21703) behavior and [url completion](https://robertzk.github.io/gpt2-small-saes/cards/top_features_10_2.html#feature_num_11515) behavior in the top SAE features. Zero ablating each head in Layer 10 and recording the mean change in loss on synthetic datasets[^vyimrjubj8k] for each task shows a clear jump for H10.2 relative to other heads in L10, confirming that this head really is doing both of these tasks:  

![](https://lh7-us.googleusercontent.com/FvAXqA6XyNgeMbW76zb2wS88FwN2i95QAUa-kHS4gnuo6tt4L95VnavMg7te_vKV5_ClauDSB2grMaqo5v61VA2m1DcLMKDSnbENBFpNlSDujHaknSD1MgYUsXvF_Smls0qbTRqfTYeDNkcnw7MiGNU)

 Average change in loss when ablating Layer 10 heads on prompts of the form “ {noun} {digit}, {filler text} {noun} {digit}” when predicting the the repeated digit.

![](https://lh7-us.googleusercontent.com/s3E8FKDS_tve2IWZmdiL94injmoGo6EBAqt8Hhrp0eMazvLtg48ytnbWfSg8Of7BhsmGITXn695usLeijv7F2BYN8njF4_D_VqF7SinzGaCsrjuTJtwQAz5y4vv7u1byLJA57H8v-3S40-n9XOcaIV8)

Average change in loss when ablating Layer 10 heads on prompts of the form “ https://t.co/{random\_resource\_id}” for the resource id predictions.

Note that the line between polysemantic and monosemantic heads is blurry, and we had a high bar for considering monosemantic candidates. For example, consider [H5.10](https://robertzk.github.io/gpt2-small-saes/cards/top_features_5_10.html): all 10 features look like context features, boosting the logits of tokens related to that context. We labeled this as polysemantic since some of the contexts are unrelated, but we could plausibly think of it as a general monosemantic “context” head. We also think that head polysemanticity is on a spectrum (e.g. heads with 2 roles are less polysemantic than heads with 10). If we can understand the multiple roles of a polysemantic head, it still might be worth trying to fully understand it in the style of [McDougall et al](https://arxiv.org/abs/2310.04625).

Discovering Plausibly Monosemantic Heads
----------------------------------------

While our technique doesn’t prove that heads are monosemantic, we are excited that our SAEs might narrow down the search space for monosemantic heads, and reveal new, messier behaviors that have been historically harder to understand in comparison to cleaner algorithmic tasks. 

For the monosemantic candidates, we see a range of different behaviors:

*   Local context features in descriptions of some entity ([2.9](https://robertzk.github.io/gpt2-small-saes/cards/top_features_2_9.html))
*   Previous token ([4.11](https://robertzk.github.io/gpt2-small-saes/cards/top_features_4_11.html), [5.6](https://robertzk.github.io/gpt2-small-saes/cards/top_features_5_6.html))
*   Induction ([5.5](https://robertzk.github.io/gpt2-small-saes/cards/top_features_5_5.html), [6.9](https://robertzk.github.io/gpt2-small-saes/cards/top_features_6_9.html), [7.10](https://robertzk.github.io/gpt2-small-saes/cards/top_features_7_10.html))
*   Long prefix induction ([5.1](https://robertzk.github.io/gpt2-small-saes/cards/top_features_5_1.html))
*   Preposition copying ([8.1](https://robertzk.github.io/gpt2-small-saes/cards/top_features_8_1.html))

For example, consider [H8.1](https://robertzk.github.io/gpt2-small-saes/cards/top_features_8_1.html). For all top 10 features, the top DFA suggests that the head is  attending to a different preposition (including ‘with’, ‘from’, ‘for’, ‘to’), and the top logits boost that same preposition. This suggests that this might be a monosemantic “Preposition mover” head that specifically looks for opportunities to copy prepositions in the context. 

![](https://lh7-us.googleusercontent.com/KsN-rKtoNvBk1-KHzSaZ2dyfhZwIVfCHxXiO4Igp892DDV9YkzWBg6MNKnWuDQGtqpC5LkNr1tTJBlQEO9RAwJ1aN4sw-88pEYOB1Ltt9XPCg9Y5eobOdle64UMU7nb_hZnMPDnYHVv7Mq7zrXdVyro)

![](https://lh7-us.googleusercontent.com/1SF-S3za7-jWLYQ2hlkmuc1kMapo1PwpcsHdEn3QR-FL-qyJHIngeXafQt1FIFG2zR_26eaNR6BhV4l2gFe261ZtMde5616UbYczsPBDIM13WNJazLi4mfz-1rEXHfq_8zXPX0CBLien91zV_JWkCKo)

As shown in the table below, we also found instances where a head was almost monosemantic or plausibly bisemantic.

| **Head Type** | **Fraction of Heads** |
| --- | --- |
| **Plausibly monosemantic**: All top 10 features were deemed conceptually related by our annotator. | 9.7% (14/144) |
| **Plausibly monosemantic, with minor exceptions**: All features were deemed conceptually related with just one or two exceptions. | 5.5% (8/144) |
| **Plausibly bisemantic**: All features were clearly in only two conceptual categories. | 2.7% (4/144) |

Case Study: Long Prefix Induction Head
--------------------------------------

To further verify that our SAE features are teaching us something real about the roles of heads, we show that we can distinguish meaningfully different roles for two induction heads in L5 of GPT-2 small, shedding some light on why there are [so many induction heads](https://www.neelnanda.io/mosaic) in language models. We find that one head seems to be specializing in “long prefix induction”, while one head mostly does “standard induction”.

Notably this hypothesis was motivated by our SAEs, as glancing at the top features attributed to [5.1](https://robertzk.github.io/gpt2-small-saes/cards/top_features_5_1.html) shows “long induction” features, defined as features that activate on examples of induction with at least two repeated prefix matches (eg 2-prefix induction: ABC … AB -> C).  We spot these by comparing tokens at (and before) each top feature activation with the tokens preceding the corresponding top DFA[^gk1ijmi45jj] source position. While previous work from [Goldowsky-Dill et al](https://arxiv.org/abs/2304.05969) found similar “long induction” behavior in a 2-layer model, we (Connor and Rob) were not aware of this during our investigations, showing that our SAEs can teach us novel insights about attention heads.

As an illustrative example, we compare two “‘-’ is next by induction” features attributed to heads 5.1 and 5.5 respectively. Notice that all of the top examples for 5.1’s feature are examples of long prefix induction, while almost all of the examples in 5.5’s feature are standard (AB ... A -> B) induction. For example, comparing the top DFA to the feature activation for 5.1’s top example shows a 4-prefix match (.| ”|Stop| victim), while 5.5’s top feature is  1-prefix ( center). 

![](https://lh7-us.googleusercontent.com/SBqYaw80MMiiAaEpILiSo_qwzO-0w_Y-MrZZEr6LCrx6ouRPOg8GOC6enrdz-YAFaAt9f_K5Qx_YihsrdR-jaldkWLmSOm97lxU0Zv1EgykCkyGVq8kDdvQ9oF0VgKMhoHPjUypS_FJDWBIE8iLSuiA)

L5H1 F19293: ‘-’ is next by long induction. Notice the same 4-token prefix on the left (activations) and right (DFA) examples.

![](https://lh7-us.googleusercontent.com/dT9_CkxJD2SB0NUae6gIvZivcismCHOgm-Q6VQKXlYSzqDCMiGDGqSScurzVg_e9Q5hKEz8C6kQ5oj_tmImJTTddCahI3quxaL6iOQ1RtJJwsOW76Bam5Y8_9HTqFvB8BHxokWkfz2ivY3CvwYaE_BY)

L5H5 F35744: ‘-’ is next by induction. Notice that for most examples there is no common prefix other than the preceding token.

To confirm that this isn’t just an artifact of our SAEs, we reinforce this hypothesis with independent lines of evidence. We first generate synthetic induction datasets with random repeated tokens of varying prefix lengths. We confirm that while both induction scores rise as we increase prefix length, 5.1 has a much more dramatic phase change as we transition to long prefixes (i.e. >=2 ):

![](https://lh7-us.googleusercontent.com/McvYFxsT7e8-ozorC5H5Ccg2ttFrUoPclco4klZh6d4W_TT5ZQ8VoD0v_0-oNLIYACdypc9-meAs5m5IilBwPQDu9eLKenK7zJmEdkIHwefUhVYKBYVCZADZZ0VrP_HyQ-FUQerA9I-eK8gCrG5RTM8)  
  
We also check each head’s average [direct logit attribution](https://dynalist.io/d/n2ZWtnoYHrU1s4vnFSAQ519J#z=disz2gTx-jooAcR0a5r8e7LZ) (DLA) to the correct next token as a function of prefix length. We again see that 5.1’s DLA skyrockets as we enter the long prefix regime, while 5.5’s DLA remains relatively constant:

![](https://lh7-us.googleusercontent.com/blwqBS9Fm43ASG-DJ7nnYHNZSSCT-0Kjn1h8DAKS0pEjsxolzXGguYLEedQuVkDMaiZusIhnrfcrrIGK9D7buyhEjd__6FH_dswYIsXkvA2Ut_0WnANWTLGpUKm92oQL2VAvCd1EHkC4Sqsu3HGi_so)  
We now check that these results hold on a random sample of the training distribution. We first filter for examples where the heads are attending non-trivially to some token[^tmckfir2mc] (i.e. not just attending to BOS), and check how often these are examples of n-prefix induction. We find that 5.1 will mostly attend to tokens in long prefix induction, while 5.1 is mostly doing normal 1-prefix induction.  

![](https://lh7-us.googleusercontent.com/3K8WVALv-fKQOSDla-wgXza96MwysEbIdNOupfEDH5Na3vfo0UDPf5ULtZtZx3Nb4NVmOY2X2FEnuTyZJEokgIeCGtv35n8k-wAwEcOOFZO3PRlj_FLXU7meJ1-OD_960qrkkk2XJwX4PFY4oB9FlyI)  
We intervene on the long induction examples from the training distribution, corrupting them to only be one prefix, and show that 5.1’s average induction score plummets from ~0.55 to ~0.05, while 5.1 still maintains an induction score of ~0.45. 

![](https://lh7-us.googleusercontent.com/QV-_-rGPkrSNdmLo92J9_b5mV6GynpagT561qvRSnt8NJK_mtVd-8Lp2L3-RmcZpBSN6AhA7qnzDIRnwWDbZrGjN3-sU06JuFg7fvF2TBZ6WrEom82PBiCDLqXygciPELtmWqodg3XoqZ3eBNkGRpMs)  
Finally, we see hints of universality: checking average induction scores on our synthetic induction dataset for a larger model, GPT-2 Medium, reveals signs of both “long prefix” and “standard” induction heads. 

![](https://lh7-us.googleusercontent.com/J3k8upWV6wPBSb0RK2Bwqd_JWs6V2D47HgnvwOREU9WzmOHRdEoYQ9cy_e5bjM1XBylFfa5SvOsESesOCIgBIHxU0E3-tizLmC3osPHGVdJyma-X2ifcCnKwDiOttfPkF_9PHzQNfDdCCcicYN4VFkY)  
Limitations
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

*   We only looked at the top 10 SAE features per head, sorted by an imperfect proxy. Ten is a small number, and sorting may cause [interpretability illusions](https://arxiv.org/abs/2104.07143) where the head has multiple roles but one is more salient than the others. We expect that if the head has a single role this will be clear, but it may look like it has a single role even if it is polysemantic. Thus negative results falsify the monosemanticity hypothesis but positive results are only weak evidence for monosemanticity.
    *   We didn’t spend much time per head and fairly shallowly looked at dataset examples per head which is also an imperfect method for determining the meaning of a feature and could lead to both false positives and false negatives.
*   We don’t totally understand what a whole attention layer does. We are deliberately looking at SAE features that mostly rely on only one attention head. This misses additional behavior that relies on clever use of multiple heads (e.g. attention head superposition)
*   Interestingly, we note that some heads involved in IOI did not show representative features, but this is plausibly due to the IOI roles not being their primary tasks.

Appendix: Attention Heads Feature Map
-------------------------------------

We recorded the groupings for all heads in [this Google Sheet](https://docs.google.com/spreadsheets/d/12HWFwUrs_W60pfjBOo6-CMLTfPG92XIbkr8_ANs1lA0/edit#gid=0) based on the corresponding [attention head feature dashboards](https://robertzk.github.io/gpt2-small-saes/). We thank Callum McDougall for providing the [visualization codebase](https://github.com/callummcdougall/sae_vis) on top of which these dashboards were constructed. The code for generating the dashboards is available by messaging any of the first two authors.

Citing this work
----------------

Feel free to use [the citation from the first post](https://www.lesswrong.com/posts/DtdzGwFh9dCfsekZZ/sparse-autoencoders-work-on-attention-layer-outputs#Citing_this_work), or this citation specifically for this current post:

    @misc{gpt2_attention_saes_3,
      author= {Robert Krzyzanowski and Connor Kissane and Arthur Conmy and Neel Nanda},
      url = {https://www.alignmentforum.org/posts/xmegeW5mqiBsvoaim/we-inspected-every-head-in-gpt-2-small-using-saes-so-you-don},
      year = {2024},
      howpublished = {Alignment Forum},
      title = {We Inspected Every Head in GPT-2 Small Using SAEs So You Don’t Have To}
    }

Author Contributions Statement
------------------------------

Connor and Rob were core contributors on this project. Rob performed high-level grouping analysis of every attention head in GPT-2 Small and some corresponding shallow dives. Connor performed the long prefix induction deep dive and the H10.2 polysemanticity experiment. Arthur and Neel gave guidance and feedback throughout the project. The original project idea was suggested by Neel.

We would like to thank Georg Lange and Joseph Bloom for extremely helpful criticism about our claims on polysemanticity in an earlier draft of this work.

[^vyimrjubj8k]: For other heads, we also used proxies to detect examples in OpenWebText with the hypothesized head behaviors, but had messier results. Our initial hypotheses were often too broad (eg "succession" vs "succession for integers"), which led to false negatives. Synthetic data was helpful to filter these. 

[^gk1ijmi45jj]: Note DFA is attention weighted, so you can think of it as similar to an attention pattern 

[^tmckfir2mc]: We show a threshold of 0.3. The results generally hold for a range of thresholds.