# Latent Reasoning Sprint #3: Activation Difference Steering and Logit Lens

In my[](https://www.lesswrong.com/posts/c4LYmzEC6cFQzrDZz/probing-codi-s-latent-reasoning-chain-with-logit-lens-and)[previous post I found](https://www.lesswrong.com/posts/c4LYmzEC6cFQzrDZz/probing-codi-s-latent-reasoning-chain-with-logit-lens-and) evidence consistent with the scratchpad paper's compute/store alternation hypothesis — even steps showing higher intermediate answer detection and odd steps showing higher entropy along with results matching “Can we interpret latent reasoning using current mechanistic interpretability tools?”.

This post investigates activation steering applied to latent reasoning and examines the resulting performance changes.

Quick Summary:
==============

*   Tuned Logit lens sometimes does not find the final answer to a prompt and instead finds a close approximation
*   Tuned Logit lens does not seem to have a consistent location layer or latent where the final answer is positioned.
*   Tuned logit lens variants like ones only trained on latent 3 still only have therefore on odd vectors.
*   Activation steering for the average difference between latent vectors did not create increases in accuracy with specific latent pair combinations and instead matched closely with random vectors from[](https://www.lesswrong.com/posts/YGAimivLxycZcqRFR/can-we-interpret-latent-reasoning-using-current-mechanistic)[“Can we interpret latent reasoning using current mechanistic interpretability tools?”](https://www.lesswrong.com/posts/YGAimivLxycZcqRFR/can-we-interpret-latent-reasoning-using-current-mechanistic)
*   Steering the kv cache to steer CODI outputs can increase accuracy while steering with hidden states do not seem to have a significant effect on CODI

Experimental setup
==================

### CoDI model

I use the publicly available CODI Llama 3.2 1B checkpoint from[ Can we interpret latent reasoning using current mechanistic interpretability tools?](https://www.lesswrong.com/posts/YGAimivLxycZcqRFR/can-we-interpret-latent-reasoning-using-current-mechanistic)

### Tuned Logit Lens

### To create my tuned logit lens implementation I used the code implementation for the training of Tuned logit lens from[ Eliciting Latent Predictions from Transformers with the Tuned Lens](https://github.com/AlignmentResearch/tuned-lens)  
  
Activation Steering

1.  Embedding steering

Getting the average hidden state from each latent vector and using the difference between latent vector A and B to steer the hidden states.

 Since codi uses the kv values on eot token. To get new kv values that contain the info from the steered vector I needed to steer latent 1 -> run codi for one additional latent and then get the kv values of latent 2 and see the output.

2.  KV cache Steering

Steering the KV kache and adding the steered KV kache directly onto the codi model. Directly adding average difference in kv values to past\_key\_values.

Experiments
===========

Confirming Previous Assumptions
-------------------------------

PROMPT = "Out of 600 employees in a company, 30% got promoted while 10% received bonus. How many employees did not get either a promotion or a bonus?"

Answer = 360

Tuned Logit Lens properties:

*   Tuned lens approximates but, doesn't find the answer in some cases  like 720 (360 x 2) and 350 (360 - 10) latent 0 and 1
*   Approximate answers are not GSM8K artifacts as neither of these numbers are in the most common answers for the dataset
*   The answers being found in latent 3 and 5 for my[](https://www.lesswrong.com/posts/c4LYmzEC6cFQzrDZz/latent-reasoning-sprint-1-tuned-lens-and-logit-lens-on-codi)[previous post](https://www.lesswrong.com/posts/c4LYmzEC6cFQzrDZz/latent-reasoning-sprint-1-tuned-lens-and-logit-lens-on-codi) with tuned lens might be prompt specific. This suggests tuned lens might just be used as a way to see potential outputs

| Default Tuned | Default |
| --- | --- |
| ![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/oc6yr95MCiCMggYHG/aeab01fea9ec6fa99a9f21393957fd53e33782ba4cb22b1477daa1480653f850/ujpfqxj9c1qepgwnrcvk) | ![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/oc6yr95MCiCMggYHG/37d097bc864ced602638bf1c1d622a24834c3c1097c2b9f543bfeb902614dad9/d1aqpkjwkx5zp2jx9xk0) |

The following is the answer frequency for the GSM8K data used to train the tuned logit lens

![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/oc6yr95MCiCMggYHG/593011ae89d0e41fbfe3a5b2c7a8a54296da875975694215b495e93faf4d1ec3/jnommxgoe07gxtffok8z)

This prompted me to revisit my previous results using a tuned logit lens trained only on latent 3. Notably, 'therefore' still appears only on odd latents, even with this different prompt.

  

![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/9d1c40c596521e8a724dbe06de7357f287e689da19c837ecb0b2cb9da748510e/m7fbzi1a4yfsyxu9asqk)

Activation Difference (Steering Embeddings)
-------------------------------------------

Across all coefficient values tested, the steering was applied to latents 1–4, with one additional latent step run afterward to obtain updated KV values. The steered models seem to consistently underperform the baseline of no steering until the later latents match the performance of random vector patching “Can we interpret latent reasoning using current mechanistic interpretability tools?”. This might be the case because steering acts the same as random vector patching as the average difference vector might be too noisy to encode meaningful directional information.

![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/oc6yr95MCiCMggYHG/0c4494468464d27078d26e532b1da8a34823d2517c276d354381184e44fde7be/pta8vxxuujfzwwrncy9n)![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/c4c19aa38ec4fe49eed275297945c6fbe0392a78f00f6f3ad271cabf6c9da308/wvpgxkgte4hgsfanxbyg)

Activation Difference (Steer KV cache)
--------------------------------------

*   Unlike the other method of steering which required another codi pass to get new kv values to pass this method steered the kv values as it was being used on the EoT token to generate the answer
*   Set up is getting the mean activations of latents A and B and subtracting them and steering the difference with a coefficient. Latent A is the first latent vector which is in turn subtracted by another latent vector B
*   Steering the kv values unlike steering the hidden states seemed to change work in changing the accuracy of latent step 5.
*   Most vectors being used for steering performed worse than random latent vector activation patching. Some performed significantly better than the baseline
*   Coefficient (0.5):
*   *   The steered vectors that worked to improve performance are  A1-B2, A1-B5, A2-B3, A2 - B3, A2-B4, A3-B5, A4-B5 coefficient 1. When steering with the difference of an earlier  latent vector and a later latent vector it is interesting how combinations  that included latent 2 performed the best for the latent A.
*   Coefficient (-1):
*   *   The negative coefficient flips A-B to B-A
    *   Since the coefficient is -1  A1-B4, A1-B6, A4-B6, A5-B6 can be interpreted as B4-A1 B6-A1, B6-A4, B6-A5. It seems latents are steered with 6 minus an earlier latent like 1,4,5 seems to have significant increase in accuracy. And differences like between the 1 and 6 and difference latents 5 and 6 seemed to have the highest increase in accuracy.  
*   Accuracy for all steering decreases as the coefficient increases
*   There is no activation difference that improves accuracy in positive and negative coefficients

| Positive Coefficients | Negative Coefficients |
| --- | --- |
| A1-B2 |     |
|     | B4-A1 |
| A1-B5 |     |
| A2 - B3 |     |
| A2-B4 |     |
| A3-B5 |     |
| A4-B5 |     |
|     | B6-A1 |
|     | B6-A4 |
|     | B6-A5 |

  

Baseline
--------

![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/23c138260ee5fd02d090285b5232c040056c1b4531c25ce5415eb2e8ed1873d2/ditkox032fkvwlac8qud)

For negative coefficients A1-B4, A1-B6, A4-B6, A5-B6 performed better than the baseline after the steering for latent 5 a common pattern is with negative coefficient  after steering performed  significantly better than the baseline for latent 5![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/778eb576fa65f1ca6687b68f0c72380335359ed77aad669dcf22c6067bcffb00/nxemj88zq35evyfc28gt)

The positive latents performed better than the baselines on A1-B2, A1-B5, A2-B3, A2 - B4, A2-B4, A3-B5, A4-B5.

![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/1b5f8e1e02454d4085543dcc4a3aa7ddcaa2c8db0189c6d18051794a70204870/tyzkeklyjeij5hnzf5fw)

![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/oc6yr95MCiCMggYHG/ebac952541d841ea5fb1b97e277a2881f08e9602f68f04bfd0312249da3047f9/s3ijy0w0nncc7b4uqtpv)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/9c7ed9bd8d61baf89dffc0ac7c082a2c078b3749ad87e147ec4d1cf800a3d184/za0rbvxuallks0wxrq3t)

Activation Difference (Logit Lens)
----------------------------------

No clear pattern emerges from the activation difference logit lens. The first image is of default logit lens the second image is tuned logit lens the axis is on the y it is latent A on x latent B the activation difference is vectors A - B and the logit lens was done on the differences mean activation A and B for the different layers of the model.

![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/oc6yr95MCiCMggYHG/027595741dea0327c06d733ca8f6ac989ce2e515ca2e7dc3e7f5933b8fc9692c/ea6evgfyebmeptilnaty)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

![](https://res.cloudinary.com/lesswrong-2-0/image/upload/f_auto,q_auto/v1/mirroredImages/57a7b3438c3d1d1f69cced1eb5150f29e4cabb1fda565b76037492a89b24ced7/o4uagz8z5hdjavwyxkek)

Future Work
===========

  

*   Find a setup that makes activation steering work with CODI
*   Complete the thought anchors with CODI
*   Why did certain activation differences for the KV cache increase accuracy
*   Look with other methods such as PCA to observe the reason why activation steering worked on kv but, not hidden state.