사람은 쉬운 것부터 배웁니다. 언어모델도 그럴까요. 이 질문 하나를 확인하려고 110M 파라미터 GPT를 스크래치부터 여덟 번 사전학습했습니다.
결론부터 적습니다. 이 스케일(110M, 2.5B 토큰)에서 난이도 커리큘럼은 무작위 순서를 이기지 못했습니다. 최종 val loss도 학습 속도도 무작위가 앞섰고, 손해가 어디서 나는지는 난이도 밴드별 loss를 따로 뜯어보고서야 알았습니다. 학습률(LR) 스케줄과 교락된 것 아닌가 싶어 4런을 더 돌렸는데, 격차는 사라지기는커녕 약 40% 커졌습니다.
연구 질문
한국어 언어모델 사전학습에서 데이터 순서(난이도 커리큘럼)는 학습 속도(목표 loss 도달 토큰 수)와 최종 성능(한국어 문법성·자연스러움)에 영향을 주는가. 그리고 사람이 설계한 "쉬움 중심
- 다음 난이도 미리보기" 커리큘럼은 완전 자동 정렬과 어떻게 다른가.
두 번째 질문이 개인적으로는 더 궁금했습니다. 난이도순으로 그냥 줄 세우는 것과, 사람이 교재를 짜듯 다음 단계를 조금씩 섞어 주는 것은 다를 것 같았거든요.
실험 설계 — 바꾼 것은 순서
조건은 넷입니다.
random— 전체 셔플. 기준선입니다.length— 문장 길이 오름차순(10분위 버킷, 버킷 내 셔플).difficulty— 복합 난이도 오름차순.mixed— 스테이지 진행 + 다음 밴드 10–15% 미리보기. 최고난도 10% 청크를 난이도 하위 75% 구간의 청크로 교체했고, 총 토큰은 같습니다.
random·length·difficulty 사이의 차이는 순수한 순서 효과이지만, mixed만은 코퍼스 자체가
C′로 바뀌므로 사람이 설계한 데이터 선택 + 순서 효과로 읽어야 합니다.
통제 항목은 총 학습 토큰 2,500,000,000개(경계 청크를 슬라이스해 토큰 단위로 정확히 일치), 청크 노출 횟수 1회(단일 에포크), 모델·토크나이저·하이퍼파라미터·평가 시점입니다. 순서는 학습 전에 파일로 고정(materialize)하고 불변식(동일 multiset, 총량 일치, 노출 1회)을 자동 검증했습니다. 같은 시드의 런은 모델 초기 가중치가 완전히 동일해서(테스트로 보증), 조건 간 비교가 paired comparison이 됩니다.
모델은 Llama 레시피(RMSNorm·RoPE·SwiGLU·no-bias decoder-only)를 110M로 축소한 12L·768d·12H,
ctx 1024입니다. 데이터는 FineWeb2 kor_Hang 76.6% + 국립국어원 모두의 말뭉치 15.0% + 한국어
위키백과 8.4%로, 자체 BPE 32k 기준 29.4억 토큰 풀입니다. 난이도는 kiwipiepy 형태소 분석으로
문장당 형태소 수·희귀 형태소 비율·어절당 형태소 수·조사/어미 타입 다양성·연결/전성어미 수
다섯 피처를 z-score 균등 가중합해 정의했고, 십분위 표본을 눈으로 확인했을 때 하위는 짧은
문답·단순 서술, 중위는 표준 신문 기사, 상위는 길고 밀도 높은 분석문으로 갈려서 직관과
맞았습니다. RTX 4090 한 장으로 런당 약 7.8시간, 8런 전체 학습·평가 비용은 약 $55–60이었습니다.
결과 — 무작위가 이겼습니다

| 조건 | 최종 val loss | 목표 loss(3.645) 도달 | 최종 BPC |
|---|---|---|---|
| random | 3.505 | 1.38B tokens | 2.304 |
| mixed | 3.582 | 1.66B | 2.369 |
| difficulty | 3.632 | 1.81B | 2.470 |
| length | 3.645 | 1.99B | 2.414 |
random은 어느 공통 loss 수준이든 커리큘럼보다 30–45% 적은 토큰으로 도달했습니다. 서열
(random > mixed > difficulty ≈ length)은 모든 중간 체크포인트에서 유지됐고, length는 학습
막바지에 val loss가 소폭 상승하기까지 했습니다(2.0B 3.643 → 2.5B 3.645). BPC를 같이 적어
둔 건 토크나이저가 다른 모델과도 비교할 수 있는 형태이기 때문인데, 여기서는 difficulty와
length의 순서가 val loss와 뒤바뀝니다. 리포트도 이 둘은 ≈로 묶어 씁니다.

가설은 "커리큘럼이 초반 학습을 빠르게 만들 것"이었는데, 초반부터 끝까지 한 번도 앞선 구간이 없었습니다.
손해가 어디서 나는가 — 난이도 밴드 분해
전체 loss만 보면 "졌다"까지가 끝입니다. validation을 난이도 밴드로 쪼개고 나서야 그림이 바뀌었습니다.

difficulty와 random의 격차를 밴드별로 나누면 easy +0.262, mid +0.080, hard +0.017로
극단적으로 비대칭입니다. 커리큘럼 모델은 어려운 텍스트에서는 random과 동급인데,
초반에만 보고 다시 보지 않은 쉬운 텍스트를 잊었습니다. easy 밴드 곡선에서 커리큘럼 런들은
1.2B 토큰 이후 하강을 멈추고 되레 올라가는 반면, random은 끝까지 내려갑니다.
이 프레임에서 세 커리큘럼의 서열도 설명됩니다. 혼합이 많을수록 덜 잊습니다. 다음 밴드를
10–15% 미리 보여준 mixed는 easy 밴드 손해가 difficulty의 61% 수준(+0.160)이었습니다.
사람이 설계한 혼합이 완전 정렬의 부작용을 절반쯤 완화한 셈인데, 설계 의도대로 동작했지만
random을 넘지는 못했습니다.
이 분해가 이 실험에서 제일 마음에 드는 부분입니다. 전체 loss만 봤다면 "졌다"에서 멈췄을 텐데, 손해가 easy 밴드에 몰려 있다는 사실은 밴드 분해에서만 나옵니다.
"LR 스케줄 때문 아닌가?"
여기서 한동안 막혔습니다. cosine 스케줄에서는 커리큘럼 후반 데이터(=어려운 것)가 항상 낮은 LR로 학습되니까, 지금 보고 있는 게 순서 효과가 아니라 LR 상호작용일 수 있습니다. 그럴듯한 반박이었고, 이게 맞으면 순서 효과라는 결론 자체가 성립하지 않습니다.
원래 계획은 3시드 12런이었는데, 시드를 반복하는 대신 동일 시드·동일 순서로 LR만 3e-4 상수로 고정한 4런을 추가하는 쪽으로 계획을 바꿨습니다. 발견이 실험 계획을 바꾼 셈입니다.

| random 대비 격차 | cosine | 고정 LR |
|---|---|---|
| length Δval | +0.140 | +0.176 |
| difficulty Δval | +0.127 | +0.176 |
| mixed Δval | +0.077 | +0.101 |
| difficulty Δeasy | +0.262 | +0.369 |
| difficulty Δhard | +0.017 | −0.003 |
LR을 고정하자 커리큘럼의 손해는 사라지기는커녕 약 40% 커졌습니다. easy 밴드에서는 커리큘럼 곡선이 명백한 상승 추세를 보였고(difficulty: 1.0B 지점 3.80 → 2.5B 지점 3.92), 반대로 hard 밴드에서는 커리큘럼이 random을 처음으로 근소하게 앞섰습니다. recency 이득의 순수한 형태입니다.
그러니까 커리큘럼의 손해는 LR 아티팩트가 아니라 재방문 없는 순서 그 자체, 즉 망각이었고, cosine의 LR 감쇠는 교락 요인이 아니라 오히려 후반 데이터가 초반 지식을 덮어쓰는 것을 줄여 커리큘럼을 보호하고 있었습니다. 서열은 두 스케줄에서 동일하게 재현됐습니다.
loss 차이가 실제 생성물에서도 보이는가
loss는 결국 대리 지표입니다. random과 difficulty의 val loss 격차는 +0.127인데, 이게 사람이 읽는 문장에서 보이지 않으면 의미가 없습니다. 그래서 최종 체크포인트의 생성물을 직접 채점했습니다.
고정 프롬프트 20개의 최종 체크포인트 생성(T=0.8)을 random vs 각 커리큘럼 60쌍으로 묶고, 조건 라벨을 제거한 뒤 A/B 순서를 시드 셔플해 독립 LLM 심사자 2명(조건 매핑 비접근, 한 명은 B→A 역순 검토로 위치 편향 완화)에게 문법·결속성·반복 여부 기준의 상대 판정을 받았습니다.
| 대결 | 심사자 1 | 심사자 2 | 합의 건만 |
|---|---|---|---|
| random vs difficulty | 14–6 | 16–4 | 12–2 |
| random vs length | 12–8 | 13–7 | 10–5 |
| random vs mixed | 11–9 | 12–8 | 9–6 |
심사자 간 일치율은 73%였습니다. 방향은 loss와 같습니다. random의 생성이 가장 자연스럽고, 격차는 difficulty에서 가장 크며, mixed가 커리큘럼 중 가장 근접합니다.
다만 유의성이 보고된 것은 difficulty 대결 하나뿐입니다. 합의 건 기준 12–2로 이항검정 p≈0.006이고, mixed(9–6)는 유의하지 않습니다. length(10–5)에 대해서는 유의성 판정이 따로 보고돼 있지 않습니다. 즉 이 채점은 4조건 서열 전체를 지탱하지 못하고, 가장 큰 격차 하나를 생성물 수준에서 확인해 주는 역할입니다. 프롬프트 20개, 심사자 2명, 최종 체크포인트 1회라는 규모도 그대로 한계로 남습니다.
공통 관찰도 적어 둡니다. 모든 조건이 조사·어미가 정확한 유창한 문장을 만들고, greedy에서는 반복 루프에 빠집니다(이 스케일의 전형). 차이는 주로 문장 간 결속성과 붕괴 빈도에서 납니다.
한국어 LM인데 왜 한국어 벤치마크가 결론이 아닌가
당연히 KoBEST 같은 걸 최종 지표로 쓰고 싶었습니다. 안 됐습니다. 그리고 왜 안 되는지가 이 실험에서 두 번째로 건진 결과입니다.

정확도형 벤치마크는 천장 · 표본 잡음 · 난도 초과로 3분됐습니다.
| 지표 | 왜 조건을 못 가르는가 | 근거 |
|---|---|---|
| Ko-MinPair (자체 560쌍) | 천장 | 모든 조건이 0.5B 토큰 안에 96–99%로 포화. 8런 최종값이 0.979–0.991 |
| KoBEST COPA·HellaSwag | 표본 잡음 | 궤적(n=250) 단계에서 표준오차(±3%p)가 조건 간 차이보다 큼 |
| KoBEST BoolQ | 표본 잡음 | 8런 전체가 0.461–0.474(폭 1.3%p) |
| KoBEST SentiNeg | 조건 서열의 근거로 쓸 수 없음 | 같은 cosine 그룹에서 difficulty 0.835 > mixed 0.762로 loss 서열과 반대 |
| KoBALT-700 | 난도 초과 | 전 모델이 찬스(10%) 수준, 자체 8런 0.074–0.099 |
문법성 최소쌍이 0.5B 토큰 안에 포화한다는 건 조건 판별에는 쓸모없지만 그 자체로 흥미로운 발견입니다. 조사·어미 문법성은 데이터 순서와 무관하게 조기에 습득됩니다.
더 중요한 건 정확도형 지표에서 서열이 뒤집힌다는 사실입니다. cosine 그룹의 BoolQ는 length 0.474 > mixed 0.471 > difficulty 0.469 > random 0.464로 기준선인 random이 꼴찌이고, KoBALT도 length 0.084 > difficulty 0.080 > random 0.077 > mixed 0.074로 역전됩니다. 다만 그 서열의 근거는 1%p 안팎의 차이입니다(BoolQ는 8런 전체 폭이 1.3%p). 반면 val loss 서열은 두 스케줄에서 그대로 재현됐습니다.
SentiNeg는 결이 조금 다릅니다. 고정 LR 그룹에서 difficulty가 0.620으로 낮은데, 리포트는 이걸 벤치마크의 흔들림이 아니라 loss에서 본 망각이 다운스트림으로 새어나온 것으로 읽습니다. 그래도 조건 서열의 근거로 쓰기는 어렵습니다 — 같은 cosine 그룹에서는 difficulty 0.835 > mixed 0.762로 loss 서열과 반대이기 때문입니다.
그래서 이 스케일에서 조건 판별은 연속 지표(val loss·BPC)의 몫입니다. 지표를 방어적으로 고른 게 아니라, 정확도형 벤치마크가 이 체급에서 무엇을 못 재는지가 측정 결과로 나온 쪽에 가깝습니다.
앵커 대비 — 조건 비교가 아니라 절대 위치
외부 모델 3종도 같은 하네스로 한 번씩 돌렸습니다. 조건 간 비교와는 분리해 읽어야 하는 숫자입니다. 우리 110M은 문법성(Ko-MinPair 0.98–0.99)에서 KoGPT2 125M(0.993), Gemma 3 270M PT(0.980)와 동급이었고, KoBEST SentiNeg에서는 random(cosine) 0.848로 EXAONE 4.0 1.2B(0.815)를 포함한 전체 1위였습니다. 한국어 전용 2.5B 토큰의 in-domain 효율로 읽고 있습니다. EXAONE의 MinPair 0.864는 instruct 튜닝이 원시 문장 확률 분포를 왜곡해 로그확률 기반 문법성 비교에서 불리해지는 현상으로 봤습니다(순수 base LM이 아닙니다).
다만 앵커는 학습 데이터량이 수십–수천 배라 참고선일 뿐 공정 비교가 아니고, Gemma는 다국어 262k vocab이라는 구조 차이도 있습니다. 그리고 앞서 적은 대로 이 수치를 조건 서열의 근거로 쓸 수는 없습니다.
한계
- 시드 1개. 3시드 계획을 LR ablation으로 대체했습니다. 페어드 설계(동일 초기 가중치)와 두 LR 스케줄에서의 서열 재현이 보강 증거이지만, 조건 간 격차(0.08–0.18)의 분산 추정은 없습니다. 시드 2 부분 런 3개는 체크포인트를 보존해 뒀습니다.
- 정성 평가는 LLM 심사자 기반이고 프롬프트 20개·최종 체크포인트 1회 규모입니다. 위에 적은 대로 유의성이 보고된 대결은 difficulty 한 건입니다.
- Ko-MinPair의 일부 카테고리((으)로·활용·높임 80쌍)는 good/bad 길이가 1자 내외로 달라 합산 로그확률에 방향성 편향 가능성이 있어 카테고리를 분리 보고했습니다(조사 4종 480쌍은 동일 길이). 높임 카테고리는 엄밀한 비문이 아닌 수용성 대조를 포함합니다.
- 난이도는 청크 단위 집계 피처로 정의했습니다. 문장 단위 셔플은 기준선 자체를 비표준 학습으로 만들기 때문에 청크를 정렬 단위로 택했는데, mixed의 미리보기 비율도 청크 수 기준이라 밴드 간 청크 길이 차이만큼 토큰 비율이 목표치에서 벗어날 수 있습니다.
- 웹 코퍼스의 near-duplicate는 exact-hash dedup만 수행했습니다.
곁다리로 배운 것
앵커 평가에서 KoGPT2가 전 지표 찬스 수준으로 나와서 한참 헤맸습니다. 원인은 transformers의
GPT2 래퍼가 kogpt2 토크나이저의 SentencePiece식 파이프라인을 byte-level로 덮어써 한국어를
바이트로 분해하고 있던 것이었습니다. 한글 포함 여부를 프로브로 감지해 raw tokenizers.Tokenizer
로 우회 로드해 해결했는데, "숫자가 나온다 ≠ 맞게 재고 있다"를 제일 아프게 배운
지점이었습니다.
다음 질문
망각이 원인이라면 다음 실험은 정해져 있습니다. 총 토큰을 고정한 채(코퍼스 1/4 × 4에포크) 에포크별 재셔플 / 커리큘럼 전체 사이클 반복(spaced) / 난이도 밴드 블록 반복(blocked)을 비교하는 것입니다. 사이클 반복은 쉬운 밴드를 재방문하므로, 망각 가설이 맞다면 이 실험에서 관찰된 easy 밴드 상승이 사라져야 합니다. 인지과학의 blocked vs interleaved practice 논쟁과 직접 연결되는 설계이기도 합니다.
정리하면 이렇습니다. 결론을 지탱하는 것은 val loss·BPC이고, blind pairwise 생성 채점이 그 결론이 생성물 수준에서도 보인다는 것을 (유의성이 확인된 것은 difficulty 대결 한 건입니다) 뒷받침합니다. 그리고 정확도형 벤치마크가 조건을 못 가른다는 것 자체가 이 스케일에서의 방법론적 발견입니다.