LLM 엔지니어링3장 · Attention 과 Transformer, GPT 직접 구현3 / 23← 이전목차다음 →MetaContents

3장. Attention 과 Transformer, GPT 직접 구현

토큰과 토크나이저

택배 상자에 물건을 담을 때, 큰 물건은 나눠 담고 작은 물건은 모아 담습니다. 모델도 글을 통째로 받지 못해서 알맞은 크기의 조각으로 잘라 받습니다. 이 조각이 토큰이고, 자르는 도구가 토크나이저입니다.

같은 문장을 글자 단위, 낱말 단위, 서브워드 단위로 자른 모습을 나란히 놓은 비교 그림

"배송이 늦어요"를 세 가지 크기로 잘랐습니다. 왼쪽 글자 단위는 조각의 종류가 적지만 글이 길어지고, 가운데 낱말 단위는 조각이 적지만 처음 보는 낱말이 생기면 다루지 못합니다. 오른쪽 서브워드 단위는 그 사이입니다. 여기서 물건이 글, 상자가 토큰입니다.

세 가지 자르는 법

단위"배송이 늦어요"어휘 크기좋은 점아쉬운 점
글자배 / 송 / 이 / 빈칸 / 늦 / 어 / 요작다(수백~수천)모르는 글자가 거의 없다글이 길어져 계산이 많다
낱말배송이 / 늦어요아주 크다글이 짧다처음 보는 낱말을 못 다룬다
서브워드배 / 송이 / 늦 / 어요중간(수만)둘의 장점을 섞었다자르는 규칙을 따로 배워야 한다

실습 1~4의 미니 GPT 는 이해하기 쉬운 글자 단위를 쓰고, 실습 5의 번역 모델은 서브워드 단위를 씁니다.

글자 토크나이저 만들기

글자 단위 토크나이저는 파이썬 사전 두 개면 됩니다.

Python
text = "배송이 늦어요"

chars = sorted(set(text))                          # 나오는 글자를 모아 정렬한 것이 어휘
stoi = {c: i for i, c in enumerate(chars)}         # 글자 → 번호
itos = {i: c for c, i in stoi.items()}             # 번호 → 글자

ids = [stoi[c] for c in text]                      # 인코딩: 글을 번호 목록으로
print(chars)
print(ids)
print("".join(itos[i] for i in ids))               # 디코딩: 번호를 다시 글로

어휘는 [' ', '늦', '배', '송', '어', '요', '이'] 일곱 글자이고, 문장은 [2, 3, 6, 0, 1, 4, 5] 가 됩니다. 번호를 다시 글자로 바꾸면 원래 문장이 그대로 돌아옵니다. 번호의 크기에는 뜻이 없습니다. "늦"이 1, "배"가 2 인 것은 정렬 순서일 뿐입니다.

코드에 나오는 함수

코드쉬운 뜻
sorted(set(text))글에 나오는 글자를 겹치지 않게 모아 정렬한다. 이 목록이 토크나이저의 어휘다
stoi"string to integer"의 줄임말이다. 글자를 넣으면 번호가 나오는 사전이다
itos"integer to string"의 줄임말이다. stoi 를 뒤집어 번호를 넣으면 글자가 나오는 사전이다
ids = [stoi[c] for c in text]인코딩이다. 글을 모델이 받을 번호 목록으로 바꾼다
"".join(itos[i] for i in ids)디코딩이다. 번호 목록을 다시 글로 되돌린다

이 코드에는 PyTorch 가 나오지 않습니다. 토크나이저는 신경망이 아니라 글과 번호를 오가는 번호표일 뿐입니다. stoi, itos 라는 이름은 실습 1과 실습 3, 4에서도 그대로 씁니다.

주의할 점

  • 같은 글이라도 토크나이저마다 토큰 수가 다릅니다. LLM 의 요금과 입력 길이 제한은 글자 수가 아니라 토큰 수로 셉니다.
  • 학습에 쓴 토크나이저와 쓸 때의 토크나이저는 반드시 같아야 합니다. 번호표가 바뀌면 모델은 엉뚱한 글자를 읽습니다.
← 이전 절3장 · 용어 짚고 가기다음 절 →3장 · 임베딩