사내 모델을 직접 학습하거나 오픈 모델을 긴 문서로 지속학습하려고 할 때, rope_theta를 그대로 둘지 얼마로 올릴지, 장문 학습에 토큰과 GPU가 얼마나 드는지부터 막히죠. 결론부터 말하면 목표 길이에 맞는 base 하한(32K면 약 6.4×10⁵, 128K면 약 7.8×10⁶)보다 크게 잡고, 대부분은 짧은 길이로 학습하다 마지막에 길이를 늘리는 게 가장 싸요. base가 하한보다 작으면 perplexity는 멀쩡해도 긴 문서에서 정보를 못 찾는 모델이 나와요.
이 글은 학습 쪽 결정만 다뤄요. 이미 학습된 모델에 추론 설정(rope_scaling, YaRN factor)만 바꿔 길이를 늘리는 경우는 LLM 컨텍스트 길이 늘리기, YaRN·rope_scaling 설정별 비용에 정리해 뒀어요. 여기서는 base 값을 고르는 기준, 토큰당 학습 연산, 지속학습 예산별 비용, 짧은 입력 손실, 점검표 순서로 가요.
위치 인코딩부터 고를 때, RoPE를 쓰는 이유와 대안
새 모델을 설계한다면 위치 인코딩 선택지는 사실상 셋이에요. 대부분의 공개 LLM이 쓰는 RoPE, 어텐션 점수에 거리 비례 감점을 더하는 ALiBi, 그리고 입력에 더하는 절대 위치 임베딩이에요.
| 방식 | 길이를 늘릴 때 | 생태계 지원 | 고르면 좋은 경우 |
|---|---|---|---|
| RoPE | base 조정·보간·지속학습 필요 | vLLM·llama.cpp·transformers 기본 | 기존 체크포인트 이어 쓰기, 범용 |
| ALiBi | 학습 길이보다 긴 입력도 바로 받도록 설계 | 일부 모델만 | 짧게 학습하고 조금 더 긴 입력 처리 |
| 학습형 절대 위치 | 표 밖 위치는 표현 못 함 | 오래된 모델 | 새로 고를 이유가 적어요 |
ALiBi 논문(Press 외)은 1.3B 모델을 1,024 길이로 학습해 2,048에서 사인 위치 인코딩을 2,048로 학습한 모델과 같은 perplexity를 내면서 학습은 11% 빠르고 메모리는 11% 적었다고 보고해요. 대신 공개 체크포인트·서빙 최적화·컨텍스트 확장 연구가 RoPE 쪽에 몰려 있어서, 기존 모델을 이어 학습하거나 범용 서빙 스택에 올릴 계획이면 RoPE가 무난해요. RoPE의 수식은 RoFormer 논문에 있고, 아래부터는 RoPE를 고른 뒤의 결정이에요.
rope_theta 하한, 목표 길이별로 얼마나 커야 하나
rope_theta(base)는 차원 쌍마다 도는 속도를 정해요. base가 클수록 느린 쌍이 더 느리게 돌아 먼 위치까지 구분할 여유가 생겨요. Men 외(2024) "Base of RoPE Bounds Context Length"는 비슷한 토큰에 무작위 토큰보다 더 큰 어텐션을 줄 수 있는 능력을 B(m) = Σcos(m·θᵢ)로 두고, 목표 길이 L까지 이 값이 0 아래로 내려가지 않는 최소 base를 수치로 구했어요.
| 목표 길이 | 4K | 8K | 16K | 32K | 64K | 128K | 256K | 1M |
|---|---|---|---|---|---|---|---|---|
| base 하한 | 2.7×10⁴ | 8.4×10⁴ | 3.1×10⁵ | 6.4×10⁵ | 2.1×10⁶ | 7.8×10⁶ | 3.6×10⁷ | 5.1×10⁸ |
길이가 두 배가 될 때마다 하한은 대략 3~4배씩 커져요. 논문은 층을 쌓으면 한 층의 범위보다 넓게 정보를 모을 수 있어 이 경계가 엄밀하지는 않다고 적으면서도, Llama 2 7B를 32K로 미세조정한 실험에서 하한보다 작은 base는 Long-eval 정답률이 뚜렷하게 떨어졌다고 보고해요.
공개 모델의 실제 값을 이 표와 맞춰 보면 이래요. config 값은 각 모델 저장소의 config.json에서 확인했어요.
| 모델 | rope_theta | 기준 길이 | 그 길이의 하한 | 비교 |
|---|---|---|---|---|
| Llama 2 7B | 10,000 (기본값) | 4,096 | 27,000 | 하한보다 작음 |
| Code Llama 7B | 1,000,000 | 16,384 | 310,000 | 약 3배 여유 |
| Llama 3.1 8B | 500,000 | 8,192 (스케일링 전) | 84,000 | 약 6배 여유 |
| Qwen2.5-7B | 1,000,000 | 32,768 | 640,000 | 약 1.6배 여유 |
| Qwen3-8B | 1,000,000 | 32,768 (모델 카드) | 640,000 | 약 1.6배 여유 |
Code Llama 논문은 장문 미세조정에서 base를 10,000에서 1,000,000으로 바꾸고 16,384 길이로 학습했고, Code Llama 7B config.json에도 그 값이 들어 있어요. Llama 2 Long 논문(Xiong 외)은 base를 500,000으로 올리는 방식(ABF)을 썼고, Llama 3 논문은 이 값이 32,768까지 효과적이었다는 근거로 처음부터 500,000을 썼다고 적어요. Qwen3-8B 모델 카드는 원래 길이를 32,768로 밝혀요.
토큰 하나 학습하는 데 드는 연산, 길이에 따라 얼마나 느나
base를 정했으면 비용이에요. 학습 연산은 토큰당 6 × 행렬 곱 파라미터 수에 인과 마스크 어텐션 6 × 층 수 × 길이 × 어텐션 폭을 더해 어림해요(순전파 1 + 역전파 2). Llama 3.1 8B config(32층, 어텐션 폭 4,096, 행렬 곱 파라미터 약 75억 개)로 직접 계산했어요.
4K 대비 32K는 1.47배, 128K는 3.07배예요. 64K부터 어텐션이 행렬 곱보다 커져요.
표로 보기
| 구분 | 행렬 곱 | 어텐션 |
|---|---|---|
| 4K | 45 | 3.2 |
| 8K | 45 | 6.4 |
| 16K | 45 | 12.9 |
| 32K | 45 | 25.8 |
| 64K | 45 | 51.5 |
| 128K | 45 | 103 |
같은 토큰 수라도 32K로 학습하면 4K보다 약 47%, 128K면 약 3배 비싸요. 실제로는 긴 길이에서 GPU 활용률(MFU)도 떨어지기 쉬워 차이가 더 벌어질 수 있어요. Llama 2 Long 논문은 FlashAttention을 써서 70B 모델의 길이를 4,096에서 16,384로 늘렸을 때 속도가 약 17% 떨어졌다고 적었어요. 어텐션 구현에 따른 메모리와 속도 차이는 어텐션 구현 고르기, SDPA·FlashAttention 비교에 있어요.
Llama 3 논문이 긴 시퀀스 학습을 사전학습 마지막에만 한 이유도 이거예요. 셀프 어텐션 연산이 길이 제곱으로 늘기 때문이라고 밝히고, 405B 모델을 8K에서 128K까지 여섯 단계로 늘리며 약 800B 토큰을 썼어요. 각 단계는 짧은 입력 평가 점수가 완전히 회복되고 그 길이까지 바늘 찾기를 다 맞힐 때 넘어갔어요.
장문 지속학습 예산별 GPU 비용 계산
논문들이 쓴 장문 학습 토큰 수를 같은 8B 구조에 넣어 비용을 비교했어요. H100 SXM의 BF16 성능은 NVIDIA H100 제품 페이지에 희소성 포함 1,979 TFLOPS로 나와 있어 밀집 연산은 그 절반인 약 989.5 TFLOPS로 잡았고, MFU 40%를 가정했어요. 단가는 Lambda 가격표의 H100 SXM 8장 인스턴스 GPU당 시간당 3.99달러(2026-10-30 확인, 세금 별도)예요.
토큰 수의 근거는 이래요. Code Llama는 배치 200만 토큰으로 기본 10,000스텝을 학습했고, 불안정했던 7B는 3,000스텝(약 6B 토큰)으로 줄였어요. Llama 2 Long은 Llama 2 체크포인트를 400B 토큰, 100,000스텝 지속학습했고, 위치 인코딩 비교 실험은 32,768 길이로 80B 토큰씩 썼어요. YaRN은 64K 조각, 배치 64로 400스텝이라 약 1.7B 토큰이에요.
양 끝의 차이가 약 170배예요. 도메인 하나를 16K로 늘리는 정도면 수천 달러 안쪽이고, 범용 장문 능력은 수만 달러 단위예요. 미세조정 방식(LoRA 등)으로 줄일 수 있는 메모리 쪽 비용은 LoRA 파인튜닝 메모리와 비용 계산을 참고하세요.
처음부터 길게 vs 짧게 학습 후 늘리기, 커리큘럼 비교
새 모델을 처음부터 사전학습한다면 언제 길이를 늘릴지가 비용을 크게 바꿔요. Llama 2 Long 논문은 7B 모델을 같은 총 토큰 수, 같은 배치당 토큰 수(400만)로 두고 학습 커리큘럼만 바꿔 비교했어요.
같은 표의 장문 QA 점수예요.
| 커리큘럼 | NarrativeQA F1 | Qasper F1 | QuALITY EM | QMSum ROUGE |
|---|---|---|---|---|
| 처음부터 32K | 18.5 | 28.6 | 37.9 | 11.46 |
| 4K → 32K (20%) | 20.0 | 28.1 | 38.8 | 12.09 |
| 4K → 32K (40%) | 20.1 | 27.0 | 37.4 | 12.44 |
| 4K → 32K (80%) | 18.5 | 25.0 | 38.3 | 11.00 |
논문은 짧은 모델에서 이어 학습해 약 40% 연산을 아끼면서 성능 손실이 거의 없다고 결론 냈어요. 다만 표를 보면 80% 전환은 Qasper가 28.6에서 25.0으로 떨어졌어요. 20% 전환은 연산이 10%만 줄지만 네 과제 중 셋이 처음부터 32K보다 높았고, 40% 전환은 연산 20%를 줄이면서 둘이 높고 둘이 낮았어요. 장문 품질이 중요할수록 전환을 앞당기는 쪽으로 잡으면 돼요. 같은 논문은 길이보다 데이터 품질이 더 중요했다고도 적어요.
짧은 입력 품질 손실, 얼마나 감수해야 하나
장문 학습은 공짜가 아니에요. Code Llama 논문은 장문 미세조정 뒤 HumanEval pass@1이 평균 0.52%p, MBPP가 1.9점 떨어졌고, 4K보다 짧은 프롬프트의 코드 완성에서 BLEU가 최대 2점 낮아졌다고 보고해요. 그래도 100K 토큰 입력까지 개선을 보였기 때문에 장문 미세조정한 모델을 공개했어요.
그래서 지속학습을 할 땐 두 가지를 같이 해요. 첫째, 장문 데이터만 넣지 말고 기존 길이의 데이터를 섞어요. 둘째, 학습 전후로 기존 짧은 평가 세트를 같은 조건으로 돌려 차이를 기록해요. Llama 3가 단계를 넘어가는 조건으로 "짧은 입력 평가 점수의 완전한 회복"을 둔 것도 같은 이유예요.
직접 해 보기, config로 base와 비용 한 번에 점검
아래 스크립트는 config.json을 읽어 목표 길이의 base 하한을 통과하는지와 장문 지속학습 비용을 어림해요. 숫자 기준은 위 표와 같고, 단가·MFU는 인자로 바꿔 쓰면 돼요.
import json, sys
# Men 외(2024) 표 2: 목표 길이별 RoPE base 하한
BOUND = {4096: 2.7e4, 8192: 8.4e4, 16384: 3.1e5, 32768: 6.4e5,
65536: 2.1e6, 131072: 7.8e6}
def plan(path, target, tokens, gpu_price=3.99, mfu=0.40, peak=989.5e12):
c = json.load(open(path))
theta = c.get("rope_theta") or 10000.0 # 빈 칸이면 transformers 기본값
rs = c.get("rope_scaling") or {}
L, h = c["num_hidden_layers"], c["hidden_size"]
hd = c.get("head_dim") or h // c["num_attention_heads"]
kv = c["num_key_value_heads"]
per_layer = h * c["num_attention_heads"] * hd * 2 + h * kv * hd * 2 \
+ 3 * h * c["intermediate_size"]
n = L * per_layer + c["vocab_size"] * h # 행렬 곱 파라미터(입력 임베딩 제외)
attn_w = c["num_attention_heads"] * hd
flops = tokens * (6 * n + 6 * L * target * attn_w)
gpu_h = flops / (peak * mfu) / 3600
need = BOUND[target]
print(f"[{path}] rope_theta={theta:.0e} scaling={rs.get('rope_type', '없음')}")
if rs:
verdict = "이미 스케일링이 있어 표와 바로 비교하지 않음"
else:
verdict = "통과" if theta >= need else f"부족, {need:.1e} 이상으로"
print(f" {target:,} 목표 하한 {need:.1e} → {verdict}")
print(f" {tokens / 1e9:.0f}B 토큰 학습: H100 {gpu_h:,.0f}시간, 약 ${gpu_h * gpu_price:,.0f}")
target, tokens = int(sys.argv[1]), float(sys.argv[2])
for p in sys.argv[3:]:
plan(p, target, tokens)
네 모델의 config.json을 받아 python3 theta_plan.py 32768 10e9 *.json(32K 목표, 10B 토큰)으로 돌린 결과예요.
[llama-2-7b-hf.json] rope_theta=1e+04 scaling=없음
32,768 목표 하한 6.4e+05 → 부족, 6.4e+05 이상으로
10B 토큰 학습: H100 459시간, 약 $1,832
[codellama-7b-hf.json] rope_theta=1e+06 scaling=없음
32,768 목표 하한 6.4e+05 → 통과
10B 토큰 학습: H100 459시간, 약 $1,832
[meta-llama-3.1-8b.json] rope_theta=5e+05 scaling=llama3
32,768 목표 하한 6.4e+05 → 이미 스케일링이 있어 표와 바로 비교하지 않음
10B 토큰 학습: H100 497시간, 약 $1,983
[qwen2.5-7b-instruct.json] rope_theta=1e+06 scaling=없음
32,768 목표 하한 6.4e+05 → 통과
10B 토큰 학습: H100 436시간, 약 $1,740
Llama 3.1처럼 rope_scaling이 이미 들어간 모델은 주파수가 base만으로 정해지지 않아 표와 바로 비교하지 않아요. Llama 2를 32K로 늘리려면 Code Llama·Llama 2 Long처럼 base부터 바꾸고 학습해야 해요.
상황별 추천과 도입 체크리스트
| 상황 | 추천 | 근거 |
|---|---|---|
| 새 모델, 목표 8K 이하 | base 8.4×10⁴ 이상, 끝까지 짧게 | 8K 하한, Llama 3는 5×10⁵ |
| 새 모델, 최종 32K~128K | 처음부터 목표 하한 이상 base, 학습 후반에 길이 단계적 증가 | Llama 3가 500,000으로 시작해 마지막에 6단계 확장 |
| 기존 4K 모델을 16K~32K로 | base를 10⁶ 근처로 올리고 수십억 토큰 지속학습 | Code Llama 6B~20B 토큰, 약 1천~3천 달러 |
| 범용 장문 능력이 필요 | 직접 하기보다 장문 학습된 모델로 교체 | 400B 토큰이면 약 7.9만 달러 |
| 장문 데이터가 적음 | 학습 대신 RAG나 추론 설정 | 데이터 품질이 길이보다 중요 |
- 목표 길이를 실제 요청의 p95로 정해요. 하한이 길이 두 배마다 3~4배 커지니 필요 이상으로 잡으면 짧은 쪽 손해만 커져요.
- base를 하한 이상으로 바꾸고 config와 학습 코드 둘 다 반영해요. 서빙 config에 옛 값이 남으면 학습한 각도와 다른 각도로 추론해요.
- 회전 쌍 배치 방식을 맞춰요. 인접한 두 원소를 묶는 구현과 앞뒤 절반을 묶는 구현(
rotate_half)이 다르면, 가중치를 옮길 때W_q·W_k행 재배치가 필요해요. 빠뜨리면 오류 없이 출력만 망가져요. - 배치당 토큰 수를 유지해요. 길이를 늘리면 시퀀스 수를 줄여 맞춰요. Llama 2 Long과 커리큘럼 실험이 모두 이렇게 했어요.
- 짧은 입력 회귀, 위치별 바늘 찾기, 비슷한 문장 속 검색을 같이 재요. 한 가지만 보면 "겉으로만 긴" 모델을 놓쳐요.
자주 묻는 질문
rope_theta는 클수록 좋은가요?
하한은 최소 조건이지 최적값이 아니에요. 위 표에서 Llama 2를 뺀 공개 모델들은 기준 길이 하한의 약 1.6~6배를 썼어요. base는 나중에 바꾸면 다시 학습해야 하니, 처음 정할 때 하한을 넘기는 후보 몇 개를 작은 규모로 학습해 장문 검색 정답률로 비교하는 게 안전해요.
학습된 모델의 rope_theta만 바꿔도 길이가 늘어나나요?
학습 없이 base만 바꾸면 모든 쌍의 각도가 학습 때와 달라져요. Code Llama와 Llama 2 Long 모두 base를 바꾼 뒤 수십억~수백억 토큰을 학습했어요. 학습 없이 늘리고 싶다면 base를 손대기보다 모델 카드가 검증한 rope_scaling 설정을 쓰는 편이 나아요.
perplexity가 낮게 나오면 장문 학습이 된 건가요?
아니에요. Men 외 논문에서 base 500으로 학습한 모델은 128K에서도 perplexity가 낮았지만 1K 길이에서조차 정보를 찾지 못했어요. 32K 미세조정에서도 base 2×10⁵가 perplexity는 가장 좋았지만 Long-eval 정답률은 매우 낮았어요. 바늘 찾기와 비슷한 문장 속 검색을 함께 재세요.
장문 지속학습 토큰은 얼마나 잡아야 하나요?
공개 사례는 YaRN 약 1.7B부터 Llama 3 405B 약 800B 토큰까지 넓어요. 도메인 하나를 16K~32K로 늘리는 정도면 수십억 토큰에서 시작해 평가를 보며 늘리는 게 현실적이에요.
장문 학습을 하면 짧은 입력 성능이 꼭 떨어지나요?
떨어질 수 있어요. Code Llama는 장문 미세조정 뒤 HumanEval이 평균 0.52%p, MBPP가 1.9점 낮아졌어요. 기존 길이 데이터를 섞고, 학습 전후로 같은 평가 세트를 돌려 손실이 허용 범위인지 확인하세요.
정리
- base 하한은 32K에 6.4×10⁵, 128K에 7.8×10⁶이에요. 목표 길이를 먼저 정하고 그보다 큰
rope_theta로 학습하세요. - 8B 구조에서 토큰당 학습 연산은 32K가 4K의 1.47배, 128K가 3.07배예요. 긴 길이 학습은 마지막 단계에 몰아서 하세요.
- 지속학습 비용은 6B 토큰(16K) 약 1천 달러에서 400B 토큰(32K) 약 7.9만 달러까지 벌어져요. 범용 장문이 필요하면 장문 학습된 모델로 바꾸는 쪽이 싸요.
- 학습이 끝나면 짧은 입력 회귀와 위치별 검색 정답률을 같이 재고, 서빙 설정은 rope_scaling 설정별 비용 글의 점검 순서대로 반영하세요.
더 깊이 읽기
이 글은 실무에서 판단할 때 필요한 것 위주로 정리했어요. 같은 주제의 내부 동작 원리는 devboi 기술 블로그의 RoPE 원리 — 위치 인코딩과 PI·YaRN 컨텍스트 확장에서 도식과 코드로 단계별로 풀었어요.