앞 글자 여럿 보기: 비슷한 낱말을 비슷하게 다루는 신경망
혼동하기 쉬운 점과 요약
토론 2. 학습률을 키우면 빨리 배우는가
학습률을 0.0001, 0.001, 0.01 로 열 배씩 키우자 500 스텝 뒤의 손실이 4.564, 3.237, 2.922 로 낮아졌다. 학습률을 더 키우면 더 빨리 배우는가?

0.01 까지는 키울수록 좋았어요. 0.1 도 될 줄 알았는데, 스텝 4 에 26.447 로 튀고 6 근처에서 멈췄어요.

0.01 과 0.1 은 열 배 차이예요. 그 사이 어딘가에 벼랑이 있겠죠. 벼랑을 찾았으면 벼랑 바로 앞을 고르면 될까요?

그게 가장 빠르긴 하겠지만 불안해요. 500 스텝 동안 괜찮았어도 4,000 스텝 동안 한 번이라도 큰 그래디언트가 오면 넘어갈 수도 있잖아요.

그래서 본 학습에는 워밍업이랑 그래디언트 클리핑을 붙인 거네요. 처음 100 스텝은 학습률을 작게 두고, 튀는 스텝은 길이를 1.0 으로 자르고요.

그래요. 학습률은 키울수록 빨라지다가 어느 값을 넘으면 터지거나 멈춰요. 그 경계는 모델과 데이터마다 달라서 실험으로 찾고, 찾은 다음에는 조금 물러서서 골라요.
혼동하기 쉬운 점
| 혼동하기 쉬운 생각 | 나온 문제 | 바로잡는 법 |
|---|---|---|
| 토큰 번호를 그대로 숫자로 넣어도 된다고 봄 | 1 | 번호는 합친 순서일 뿐이라 크기에 뜻이 없다. 원핫 벡터에 임베딩 표를 곱해 토큰마다 배운 벡터로 바꾼다 |
| 본 적 없는 문맥은 모델도 모른다고 봄 | 2, 6 | 임베딩은 모든 문장이 함께 고친다. 같은 자리에 쓰이는 토큰은 벡터가 비슷해져 처음 보는 문맥도 비유해 맞힌다 |
| 앞 토큰을 늘리면 그만큼 잘 맞힌다고 봄 | 3 | 이어 붙이는 모델은 자리마다 가중치가 따로라, 같은 토큰도 몇 칸 앞이냐에 따라 따로 배워야 한다 |
| 손실이 터지지 않으면 학습이 된다고 봄 | 4 | 학습률 0.1 은 터지지 않고도 바이트당 비트 2.3768 에 멈췄다. 어디까지 줄었는지를 본다 |
| 학습 전 손실이 ln V 보다 조금 큰 것은 잘못이라고 봄 | 5 | −log 가 아래로 볼록해서 무작위로 고르지 않은 확률은 평균 손실을 ln V 보다 키운다. 많이 크거나 작으면 그때 의심한다 |
| 학습률은 클수록 빨리 배운다고 봄 | 토론 2 | 키울수록 빨라지다 벼랑을 넘으면 터진다. 학습률 1 은 50 스텝 만에 손실 417.8 이 되었다. 벼랑을 실험으로 찾고 조금 물러선다 |
| 임베딩 이웃이 곧 모델의 생각이라고 봄 | 7, 8 | 이웃은 같은 자리에 쓰였다는 뜻이다. 드문 토큰은 덜 배운다. 이름 붙이기 전에 문맥을 세어 확인한다 |
| 여러 토큰으로 잘린 낱말은 조각 임베딩을 평균하면 된다고 봄 | 9 | 평균은 조각에 가장 가깝게 남고(「 Minjun」 옆에 「␣M」, 「j」, 「un」) 순서를 모른다. 모델이 낱말을 다 읽은 자리의 벡터가 낫지만, 모델이 낱말이 끝났다고 알아야 한다 |
| 임베딩은 길수록 좋다고, 또는 가장 좋은 길이가 하나 정해져 있다고 봄 | 토론 1 | 길이를 두 배로 할 때 얻는 양은 줄고(256 → 512 에서 0.0069) 파라미터는 7,168d 개씩 는다. 학습 글이 400만 토큰이면 128 을 넘어서 검증 값이 다시 나빠졌다. 검증 글의 곡선과 비용으로 고르고, 글의 양이 바뀌면 다시 잰다 |
요약
토큰 표는 문맥을 하나하나 따로 외우므로 앞 토큰을 여럿 보려 하면 칸이 10¹⁸ 개를 넘어 거의 다 빈다. 벤지오 팀(2003)는 낱말마다 학습되는 벡터를 두고 앞 낱말들의 벡터로 다음 낱말의 확률을 내는 신경망을 함께 학습해 이 차원의 저주를 피했다. 토큰 번호로 꺼내 쓰는 학습되는 벡터가 임베딩이다. 이 장의 모델은 앞 토큰 여섯 개의 임베딩(길이 64)을 이어 붙여 은닉층 512 와 출력층 4,096 을 지나 다음 토큰의 확률을 내고, 파라미터는 2,560,512 개, 그 가운데 82% 가 출력층에 있다.
학습 루프는 조각을 뽑아 손실을 계산하고, 역전파로 그래디언트를 구하고, AdamW 로 파라미터를 고치기를 되풀이한다. 학습률 1 은 50 스텝 만에 손실을 8.36 에서 417.8 로 올렸고 모델은 「Later」 몇 개만 되풀이했다. 학습률 0.1 은 터지지 않고도 바이트당 비트 2.3768 에 멈췄고, 0.01 이 가장 좋았다. 0.01 에 워밍업과 코사인 감쇠, 그래디언트 클리핑을 붙여 4,000 스텝(6,553만 토큰, RTX 4090 한 장에서 39초) 학습하자 바이트당 비트가 0.9326 이 되어 토큰 바이그램 1.2818 보다 낮아졌다. 학습한 임베딩에서는 「 Lily」 옆에 「 Mia」, 「 red」 옆에 「 blue」가 오고, 드문 이름 「 Luna」는 이름 자리를 함께 쓰는 「 Mimi」, 「 Kitty」 옆에 있다. 여러 토큰으로 잘린 「 Seoyeon」은 조각 임베딩을 평균하면 자기 조각 옆에 남지만, 동화를 쓰는 8층 GPT 가 다섯 토큰을 다 읽은 자리의 벡터로 재면 「 John」, 「 Joe」 옆에 온다. 임베딩 길이를 4 부터 512 까지 바꾸면 검증 바이트당 비트는 1.1734 에서 0.8795 까지 내려가지만, 두 배로 늘릴 때마다 얻는 양이 줄어 256 을 넘으면 거의 평평하다. 학습 글이 400만 토큰뿐이면 길이 128 이 가장 좋고 512 는 학습 글을 외워 32 보다도 나빠진다. 가장 좋은 길이는 하나로 정해져 있지 않고, 검증 곡선과 비용과 학습 글의 양이 함께 정한다.
루나 설정서 점검
| 설정서의 줄 | 이번 장에서 |
|---|---|
| 1. 말이 된다 | 조금. 문장 하나는 동화처럼 시작하고 끝난다(바이트당 비트 0.9326). 그러나 토끼 Spot 이 한 문장 뒤에 개가 된다 |
| 2. 앞에서 한 말을 기억한다 | 아직. 앞 여섯 토큰 밖은 보이지 않는다 |

「girl named Luna」로 시작해도 두 문장 뒤엔 Jimmy 랑 토끼 얘기를 해.

루나 이름을 말하고 일곱 토큰만 지나면 루나를 잊어버리는 거네.
막힌 곳
시작 문장을 「Once upon a time, there was a girl named Luna.」로 주면 모델은 「 Luna」를 받아 다음 문장을 시작하지만, 몇 문장 뒤에는 「Jimmy smiled and nodded.」처럼 다른 인물로 넘어간다(sources/mlp-lm/probe_mlp.out). 이 모델은 앞 여섯 토큰만 보도록 만들어졌기 때문이다. 앞 토큰 수를 늘리면 되겠지만, 이어 붙이는 방식에서는 은닉층 가중치가 자리마다 따로라서 같은 「 Luna」도 여섯 칸 앞과 백 칸 앞을 따로 배워야 한다. 이야기 처음에 나온 이름을 몇백 토큰 뒤에서도 찾아 쓰려면, 자리마다 따로 배우지 않고도 먼 앞의 토큰을 골라 읽는 방법이 있어야 하지 않을까?