밑바닥부터 만드는 mini GPT 공부 시리즈 2편
BPE가 문장을 token ID 목록으로 바꾸었다면, 다음 단계는 그 목록을 학습 샘플로 자르는 일이다. GPT는 현재까지의 토큰을 보고 다음 토큰을 맞히도록 학습한다.
이 단계에서 자주 헷갈리는 지점은 두 가지다. 첫째, input과 target은 길이가 같지만 한 칸 밀려 있다. 둘째, token ID는 그 자체로 의미 벡터가 아니므로 embedding을 거쳐야 한다.
이번 글에서 다루는 것
- GPTDataset이 input과 target을 어떻게 만드는지
- context_length와 stride가 샘플 수에 어떤 영향을 주는지
- token embedding과 position embedding을 왜 더하는지
- 최종 입력 shape가 왜 `(batch_size, seq_len, emb_dim)`인지
1. 다음 토큰 예측은 input과 target을 한 칸 어긋나게 만든다
token ID 목록이 `[10, 11, 12, 13]`이고 context 길이가 3이라고 하자. 모델은 `[10, 11, 12]`를 보고 `[11, 12, 13]`을 맞히도록 훈련된다.
이 구조는 한 번의 forward에서 여러 위치의 다음 토큰 예측을 동시에 학습하게 만든다. 첫 번째 위치는 10 다음 11을, 두 번째 위치는 11 다음 12를, 세 번째 위치는 12 다음 13을 맞히는 식이다.
2. context_length는 모델이 한 번에 보는 문맥 길이다
context_length는 한 샘플 안에 들어가는 토큰 수다. 너무 짧으면 긴 문맥을 배우기 어렵고, 너무 길면 계산량이 늘어난다. 이번 과제에서는 처음부터 크게 잡지 않고 작은 설정으로 동작을 확인한 뒤 키우는 방식이 권장된다.
| 값 | 의미 | 주의점 |
|---|---|---|
| context_length | 한 샘플의 input 길이 | target까지 만들려면 실제로는 `context_length + 1`개 토큰이 필요 |
| stride | 다음 샘플로 이동하는 간격 | 작을수록 샘플은 많아지지만 겹침도 늘어남 |
| batch_size | 한 번에 묶어 계산하는 샘플 수 | GPU 메모리와 학습 안정성에 영향 |
3. token ID는 embedding을 거쳐야 의미 있는 계산 대상이 된다
token ID 10과 token ID 11은 숫자 크기 자체에 의미가 있는 것이 아니다. 11이 10보다 크다고 해서 더 중요한 토큰이라는 뜻은 아니다. 그래서 ID를 바로 계산하지 않고 embedding table에서 벡터를 꺼낸다.
[10, 11, 12]
각 token을 emb_dim 길이의 벡터로 변환
토큰 의미와 위치 정보를 함께 가진 벡터
position embedding이 필요한 이유도 여기서 나온다. 같은 token이라도 문장 안에서 어디에 놓였는지에 따라 역할이 달라질 수 있기 때문이다.
shape로 기억하기
이 단계의 최종 출력 shape는 다음처럼 기억하면 된다.
input token IDs: (batch_size, seq_len)
token embedding: (batch_size, seq_len, emb_dim)
position embedding: (seq_len, emb_dim)
final input: (batch_size, seq_len, emb_dim)
스스로 점검
- target이 input보다 한 칸 뒤로 밀리는 이유는 무엇인가?
- token ID 숫자 자체를 바로 모델 입력으로 쓰지 않는 이유는 무엇인가?
- position embedding이 없다면 같은 토큰의 위치 차이를 어떻게 알 수 있을까?
다음 글 예고
다음 글에서는 attention을 다룬다. 핵심은 각 토큰이 문맥 안의 다른 토큰을 어떤 비율로 참고하는지 계산하는 방식이다.
한 줄 정리: Dataset은 다음 토큰 예측 문제를 만들고, Embedding은 token ID를 모델이 계산할 수 있는 위치 포함 벡터로 바꾼다.