Split View: 위치 인코딩 — RoPE와 컨텍스트 확장의 대가
위치 인코딩 — RoPE와 컨텍스트 확장의 대가
- 들어가며
- RoPE가 하는 일
- rope_theta를 파장으로 읽기
- 학습 중에 theta를 바꾸기
- 흥미로운 예외: 낮은 theta에 YaRN
- 절반만 회전시키기
- 긴 컨텍스트는 왜 공짜가 아닌가
- 단계적으로 늘리기
- 마치며
- 참고 자료
- 직접 해보기
- 시리즈
들어가며
트랜스포머의 어텐션은 그 자체로는 순서를 모릅니다. 토큰의 순서를 알려 주는 장치가 위치 인코딩이고, 지금 나오는 오픈소스 모델은 사실상 전부 RoPE, 즉 회전 위치 임베딩을 씁니다.
config에서 관련 필드는 두세 개뿐입니다. rope_theta, max_position_embeddings, 그리고 있을 때만 나타나는 rope_scaling입니다. 이 글은 그 몇 개의 숫자가 문맥 길이라는 결과로 어떻게 이어지는지를 다룹니다.
수치는 2026-08-12에 논문·공식 리포트·config.json에서 직접 확인했습니다. 모델은 갱신되므로 원본을 다시 확인하세요.
RoPE가 하는 일
RoPE는 쿼리와 키 벡터를 위치에 비례한 각도만큼 회전시킵니다. 두 토큰의 내적이 결국 두 위치의 차이에만 의존하게 되어, 상대적 거리가 자연스럽게 어텐션에 반영됩니다.
핵심은 차원마다 회전 속도가 다르다는 점입니다. 앞쪽 차원은 빠르게 회전해 가까운 거리를 세밀하게 구분하고, 뒤쪽 차원은 아주 느리게 회전해 먼 거리를 구분합니다. 그 속도를 정하는 값이 rope_theta입니다.
rope_theta를 파장으로 읽기
숫자의 의미를 파장으로 바꿔 보면 직관이 생깁니다. 차원 쌍의 파장은 다음과 같이 계산합니다.
파장(i) = 2 x pi x theta^(2i / head_dim)
head_dim = 128 일 때 가장 느린 차원의 파장:
theta = 10,000 -> 54,410 위치
theta = 50,000 -> 265,295 위치
theta = 500,000 -> 2,559,196 위치
theta = 1,000,000 -> 5,063,256 위치
파장이 문맥 길이보다 짧으면 그 차원의 위치 신호가 한 바퀴를 돌아 되감깁니다. 서로 다른 두 위치가 같은 각도를 가리키게 되므로 모델이 둘을 구분하기 어려워집니다. theta를 키우는 것은 이 되감김이 일어나는 지점을 멀리 밀어내는 일입니다.
실제 값은 이렇습니다. Llama 3는 500,000을 씁니다. 리포트는 RoPE 기준 주파수를 500,000으로 올렸고 이것이 더 긴 문맥을 지원하게 해 준다고 밝히면서, 선행 연구가 이 값이 32,768까지의 문맥 길이에 효과적임을 보였다고 인용합니다(arXiv:2407.21783). Qwen3, Qwen2.5, Mixtral, GLM-4.5의 config는 1,000,000입니다.
학습 중에 theta를 바꾸기
Qwen3는 이 값을 처음부터 크게 두지 않고 학습 도중에 올립니다. 리포트에 따르면 마지막 장문맥 단계에서 ABF 기법으로 RoPE 기준 주파수를 10,000에서 1,000,000으로 높입니다(arXiv:2505.09388). 위 표를 기준으로 하면 가장 느린 차원의 파장이 약 93배로 늘어납니다.
순서가 중요합니다. 짧은 문맥에서는 작은 theta가 가까운 거리를 더 촘촘하게 구분해 유리하고, 긴 문맥이 필요해지는 시점에 theta를 올려 먼 거리를 구분할 수 있게 만듭니다. 대부분의 학습을 짧은 문맥에서 값싸게 마치고 마지막에만 비싼 긴 문맥 학습을 하는 구조와 맞물립니다.
흥미로운 예외: 낮은 theta에 YaRN
DeepSeek-V3의 config를 보면 rope_theta가 10,000입니다. 위 표대로면 파장은 5만 수준인데 문맥 길이는 128K를 표방합니다. 답은 같은 config의 rope_scaling 항목에 있습니다.
{
"rope_theta": 10000,
"rope_scaling": {
"type": "yarn",
"factor": 40,
"original_max_position_embeddings": 4096,
"beta_fast": 32,
"beta_slow": 1
}
}
원래 위치 범위 4096에 배율 40을 곱해 확장한다는 뜻입니다. 리포트도 사전학습 후 YaRN을 적용해 각각 1000 스텝의 두 단계를 거쳐 4K에서 32K로, 다시 128K로 창을 넓혔다고 적습니다. 배율은 40, 알파는 1, 베타는 32로 두 단계에서 동일하며, 이 확장은 분리된 공유 키에만 적용한다고 밝힙니다(arXiv:2412.19437).
Kimi K2는 rope_theta 50,000에 YaRN 배율 32입니다. 같은 계열의 설계이지만 기준 주파수를 다섯 배 높게 잡았습니다.
YaRN 논문은 이 방식이 이전 방법 대비 10배 적은 토큰과 2.5배 적은 학습 스텝으로 문맥 창을 확장한다고 보고합니다(arXiv:2309.00071). 확장 자체가 저렴하다는 것이지, 확장된 문맥을 쓰는 비용이 저렴하다는 뜻은 아닙니다.
절반만 회전시키기
GLM-4.5의 config에는 partial_rotary_factor가 0.5로 들어 있습니다. 헤드 차원의 절반에만 회전을 적용하고 나머지 절반은 위치와 무관하게 둔다는 뜻입니다. 위치에 묶이지 않는 성분을 남겨 두는 설계로, 회전 연산량도 함께 줄어듭니다.
MLA를 쓰는 모델에서도 비슷한 분리가 나타납니다. DeepSeek-V3는 qk_nope_head_dim 128과 qk_rope_head_dim 64를 따로 둡니다. 회전을 적용하지 않는 부분과 적용하는 부분을 나눈 것인데, 압축된 잠재 벡터에서 위치 정보를 복원하기 어렵기 때문에 위치 담당 성분만 따로 빼 둔 구조입니다.
긴 컨텍스트는 왜 공짜가 아닌가
rope_scaling을 켜면 숫자상 문맥은 늘어납니다. 그러나 비용은 세 군데에서 발생합니다.
첫째, 프리필 연산입니다. 어텐션 점수 계산은 시퀀스 길이의 제곱에 비례합니다. 문맥을 네 배로 늘리면 이 부분의 연산량은 열여섯 배가 됩니다.
둘째, KV 캐시입니다. 앞 글에서 계산했듯 캐시는 문맥 길이에 선형으로 늘어납니다. Qwen3-8B 기준으로 fp16 캐시는 4,096 토큰에서 0.56 GiB, 32,768 토큰에서 4.50 GiB, 131,072 토큰에서 18.00 GiB입니다. 가중치보다 캐시가 커지는 지점이 옵니다.
셋째, 아키텍처 선택 자체가 문맥 길이에 좌우됩니다. Kimi K2 리포트는 시퀀스 길이 128k에서 어텐션 헤드를 64개에서 128개로 늘리면 추론 연산량이 83퍼센트 증가한다고 적고, 이를 근거로 헤드를 64개로 유지했습니다(arXiv:2507.20534). 긴 문맥을 전제하면 설계 결정이 달라집니다.
그리고 확장 기법이 품질을 보존한다는 보장은 없습니다. 그래서 리포트들이 확장 후 별도의 장문맥 평가를 싣습니다.
단계적으로 늘리기
Llama 3는 확장을 학습으로 처리했습니다. 리포트에 따르면 405B 모델의 사전학습은 초기 사전학습, 장문맥 사전학습, 어닐링의 세 단계로 이루어지며, 문맥 길이는 원래의 8K에서 최종 128K까지 여섯 단계에 걸쳐 점진적으로 늘렸고 이 장문맥 단계에 약 8000억 토큰을 썼습니다.
즉 긴 문맥을 얻는 길은 크게 두 갈래입니다. 학습으로 늘리거나, 확장 기법으로 늘리거나. 전자는 비싸고 후자는 값싸지만 검증이 더 필요합니다.
마치며
rope_theta를 볼 때는 파장으로 환산해 보세요. 그 값이 문맥 길이보다 충분히 큰지가 첫 번째 점검입니다. rope_scaling이 있다면 그 모델의 문맥 길이는 학습된 값이 아니라 확장된 값입니다. 그리고 문맥을 늘릴 때는 프리필 연산과 캐시 메모리가 함께 늘어난다는 사실을 계산에 넣어야 합니다.
참고 자료
- The Llama 3 Herd of Models (arXiv:2407.21783): https://arxiv.org/abs/2407.21783
- Qwen3 Technical Report (arXiv:2505.09388): https://arxiv.org/abs/2505.09388
- DeepSeek-V3 Technical Report (arXiv:2412.19437): https://arxiv.org/abs/2412.19437
- YaRN (arXiv:2309.00071): https://arxiv.org/abs/2309.00071
- Kimi K2 (arXiv:2507.20534): https://arxiv.org/abs/2507.20534
- GLM-4.5 config.json: https://huggingface.co/zai-org/GLM-4.5/raw/main/config.json
직접 해보기
- VRAM 계산기 — 문맥 길이를 늘렸을 때 메모리가 어떻게 변하는지 확인해 보세요.
- 신경망 아키텍처 탐색기 — 헤드 차원과 층 구성을 바꿔 보세요.
- 뉴럴넷 실습실 — 작은 모델로 위치 정보의 역할을 실험해 보세요.
시리즈
- 이전 글: 어텐션 변형 — MHA에서 MLA까지
- 다음 글: 정규화와 활성화 — 학습을 무너뜨리지 않는 법
Positional Encoding — RoPE and the Price of Context Extension
- Introduction
- What RoPE Does
- Reading rope_theta as a Wavelength
- Changing theta During Training
- An Interesting Exception: Low theta With YaRN
- Rotating Only Half
- Why Long Context Is Not Free
- Growing It in Stages
- Closing
- References
- Try It Yourself
- Series
Introduction
Transformer attention has no sense of order on its own. Positional encoding is the mechanism that supplies token order, and virtually every open-source model shipping today uses RoPE, rotary position embeddings.
In the config there are only two or three related fields: rope_theta, max_position_embeddings, and, when present, rope_scaling. This post is about how those few numbers lead to the outcome we call context length.
All figures were verified directly against papers, official reports, and config.json files on 2026-08-12. Models get updated, so check the originals again.
What RoPE Does
RoPE rotates the query and key vectors by an angle proportional to position. The dot product of two tokens then depends only on the difference between their positions, so relative distance enters attention naturally.
The key point is that each dimension rotates at a different speed. Early dimensions rotate quickly and resolve short distances finely, while later dimensions rotate very slowly and distinguish long distances. The value that sets those speeds is rope_theta.
Reading rope_theta as a Wavelength
Converting the number into a wavelength builds intuition. The wavelength of a dimension pair is computed like this.
wavelength(i) = 2 x pi x theta^(2i / head_dim)
With head_dim = 128, the wavelength of the slowest dimension:
theta = 10,000 -> 54,410 positions
theta = 50,000 -> 265,295 positions
theta = 500,000 -> 2,559,196 positions
theta = 1,000,000 -> 5,063,256 positions
If a wavelength is shorter than the context length, that dimension's positional signal wraps around. Two different positions end up pointing at the same angle, making them hard for the model to tell apart. Raising theta pushes the point where this wrapping happens further out.
Here are the real values. Llama 3 uses 500,000. The report states that the RoPE base frequency hyperparameter was increased to 500,000 to better support longer contexts, citing prior work showing this value effective for context lengths up to 32,768 (arXiv:2407.21783). The configs of Qwen3, Qwen2.5, Mixtral, and GLM-4.5 all use 1,000,000.
Changing theta During Training
Qwen3 does not set this value high from the start but raises it mid-training. According to the report, in the final long-context stage the RoPE base frequency is increased from 10,000 to 1,000,000 using the ABF technique (arXiv:2505.09388). By the table above, that stretches the slowest dimension's wavelength by roughly 93 times.
The ordering matters. At short context a smaller theta resolves nearby distances more finely, and theta is raised only when long context becomes necessary, enabling long-distance discrimination. This dovetails with a structure where most training happens cheaply at short context and only the final stage pays for expensive long-context training.
An Interesting Exception: Low theta With YaRN
Look at the DeepSeek-V3 config and rope_theta is 10,000. By the table above that gives a wavelength around fifty thousand, yet the model advertises a 128K context. The answer is in the rope_scaling entry of the same config.
{
"rope_theta": 10000,
"rope_scaling": {
"type": "yarn",
"factor": 40,
"original_max_position_embeddings": 4096,
"beta_fast": 32,
"beta_slow": 1
}
}
This means the original positional range of 4096 is extended by a factor of 40. The report likewise states that after pre-training, YaRN was applied through two phases of 1000 steps each, widening the window from 4K to 32K and then to 128K. The scale is 40, alpha is 1, and beta is 32, identical across both phases, and the extension is applied exclusively to the decoupled shared key (arXiv:2412.19437).
Kimi K2 pairs a rope_theta of 50,000 with a YaRN factor of 32. The same family of design, but with a base frequency set five times higher.
The YaRN paper reports that the method extends the context window with 10x fewer tokens and 2.5x fewer training steps than previous methods (arXiv:2309.00071). That says the extension itself is cheap, not that using the extended context is cheap.
Rotating Only Half
The GLM-4.5 config carries partial_rotary_factor set to 0.5. This means rotation is applied to only half the head dimensions while the other half is left position-independent. It is a design that keeps some components untied to position, and it reduces rotation compute along the way.
A similar split appears in models using MLA. DeepSeek-V3 keeps qk_nope_head_dim 128 and qk_rope_head_dim 64 separately. This divides the portion that receives no rotation from the portion that does, a structure that exists because positional information is hard to recover from a compressed latent vector, so the position-carrying component is pulled out and handled on its own.
Why Long Context Is Not Free
Switch on rope_scaling and the context grows on paper. But cost appears in three places.
First, prefill compute. Attention score computation scales with the square of sequence length. Quadruple the context and this portion becomes sixteen times the work.
Second, the KV cache. As computed in the previous post, the cache grows linearly with context length. For Qwen3-8B the fp16 cache is 0.56 GiB at 4,096 tokens, 4.50 GiB at 32,768 tokens, and 18.00 GiB at 131,072 tokens. There comes a point where the cache outweighs the weights.
Third, architectural choices themselves hinge on context length. The Kimi K2 report states that at a sequence length of 128k, raising attention heads from 64 to 128 increases inference FLOPs by 83 percent, and on that basis the model keeps 64 heads (arXiv:2507.20534). Presuming long context changes the design decisions.
And there is no guarantee that extension techniques preserve quality, which is why reports include separate long-context evaluations after extending.
Growing It in Stages
Llama 3 handled extension through training. According to the report, pre-training of the 405B model consists of three stages — initial pre-training, long-context pre-training, and annealing — and the context length was increased gradually in six stages from the original 8K to a final 128K, with roughly 800B tokens spent in that long-context stage.
So there are broadly two roads to long context: grow it by training, or grow it by an extension technique. The former is expensive, the latter cheap but in greater need of verification.
Closing
When you look at rope_theta, convert it into a wavelength. Whether that value is comfortably larger than the context length is the first check. If rope_scaling is present, that model's context length is an extended value rather than a trained one. And when extending context, remember to put prefill compute and cache memory into the same calculation.
References
- The Llama 3 Herd of Models (arXiv:2407.21783): https://arxiv.org/abs/2407.21783
- Qwen3 Technical Report (arXiv:2505.09388): https://arxiv.org/abs/2505.09388
- DeepSeek-V3 Technical Report (arXiv:2412.19437): https://arxiv.org/abs/2412.19437
- YaRN (arXiv:2309.00071): https://arxiv.org/abs/2309.00071
- Kimi K2 (arXiv:2507.20534): https://arxiv.org/abs/2507.20534
- GLM-4.5 config.json: https://huggingface.co/zai-org/GLM-4.5/raw/main/config.json
Try It Yourself
- VRAM calculator — see how memory changes as you raise context length.
- Neural network architecture explorer — vary head dimension and layer configuration.
- Neural net lab — experiment with the role of positional information on a small model.