Emulating ALiBi with RoPE
LLMs typically use some sort of positional encoding for helping the model understand where different tokens (or more precisely, KV cache entries) are. Two of the most common strategies for doing this are RoPE and ALiBi. ALiBi employs a linear bias to the scores based on relative positions, whereas RoPE rotates key and query vector dimensions pairwise at different rates according to their position in the sequence.
It came up for me that I wanted to emulate ALiBi via RoPE, so this is how.
How
Take your trained ALiBi attention heads, for each head, add two dimensions to Q and K with projections that have zero weights and biases such that $q_{fixed} = (-N, 0)$, $k_{fixed} = (0, 1)$.
The RoPE frequencies for all the original dimensions are set to zero (identity rotation). Only the new pair rotates, which it does at rate θ. For query, key positions i, j, and distance d(=j-i), the RoPE contributions $(R_i q_{fixed})\cdot (R_{j} k_{fixed}) = −N \sin(\theta d)$ With scaling: $−\frac{N}{\sqrt{head\_dim}} · sin(\theta d)$ ALiBi needs $−m \cdot d$, so the local match is $N = \frac{m\sqrt{\mathrm{head\_dim}}}{\theta}.$ When $\theta \cdot d$ is small, $\sin(\theta d) \approx \theta d$, and $-\frac{N}{\sqrt{head\_dim}} \sin{\theta d} \approx \frac{N \theta}{\sqrt{head\_dim}} \cdot d = -md$
So ALiBi is equivalent to the small-angle limit of a fixed RoPE pair. As long as you make $\theta$ small enough for long contexts, doing this in turn causes $N$ to be large (for BLOOM's steepest head, $m \approx 0.707$ with $\mathrm{head\_dim} = 64$, a max phase of 0.1 over a 65K window means $\theta \approx 1.5 \times 10^{-6}$, $N \approx 3.7 \times 10^6$). Of course practically if you want to fit it into a specific model's rope you can't choose your exact $\theta$ you have to choose among the available frequencies given by rope where
$$\theta_r = base^{(\frac{-2r}{rope\_dim})}$$ Then again if you are using an existing set all your dimensions are turning which really screws things up. However we want to be realistic here so later we will consider the limitations on emulatability imposed by the size of the base, which sets the frequency of the slowest RoPE pair ($\approx \frac{1}{\mathrm{base}}$) and hence its phase over the window ($\approx \frac{L}{\mathrm{base}}$, for context length $L$).
Does it Actually Work?
I tested it with BLOOM-560M since Bloom natively uses ALiBi. Sure enough it was able to reproduce the results more or less exactly.
| Source | Contexts | Phase span at 65K (rad) | Output TV/token | Max output TV/token | KL/token | Top-1 agreement | Bias-only attention TV | Max attention TV |
|---|---|---|---|---|---|---|---|---|
| Synthetic direct | 1 | 0.1 | 1.24e-4 | 5.32e-4 | 8.33e-8 | 1.000 | 1.05e-4 | 1.63e-3 |
| Synthetic direct | 1 | 2.95 | 0.0423 | 0.206 | 0.0121 | 1.000 | 3.88e-5 | 9.52e-4 |
| Synthetic direct | 1 | 3.0 | 0.177 | 0.76 | 0.27 | 0.938 | 3.95e-5 | 9.42e-4 |
| Synthetic direct | 1 | 4.0 | 0.782 | 0.996 | 3.58 | 0.203 | 1 | 1 |
| Synthetic retrieval suite | 4 | 0.1 | 1.14e-4 | 6.72e-4 | 1.07e-7 | 1.000 | 1.03e-4 | 1.63e-3 |
| Synthetic retrieval suite | 4 | 2.95 | 0.0455 | 0.214 | 0.0142 | 0.977 | 3.73e-5 | 9.54e-4 |
| Synthetic retrieval suite | 4 | 3.0 | 0.197 | 0.932 | 0.364 | 0.871 | 3.79e-5 | 9.67e-4 |
| Synthetic retrieval suite | 4 | 4.0 | 0.792 | 0.996 | 3.68 | 0.223 | 1 | 1 |
| Wikitext-103 LM text | 1 | 0.1 | 1.38e-4 | 4.77e-4 | 1.01e-7 | 1.000 | 1.05e-4 | 1.63e-3 |
| Wikitext-103 LM text | 1 | 2.95 | 0.103 | 0.462 | 0.0579 | 0.844 | 3.88e-5 | 9.52e-4 |
| Wikitext-103 LM text | 1 | 3.0 | 0.268 | 0.484 | 0.316 | 0.703 | 3.95e-5 | 9.42e-4 |
| Wikitext-103 LM text | 1 | 4.0 | 0.817 | 1 | 4.21 | 0.125 | 1 | 1 |
| C4 web text | 1 | 0.1 | 1.47e-4 | 3.11e-4 | 1.20e-7 | 1.000 | 1.05e-4 | 1.63e-3 |
| C4 web text | 1 | 2.95 | 0.0615 | 0.169 | 0.0186 | 0.875 | 3.88e-5 | 9.52e-4 |
| C4 web text | 1 | 3.0 | 0.257 | 0.629 | 0.294 | 0.688 | 3.95e-5 | 9.42e-4 |
| C4 web text | 1 | 4.0 | 0.735 | 0.995 | 2.88 | 0.125 | 1 | 1 |
| SQuAD QA prompt | 1 | 0.1 | 1.50e-4 | 4.42e-4 | 3.46e-8 | 1.000 | 1.05e-4 | 1.63e-3 |
| SQuAD QA prompt | 1 | 2.95 | 0.0897 | 0.308 | 0.044 | 0.906 | 3.88e-5 | 9.52e-4 |
| SQuAD QA prompt | 1 | 3.0 | 0.323 | 0.845 | 0.526 | 0.641 | 3.95e-5 | 9.42e-4 |
| SQuAD QA prompt | 1 | 4.0 | 0.712 | 0.941 | 2.97 | 0.281 | 1 | 1 |
TV is total variation the amount of probability mass that would need to be moved from one bin to another to match the distributions. For the KV TV that is total variation over the attention distributions. For the output TV that is total variation over the output distribution. The rad span is the maximum rotation in radians the RoPE pair used to emulate ALiBi is rotated in the sequence measured in Radians.
The TV measurement is using prefill rather than autoregression i.e. the token sequence is fixed. Both native BLOOM and the RoPE patched version are evaluated on the same sequence. Errors do accumulate across layers but not due to differences in autoregressive results since then the sequences would not remain comparable beyond that point. The results are helped by distant pairs generally having low attention weight/influence so I also tested on a retrieval focused.
Is This Really Realistic?
Q: Isn't this is just glueing on one very slow rotating RoPE pair and keeping the rest of the dimension no-rope. Furthermore is a rotation that slow realistic to what is actually found in real rope models?
A: It depends what "realistic" means. Historically RoPE uses a base like 10k these days long-context models often use much larger rope bases (e.g. 500k-1m). This construction cares about the angular frequency of the slowest RoPE pair $\approx \frac{1}{base}$. Appendix 1 shows that extreme degradation occurs around a rotation of $\pi$ (you can see why by considering that it makes the adjustment for very distant contexts the same as the immediate context). Staying approximately linear requires $\theta \cdot d << 1$ but we can see performance remains strong far beyond that regime. Therefore to practically be able to use a RoPE pair to approximate ALiBi over a context window, its slowest angular frequency must satisfy $\theta \cdot \mathrm{max\_distance} = \frac{max\_distance}{base} < \pi$, (since we want recent items to be weighted higher than far distant ones).
P
Some concrete cached model configs (TV here is BLOOM-560M patched with the sine bias at that config's slowest frequency, versus native BLOOM follow
| Case | RoPE base | Theta / inv_freq | Phase span at 65K (rad) | Sine-vs-linear error | Mean output TV/token | Max output TV/token | KL/token | Top-1 agreement | Mean KV TV | Max KV TV |
|---|---|---|---|---|---|---|---|---|---|---|
| Pythia-70M | 10000 | 3.16e-4 | 20.55 | 95.2% | 0.754 | 0.986 | 2.79 | 0.297 | 1 | 1 |
| TinyLlama | 10000 | 1.33e-4 | 8.67 | 92.1% | 0.823 | 0.997 | 3.84 | 0.156 | 1 | 1 |
| Llama-3.2-1B | 500000 | 3.01e-6 | 0.196 | 0.638% | 1.10e-4 | 4.84e-4 | 5.95e-8 | 1.000 | 1.11e-4 | 1.50e-3 |
| Qwen2/Qwen2.5 0.5B | 1000000 | 1.54e-6 | 0.100 | 0.167% | 1.42e-4 | 9.64e-4 | 5.56e-8 | 1.000 | 1.10e-4 | 1.25e-3 |
Of course though it also helps that this approximation is most off on far distant items that don't get much attention most of the time anyways.
Reflections
RoPE can simulate ALiBi rather simply, (perhaps even pretty obviously) so it raises the question: what are they actually doing? How are the models learning to use them? Why can such different things be used to do the same job — are they really all that different? I have not yet thought of a good clean and efficient way to simulate RoPE with ALiBi. While this certainly speaks to its' relative complexity I don't know that I would characterize it as expressiveness. Since being locked into having dims that rotate at different rates feels much more like a handicap under many circumstances.
Code can be found here.
Appendix 1
Degradation around $\pi$
| Source | Contexts | Phase span at 65K (rad) | sin(phase) | Output TV/token | Max output TV/token | KL/token | Top-1 agreement | Bias-only attention TV | Max attention TV |
|---|---|---|---|---|---|---|---|---|---|
| Synthetic direct | 1 | 2.95 | 0.19 | 0.0423 | 0.206 | 0.0121 | 1.000 | 3.88e-5 | 9.52e-4 |
| Synthetic direct | 1 | 3.0 | 0.141 | 0.177 | 0.76 | 0.27 | 0.938 | 3.95e-5 | 9.42e-4 |
| Synthetic direct | 1 | 4.0 | -0.757 | 0.782 | 0.996 | 3.58 | 0.203 | 1 | 1 |
| Synthetic retrieval suite | 4 | 2.95 | 0.19 | 0.0455 | 0.214 | 0.0142 | 0.977 | 3.73e-5 | 9.54e-4 |
| Synthetic retrieval suite | 4 | 3.0 | 0.141 | 0.197 | 0.932 | 0.364 | 0.871 | 3.79e-5 | 9.67e-4 |
| Synthetic retrieval suite | 4 | 4.0 | -0.757 | 0.792 | 0.996 | 3.68 | 0.223 | 1 | 1 |
| Wikitext-103 LM text | 1 | 2.95 | 0.19 | 0.103 | 0.462 | 0.0579 | 0.844 | 3.88e-5 | 9.52e-4 |
| Wikitext-103 LM text | 1 | 3.0 | 0.141 | 0.268 | 0.484 | 0.316 | 0.703 | 3.95e-5 | 9.42e-4 |
| Wikitext-103 LM text | 1 | 3.05 | 0.0915 | 0.359 | 0.757 | 0.727 | 0.609 | 6.22e-5 | 9.35e-4 |
| Wikitext-103 LM text | 1 | 3.1 | 0.0416 | 0.368 | 0.803 | 0.761 | 0.594 | 2.29e-3 | 0.032 |
| Wikitext-103 LM text | 1 | 3.13 | 0.0116 | 0.365 | 0.819 | 0.741 | 0.609 | 0.0381 | 0.28 |
| Wikitext-103 LM text | 1 | 3.1416 | ~0 | 0.384 | 0.89 | 0.795 | 0.609 | 0.219 | 0.499 |
| Wikitext-103 LM text | 1 | 3.15 | -0.00841 | 0.794 | 0.999 | 3.75 | 0.156 | 0.92 | 1 |
| Wikitext-103 LM text | 1 | 3.2 | -0.0584 | 0.815 | 0.999 | 4.13 | 0.109 | 0.999 | 1 |
| Wikitext-103 LM text | 1 | 4.0 | -0.757 | 0.817 | 1 | 4.21 | 0.125 | 1 | 1 |
| C4 web text | 1 | 2.95 | 0.19 | 0.0615 | 0.169 | 0.0186 | 0.875 | 3.88e-5 | 9.52e-4 |
| C4 web text | 1 | 3.0 | 0.141 | 0.257 | 0.629 | 0.294 | 0.688 | 3.95e-5 | 9.42e-4 |
| C4 web text | 1 | 3.05 | 0.0915 | 0.381 | 0.855 | 0.792 | 0.562 | 6.22e-5 | 9.35e-4 |
| C4 web text | 1 | 3.1 | 0.0416 | 0.4 | 0.858 | 0.866 | 0.531 | 2.29e-3 | 0.032 |
| C4 web text | 1 | 3.13 | 0.0116 | 0.406 | 0.888 | 0.912 | 0.469 | 0.0381 | 0.28 |
| C4 web text | 1 | 3.1416 | ~0 | 0.462 | 0.889 | 1.12 | 0.500 | 0.219 | 0.499 |
| C4 web text | 1 | 3.15 | -0.00841 | 0.71 | 0.993 | 2.46 | 0.172 | 0.92 | 1 |
| C4 web text | 1 | 3.2 | -0.0584 | 0.73 | 0.994 | 2.78 | 0.156 | 0.999 | 1 |
| C4 web text | 1 | 4.0 | -0.757 | 0.735 | 0.995 | 2.88 | 0.125 | 1 | 1 |
| SQuAD QA prompt | 1 | 2.95 | 0.19 | 0.0897 | 0.308 | 0.044 | 0.906 | 3.88e-5 | 9.52e-4 |
| SQuAD QA prompt | 1 | 3.0 | 0.141 | 0.323 | 0.845 | 0.526 | 0.641 | 3.95e-5 | 9.42e-4 |
| SQuAD QA prompt | 1 | 4.0 | -0.757 | 0.712 | 0.941 | 2.97 | 0.281 | 1 | 1 |