wikillm

Paper · 2023-08-31 · cs.CL, cs.AI, cs.LG

YaRN: Efficient Context Window Extension of Large Language Models

Rescales RoPE frequencies per dimension (slow-rotating dimensions are interpolated, fast ones are kept, with a ramp between) and scales attention logits by a length-based factor, so Llama 2 models reach 64k and 128k context after short fine-tunes. Author-reported: the 7B model at 128k reaches perplexity 2.37 on Proof-pile and 99.4% passkey accuracy.

Positional encodingRelative positional encodingContext-window extensionlong-contextrotary-embeddingspositional-encodingcontext-extension

arXivPDFCodeMarkdown15 min read

AI-compiled by claude-haiku-5-5 on 2026-11-09, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.

In plain words

A language model reads text as a sequence and needs to know where each word sits in it. One common way to give it that sense of position is to rotate the internal numbers for each word by an angle that depends on its position. Models trained this way work well up to the length they saw in training, and then quickly get worse on longer text.

The obvious fix is to squeeze the longer text into the familiar range of positions. That works a little, but it blurs the fine detail of nearby word order, and the blur gets worse the more you squeeze. YaRN treats the rotation speeds differently depending on how fast they turn. Fast-turning parts already tell nearby words apart, so they are left alone. Slow-turning parts are the ones that would otherwise run out of range, so they are squeezed. A smooth blend sits in between. YaRN also scales the attention scores by a factor that depends on how far the context is stretched.

The result is a model that can read much longer text after only a short extra training run, or in some cases with no training at all. It keeps its original behaviour on short tasks, and it needs no change to the attention code itself, so fast attention kernels still work.

TL;DR

  • YaRN extends the context of RoPE models such as Llama 2 by changing only the rotary frequencies and one attention scale factor §3.3.
  • The method is the "NTK-by-parts" frequency blend plus a length-based logit scale of 0.1 ln(s) + 1 under the square root, fitted on LLaMA §3.2 §3.3 eq. 15.
  • Authors report that 7B and 13B Llama 2 models fine-tuned at 64k or 128k keep short-context benchmark scores near the originals §4.4 tab. 3.
  • Code is public (MIT) and matches most of the paper, but the optimizer defaults, the learning-rate decay, the gradient clipping and the dynamic variant differ from the text (see Paper vs code).

Problem

Rotary position embeddings (RoPE) encode position by rotating query and key vectors. Models pretrained with RoPE fail on sequences longer than their training length, even though RoPE is in principle a relative encoding §1 §3.2. Position Interpolation (PI) squeezes all positions into the trained range with one scale factor. It works after fine-tuning, but the squeeze removes high-frequency detail, and fine-tuned PI models degrade beyond a scale of about 8 §3.1. The "NTK-aware" base change avoids that loss but leaves the best base to be found by search, and some dimensions are pushed past their trained range §3.1 app. A.2. Fine-tuning cost is also a concern: the conclusion stresses extension under limited compute §5, and the training-efficiency appendix compares steps and data with PI app. B.2.

Method

The authors write every RoPE variant as a modified rotary function that replaces the position m with g(m) and the frequency θ_d with h(θ_d) §2.1 eq. 7. The base frequency of pair d is θ_d = b^(−2d/|D|) with b = 10000 §2.1. The wavelength λ_d = 2π/θ_d eq. 8 gives the number of rotations r(d) = L/λ_d that pair d makes over the pretrained window L §2.2 eq. 10.

Three steps lead to YaRN.

  1. Position Interpolation sets g(m) = s·m with scale s = L'/L and leaves h as the identity §2.3 eq. 9.
  2. NTK-by-parts keeps pairs with many rotations unchanged, divides pairs with few rotations by s, and blends in between with a ramp γ(r). The ramp is 0 for r below α, 1 for r above β, and linear in r between them §3.2 eq. 11. The frequency becomes h(θ_d) = (1 − γ) θ_d / s + γ θ_d §3.2 eq. 12 eq. 13. For Llama models the authors found α = 1 and β = 32 work well §3.2.
  3. YaRN adds an attention temperature t, so that the logits become q·k / (t√|D|) §3.3 eq. 14. The authors fit √(1/t) = 0.1 ln(s) + 1 to the perplexity minimum for LLaMA 7B, 13B, 33B and 65B without fine-tuning, and report that it also fits Llama 2 7B, 13B and 70B §3.3 eq. 15. The factor is applied by scaling the rotary cos and sin tables by √(1/t), so that both q and k scale and the logits scale by 1/t. That costs nothing at inference or training and keeps FlashAttention 2 compatible §3.3.

A separate inference-time variant, Dynamic Scaling, recomputes the factor s from the current length on each forward pass, as max(1, l'/L) where l' is the current length §3.4. Used with the NTK-aware base change, this is called Dynamic NTK. The authors note that cached rotary keys must be stored before the rotation, since the rotation changes when s changes §3.4.

Pseudocode
# YaRN inverse frequencies  [§3.2] [eq. 10] [eq. 11] [eq. 12] [eq. 13]
# Input:  head_dim |D|, base b, pretrained length L, scale s = L'/L
# Output: inv_freq (|D|/2,)

def yarn_inv_freq(head_dim, base, pretrained_len, s, alpha=1, beta=32):
    # RoPE frequency per pair, theta_d = b^(-2d/|D|)  [§2.1]
    theta = base ** (-2 * arange(head_dim // 2) / head_dim)
    # Rotations over the pretrained window, r(d) = L / lambda_d  [eq. 10]
    rotations = pretrained_len * theta / (2 * pi)
    # Ramp: 0 below alpha, 1 above beta, linear in r  [eq. 11]
    gamma = clip((rotations - alpha) / (beta - alpha), 0, 1)
    # Blend between interpolated and unchanged frequency  [eq. 12] [eq. 13]
    inv_freq = (1 - gamma) * theta / s + gamma * theta
    return inv_freq
Pseudocode
# Length-based attention factor  [§3.3] [eq. 15]
# Input:  scale s = L'/L
# Output: sqrt(1/t), applied to both q and k

def attention_factor(s):
    # The official code returns 1 for s <= 1
    # [code: scaled_rope/modeling_llama_yarn.py#L122-L125]
    if s <= 1:
        return 1.0
    return 0.1 * log(s) + 1
Pseudocode
# Rotary tables built once per context length  [§3.3]
# Input:  length T, inv_freq (|D|/2,), factor sqrt(1/t)
# Output: cos_table, sin_table (T, |D|/2)

def rotary_tables(length, inv_freq, factor):
    # Angle for position m and pair d is m * inv_freq_d  [§2.1] [eq. 7]
    angles = outer(arange(length), inv_freq)
    # Multiplying both tables by the factor scales q and k  [§3.3]
    cos_table = cos(angles) * factor
    sin_table = sin(angles) * factor
    return cos_table, sin_table
Pseudocode
# Dynamic Scaling at inference  [§3.4]
# Input:  current length l', pretrained length L
# Output: scale s used for this forward pass

def dynamic_scale(current_len, pretrained_len):
    # Recomputed each forward pass, so it can fall back toward 1  [§3.4]
    return max(1, current_len / pretrained_len)

Hyperparameters

Values in the paper are stated in the text unless noted. "Code" lists the official repository defaults or settings in train.sh, which the paper does not mention. The code paths are relative to the repository at code_commit.

NameValueWhereNotes
RoPE base b10000§2.1Code default base=10000 modeling_llama_yarn.py
Pretrained length L4k (Llama 2), 2k (LLaMA)§4.1Code default original_max_position_embeddings 4096 for Llama finetune.py
Scale s16 (64k), 32 (128k)§4.1Code default --scaling-factor 16 finetune.py. 128k runs use 32 train.sh train.sh
Context after extension64k and 128k (Llama 2); 32k (LLaMA 7B ablation)§4.1Code sets max_position_embeddings = factor × original finetune.py
α, β (ramp bounds)1, 32§3.2Code: beta_slow=1, beta_fast=32 modeling_llama_yarn.py
Attention factor√(1/t) = 0.1 ln(s) + 1§3.3 eq. 15Code get_mscale modeling_llama_yarn.py
Extrapolation factornot stated—Code default 1 modeling_llama_yarn.py
Learning rate2e-5§4.1Code default finetune.py. 70B run in train.sh uses 1e-5, constant schedule (not in paper) train.sh
Warmuplinear warmup, 20 steps§4.1Code default finetune.py
LR decay after warmupnot stated§4.1Code default: linear decay to zero at max_train_steps finetune.py
OptimizerAdamW, β1 = 0.9, β2 = 0.95§4.1Code default path calls torch.optim.AdamW with no betas set finetune.py. DeepSpeed configs set (0.9, 0.95) zero2.json
Weight decaynone§4.1Code default path does not set it finetune.py
Global batch size64§4.1Code: 1 per process × 8 accumulation × number of processes finetune.py finetune.py. Process count not stated
Steps400 (s=16); 200 more for s=32§4.1Code finetune.py train.sh
Fine-tuning dataPG19 in 64k chunks with BOS and EOS§4.1Code default dataset pg_books-tokenized-bos-eos-chunked-65536 finetune.py
Ablation dataPG19 in 32k chunks, LLaMA 7B, s=16, 400 steps§4.1No matching command in train.sh; its 8k ablations use Llama 2 7B train.sh
Attention kernelFlashAttention 2§4.1Code use_flash_attention_2=True finetune.py
Precisionnot stated§4.1Code bf16 mixed precision finetune.py
ParallelismPyTorch FSDP§4.1Code uses accelerate, with DeepSpeed behind a flag finetune.py
Gradient clippingnot stated—Code intends clipping but never runs it (see Pitfalls) finetune.py
Seednot stated—Code default 42; 128k runs use 31337 finetune.py train.sh
Perplexity windowsliding window, S = 256§4.2Code default perplexity.py
Passkey iterations50 for LLaMA 7B 32k models (2k to 32k prompts); 10 for Llama 2 64k and 128k models (8k to 128k)§4.3 app. B.5Fixed by the paper

Results

Author-reported. Setups: Llama 2 7B and 13B fine-tuned at s=16 for 400 steps on PG19 64k chunks, with 200 more steps at s=32 for 128k §4.1. Perplexity is a sliding window (S = 256) over ten Proof-pile documents of at least 128k tokens, with the test split only §4.2. Baselines are PI, NTK-aware, NTK-by-parts and published Together and Code Llama models §4.2 app. B.3.

Long-sequence perplexity tab. 1

ModelScale s8192163843276865536131072Steps
7B4k × 163.512.992.652.42>10^1400
7B4k × 323.563.042.702.452.37400 + 200
13B4k × 163.252.792.502.29>10^1400
13B4k × 323.292.832.532.312.24400 + 200

Open LLM Leaderboard benchmarks, LLaMA 7B, 2k × 16, 400 steps tab. 2

MethodFine-tunedARC-cHellaSwagMMLUTruthfulQA
None (original LLaMA 7B)no51.077.835.734.3
PIyes44.870.225.934.1
NTK-awareyes47.473.927.732.6
NTK-by-partsyes48.576.632.733.4
YaRNyes48.177.230.035.1

Open LLM Leaderboard benchmarks, Llama 2 tab. 3

ModelMethodScale sARC-cHellaSwagMMLUTruthfulQA
7BLlama 2 (original)—53.177.843.839.0
7BYaRN4k × 1652.378.842.538.2
7BYaRN4k × 3252.178.441.737.3
13BLlama 2 (original)—59.482.155.837.4
13BYaRN4k × 1658.182.352.837.8
13BYaRN4k × 3258.082.251.937.3

Training cost in A100 GPU-hours tab. 4. The paper reports these as given; it does not describe how the other rows were measured.

ModelMethodScale sEffective contextGPU-hours (A100)
7B LLaMAYaRN2k × 1632k128
7B Llama 2YaRN4k × 1664k256
7B Llama 2YaRN4k × 32128k256 + 128
7BPI [chen2023extending]2k × 816k640
7BPI (Together)4k × 832k?
7BNTK-aware [xiong2023effective]4k × 44.2≈ 50k64000
7BNTK-aware (Code Llama)4k × 88.6≈ 100k6400

Ablation at 32k, LLaMA 7B, perplexity by evaluation length tab. 5 (fine-tuned rows, 400 steps, scale 2k × 16)

Method2048409681921638432768
PI5.704.954.643.973.57
NTK-aware4.393.923.733.218.49
NTK-by-parts4.143.753.623.122.81
YaRN4.193.773.303.092.77

The same table also has non-fine-tuned rows for all four methods, with YaRN giving the lowest perplexity at 4096 for scale 2k × 2 and the lowest at 8192 and 16384 for scale 2k × 8 tab. 5.

Training efficiency, Llama 2 7B, 4096 to 8192 tab. 6

MethodFine-tunedSteps2048409661448192
Noneno—4.003.58——
PIno—4.303.843.833.65
YaRNno—4.033.613.603.49
PIyes10003.923.513.513.34
YaRNyes4003.913.503.513.35

Comparison with open long-context models tab. 7

ModelContext windowMethod8192327686553698304131072
7B Together32kPI3.502.64>10^2>10^3>10^4
7B Code Llama100kNTK3.712.742.552.542.71
7B YaRN (s=16)64kYaRN3.512.652.42>10^1>10^1
7B YaRN (s=32)128kYaRN3.562.702.452.362.37
13B Code Llama100kNTK3.542.632.412.372.54
13B YaRN (s=16)64kYaRN3.252.502.29>10^1>10^1
13B YaRN (s=32)128kYaRN3.292.532.312.232.24

GovReport perplexity, 50 documents of at least 16k tokens, window 32k tab. 8

ModelContext windowMethodPerplexity
7B Together32kPI3.67
7B Code Llama100kNTK4.44
7B YaRN (s=16)64kYaRN3.59
7B YaRN (s=32)128kYaRN3.64
13B Code Llama100kNTK4.22
13B YaRN (s=16)64kYaRN3.35
13B YaRN (s=32)128kYaRN3.39

Passkey retrieval tab. 9. Ten trials per context size in the appendix, 50 in the main text for 32k §4.3 app. B.5.

ModelScaling factorContext windowTraining data contextMethodPasskey contextPasskey accuracy
7B Together432k32kPI32k100%
7B Code Llama88.6100k16kNTK112k94.3%
7B YaRN1664k64kYaRN64k96.3%
7B YaRN32128k64kYaRN128k99.4%
13B Code Llama88.6100k16kNTK128k99.4%
13B YaRN1664k64kYaRN64k97.5%
13B YaRN32128k64kYaRN128k99.4%

The paper also reports that the 7B and 13B models at 128k pass passkey retrieval with over 99% accuracy across the whole window app. B.5. Table 10 (Open LLM results with Together and Code Llama rows) is not reproduced here app. B.6.

Headline claims in the abstract are that YaRN needs about 10x fewer tokens and 2.5x fewer training steps than earlier methods (abstract). The body supports only the step and data comparison: the YaRN run uses 400 steps against PI's 1000 for similar results app. B.2 tab. 6. The body does not derive the token ratio.

Paper vs code

Repository: jquesnelle/yarn at 995db5b575e75230b3384d658f8b944c9662f775. The paper's authors include the repository owner, and the code carries the MIT licence. Searched first: links in the abstract and the paper itself.

Matches:

Differences:

  • Ramp shape. The paper defines γ as linear in the rotation count r §3.2 eq. 11. The code computes the bounds from the log of the rotation count, then makes the ramp linear in the dimension index modeling_llama_yarn.py. Since the dimension index is a log of r, the code's ramp is linear in log r, not in r. The bounds are also rounded to whole dimensions by floor and ceil modeling_llama_yarn.py. This is my reading of the formulas. I did not run the code to confirm it.
  • Optimizer. The paper says β2 = 0.95 and no weight decay §4.1. The default path calls torch.optim.AdamW without betas or weight decay finetune.py. That gives PyTorch's defaults, which are β2 = 0.999 and weight decay 0.01 in current PyTorch. The DeepSpeed configs set β2 = 0.95 zero2.json zero3.json, but they run only with --deepspeed.
  • Learning-rate decay. The paper states a linear warmup of 20 steps §4.1 and says nothing about decay. The default schedule decays linearly to zero over the run finetune.py. The 70B run in train.sh uses a constant schedule with lr 1e-5 train.sh. The paper does not mention the 70B run.
  • Gradient clipping. The paper does not mention clipping. The code clips only when args.grad_norm is a float finetune.py. The flag is store_true, so its value is a bool, and the clip never runs finetune.py.
  • Global batch. The paper says 64 §4.1. The code defaults to batch 1 per process with 8 accumulation steps finetune.py, so the global batch depends on the process count set in accelerate. The paper does not say how many GPUs it used.
  • Ablation config. The 32k LLaMA 7B ablation §4.1 has no matching command in train.sh. The 8k ablations there use Llama 2 7B train.sh.
  • Dynamic scaling. The paper uses s = max(1, l'/L) for each forward pass, with L the pretrained length §3.4. In modeling_llama_yarn.py, the rotary cache is rebuilt only when a sequence is longer than the cache so far, and the scale is then seq_len / max_position_embeddings, not the pretrained length modeling_llama_yarn.py. Shorter inputs later reuse the larger-scale cache, so the scale does not fall back toward 1. The standalone file divides by the pretrained length LlamaDynamicYaRNScaledRotaryEmbedding.py. The config path dynamic-yarn never passes finetuned=True, so it starts as plain RoPE modeling_llama_yarn.py modeling_llama_yarn.py.
  • Perplexity protocol. The sliding window S = 256 matches the paper §4.2 perplexity.py.
  • Extra models. train.sh also runs Mistral 7B and Llama 2 70B train.sh. The paper does not describe these runs.

Pitfalls

  • The attention factor is fitted, not derived. The formula 0.1 ln(s) + 1 comes from a fit on LLaMA 7B to 65B without fine-tuning, and the authors report that it also fits Llama 2 §3.3. The paper does not say whether it holds for other architectures, and the code applies it to any RoPE model with the same constant modeling_llama_yarn.py.
  • α and β are per-family choices. The paper says they should be tuned case by case and gives values only for the Llama family §3.2. Other families need their own search.
  • Dynamic scaling is ambiguous. The text and the code disagree on the denominator and on whether the scale can fall back §3.4 modeling_llama_yarn.py. An implementer should decide which one they want and test it. The paper's Dynamic-YaRN result is on Llama 2 with no fine-tuning, on a single GovReport sample app. B.7.
  • Cached rotary keys go stale. If you cache rotated keys during dynamic scaling, the cache is wrong once s changes. Cache the keys before the rotation §3.4.
  • The s = 16 models stop at 64k. They show perplexity above 10 at 131072 tab. 1 and at 98304 tab. 7. The s = 32 model, trained for 200 more steps on 64k data, reaches 128k §4.2 tab. 1.
  • Perplexity can understate retrieval. The authors note that the 128k Code Llama model keeps strong passkey accuracy despite rising perplexity, and suggest that perplexity alone does not show effective context length app. B.5.
  • Small evaluation samples. Perplexity uses ten Proof-pile documents §4.2. Passkey uses 50 trials at 32k and 10 at 64k and 128k §4.3 app. B.5. Differences of a few tenths of a point, or a few percentage points, are within noise, but the paper does not report variance for these numbers.
  • Benchmark drops are averages. The authors report an average 0.49% drop from s = 16 to s = 32 §4.4. The per-task drops in tab. 3 are larger for some tasks.
  • Mismatched table reference. The text cites the 32k benchmark table as tab:open_llm, but that label is on the appendix table. The 32k table is labelled tab:open_llm_32k §4.4 app. B.6. When you cite these tables, use the numbers above.
  • Hidden compute. YaRN needs no runtime cost: the rotary tables are precomputed §4.5. The fine-tuning cost is in the GPU-hours of tab. 4, which are the authors' own runs. The paper does not state the hardware count.
  • The default code does not match the paper's optimizer. To reproduce the paper's fine-tune, set β2 = 0.95 and no weight decay explicitly, and choose between the linear decay and a constant schedule. The default path sets none of these.

Lineage

  • Builds on: RoPE, arXiv:2104.09864, the rotary embedding this work modifies §2.1. No card here.
  • Builds on: Position Interpolation, arXiv:2306.15595 §2.3 app. A.1. No card here.
  • Builds on: NTK-aware base change, NTK-by-parts and Dynamic Scaling, which the paper attributes to unpublished community posts rather than to arXiv §3.1 §3.2 §3.4. Not an arXiv paper.
  • Builds on: FlashAttention 2, arXiv:2307.08691, which the implementation uses without change §3.3 §4.1. No card here.
  • Builds on: LLaMA, used for the ablation and the attention-factor fit §3.3 §4.1. Card: LLaMA.
  • Compared against: Code Llama, card Code Llama, and its NTK-aware variant tab. 4 tab. 7 tab. 9. The paper also compares with Together's PI model tab. 7.
  • Compared against: LM-Infinite, arXiv:2308.16137, named as concurrent work that is not compared §2.3.
  • Superseded by: not known from content in this wiki.

Source and license

Adapted from “YaRN: Efficient Context Window Extension of Large Language Models” by Bowen Peng, Jeffrey Quesnelle, Honglu Fan, Enrico Shippole (arXiv:2309.00071), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/jquesnelle/yarn at commit 995db5b575e7 (MIT). Any quoted code is shown under that license.