nhorozov.xyz/blog/hnc rank tinkering
this is a draft, but its also not bad at the moment
Hessian Nullspace continuation effect on rank of matricies
Date: September 14 2026
This was tinkered around with over the course of a few hours, and written up over the course of a few days (after sep-14-26). I’m confident about my intuitions behind this but don’t fully understand all of the math. An example of this is eigendecomposition, which I can’t say I formally/rigourously know but I can clearly imagine what it would mean to have low eigenvalues in the eigendecomposition of a Hessian (there’s flatter bits in those directions, though they aren’t fully flat). I used GLM 5.3 flash for this, and my prompts are at the bottom of this post.
Intro
Last month I attended NEMI and a student presenter, Ann Huang, presented a project where they applied a method that moves the weights of a neural network in directions towards low-curvature regions of a loss landscape defined by a behavior similarity metric to the inital network (1/2 * |f_i(x)-f(x)|^2, averaged over a set of inputs). Because the Hessian only gives local low-curvature directions, they recompute it after moving the model a little in one of those directions. In the process they include an optional step of moving in flatter directions that also minimize CKA, or you could just pick a random flatter direction. They alternate nudging the model with the Hessian and gradient descent on a behavior preserving loss, and repeat this prosess many times. They call their method Hessian null space continuation (HNC). This is a really cool method.
They found that the internal structures learned change when HNC is applied.
When I watched the presentation I was thinking that these new networks are probably harder to compress in some way. I know that many powerful learning algorithms have a bias towards simplicity, and I knew that backpropagation and RL generally decreases the rank of the matrices in the neural networks, which is interesting because most matrices out there are really high-rank.
Because of this I figured the rank would probably increase when HNC is applied.
What I did
I trained 3 models from scratch, a MNIST MLP, an RNN for the 3 bit memory task from the presentation, and the transformer from Progress measures for grokking via mechanistic interpretability, recording their rank during training. I then applied HNC to each of them and measured the rank as it changed. I also considered how CKA-steering affected the rank.
(note: during this I didn’t know a ton about the different ways to calculate rank and the different kinds of it, and thought that the actual `numpy.linalg.matrix_rank would be the thing changing, I was wrong about that and GLM 5.3 flash suggested using stable rank and participation ratio)
GLM 5.3 flash did a lot of the heavy lifting here and was mostly given a detailed inital prompt (where i listed the models I wanted to apply HNC to, what I wanted to graph).
Here are some figures of the rank changing for multiple seeds, with phase A being the training and B being the HNC:
Graphs
note: looking at these graphs, I notice that they don’t all call rank the same thing (stable vs effective) and while they both measure the same calculation in the code, they’re labled sloppily (glm 5.3 flash made them when working). I will fix this soon
Part A (training from scratch)
We can see the rank generally fall when training the transformer from neel nanda’s grokking paper. Depending on the matrix, something it does sometimes is go down a lot and and come up a little. For seed 2 in the W_E matrix it actually keeps going down, which is cool.
Gradient decent has a bias towards simplicity and since (stable) rank is some kind of proxy to complexity (high-rank~high complexity), it makes sense to see it fall here. This part isn’t really new but I like it a lot.
i might do some interp of these models in the comming days.
Part B (HNC)
This part is more interesting. There is a general upward trend for the rank of the matrices but its not always and its not constant. You can most clearly (out of the three seeds) see a general rise in the rank this in the transformer. But some matrices’ rank increases while others’ decreases.
I think you can see it better in this seed (#2) because it got to a lower rank in part A than the other seeds.
(more) Discussion
…
all images
part A (training from scratch)
- phaseA_mlp.png
- phaseA_mlp_stable.png
- phaseA_mlp_task.png
- phaseA_rnn.png
- phaseA_rnn_stable.png
- phaseA_rnn_task.png
- phaseA_transformer.png
- phaseA_transformer_stable.png
- phaseA_transformer_task.png
part B (HNC)
- phaseB_mlp_seed0.png
- phaseB_mlp_seed1.png
- phaseB_mlp_seed2.png
- phaseB_rnn_seed0.png
- phaseB_rnn_seed1.png
- phaseB_rnn_seed2.png
- phaseB_transformer_seed0.png
- phaseB_transformer_seed1.png
- phaseB_transformer_seed2.png
Prompts I gave to the agent
Read and deeply understand the poster in this directory. More context: https://nhorozov.xyz/blog/nemi26.md. I want to apply this method to a series of simple models and use numpy.linalg.matrix_rank to see how the rank of the matricies in these models changes, as they are trained from scratch at their tasks, and then as the Hessian null space continuation method is applied. Gain a lot of comprehensive context about this project, reason deeply, and get back to me when you are ready to start.
This is good, for point 2 add the transformer from (https://www.alignmentforum.org/posts/N6WM6hs7RQMKDhYjB/a-mechanistic-interpretability-analysis-of-grokking) to the list of the three models that will be trained from scratch and then phase b, with both unsteered and CKA-steered applied to all of them. Start, and if you have questions about something or have unresovable issues with hardware stop working and ask me to help.
I gave my NEMI post to the agent because I partally describe the method there, though not very well.
you can find me at [the first two letters of my first name][my last name]@gmail.com