LLM 엔지니어링4장 · LLM 을 완성하는 3단계와 Hugging Face10 / 23← 이전목차다음 →MetaContents

4장. LLM 을 완성하는 3단계와 Hugging Face

Auto 클래스로 불러오기

처음 가는 식당에서 "오늘의 추천"이라고만 말하면 주방이 알아서 맞는 요리와 그릇을 내옵니다. transformers 의 Auto 클래스가 이렇습니다. 모델 이름만 주면 그 모델에 맞는 토크나이저와 모델 클래스를 골라 불러옵니다.

모델 이름 고르기, AutoTokenizer, AutoModelFor, generate 의 네 단계를 이은 흐름도

1번에서 Hub 의 모델 이름을 고르면, 2번 AutoTokenizer 와 3번 AutoModelFor… 가 같은 이름으로 짝이 맞는 토크나이저와 모델을 불러옵니다. 4번에서 generate() 로 토큰을 만들고 decode() 로 글로 바꿉니다. 여기서 "오늘의 추천"이 모델 이름, 알아서 나오는 요리와 그릇이 모델과 토크나이저입니다.

쓰임에 따른 Auto 클래스

클래스쓰임이 과정에서
AutoTokenizer그 모델의 토크나이저내내
AutoModelForCausalLM앞만 보고 다음 토큰을 쓰는 모델(GPT 류)3장 실습 6, 4장
AutoModelForSeq2SeqLM읽고 새로 쓰는 인코더-디코더(번역)3장 실습 5
AutoModel머리(출력층) 없이 벡터만 내는 모델7장 임베딩
AutoConfig설정 파일만4장

토크나이저가 하는 세 가지

Python
from transformers import AutoTokenizer

tok = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B")

text = "배송비는 얼마인가요?"
ids = tok(text)["input_ids"]                   # 1) 글 → 번호
print(ids)
print(tok.convert_ids_to_tokens(ids))          # 2) 번호 → 토큰 조각
print(tok.decode(ids))                         # 3) 번호 → 글

이 문장은 Qwen 의 토크나이저로 토큰 9개가 됩니다. 조각은 ë°°, Ġìĸ¼ë§Ī 같은 낯선 글자로 보이는데, 이 토크나이저가 글을 바이트 단위로 자르기 때문입니다. decode 하면 원래 문장이 그대로 돌아옵니다.

코드에 나오는 함수

코드쉬운 뜻
AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B")모델 이름에 맞는 토크나이저를 Hub 에서 받아 만든다. 처음 한 번은 인터넷이 필요하다
tok(text)["input_ids"]글을 토큰 번호 목록으로 바꾼다. 토크나이저는 사전을 돌려주는데, 그 가운데 input_ids(입력 번호) 칸만 꺼낸다
tok.convert_ids_to_tokens(ids)번호를 토크나이저 안에 적힌 토큰 조각으로 바꾼다. 조각은 사람이 읽기 어려운 바이트 꼴일 수 있다
tok.decode(ids)번호를 다시 사람이 읽는 글로 되돌린다. decode 는 "부호를 풀다"라는 뜻이다

이 코드가 뜻하는 것

은행 창구의 번호표를 떠올려 보세요. 손님(글)이 오면 번호표(토큰 번호)를 뽑아 주고, 창구는 번호만 보고 일을 합니다. 번호표 뒷면에는 기계가 쓰는 표시(토큰 조각)가 찍혀 있고, 마지막에 번호를 부르면 다시 손님 이름(글)이 됩니다.

줄하는 일쉽게 말하면
ids = tok(text)["input_ids"]문장을 번호 9개로 바꾼다번호표를 뽑는다
tok.convert_ids_to_tokens(ids)번호마다 적힌 조각을 보여 준다번호표 뒷면의 기계용 표시를 본다
tok.decode(ids)번호를 원래 글로 되돌린다번호를 불러 손님 이름을 확인한다

모델은 1번의 번호만 보고 계산합니다. 2번의 조각은 사람이 토큰이 어떻게 잘렸는지 엿보려고 찍은 것이고, 3번은 모델이 만든 번호를 글로 바꿀 때 씁니다.

작게 줄여서 눈으로 보기

조각이 ë°° 처럼 보이는 까닭을 내려받기 없이 확인해 봅니다. 한글 한 글자는 UTF-8(Unicode Transformation Format 8-bit, 유니코드를 8비트 단위로 적는 방식)에서 바이트 3개로 저장됩니다.

Python
word = "배"
raw = word.encode("utf-8")              # 글자를 컴퓨터가 저장하는 바이트로
print(list(raw))                        # 바이트 셋의 번호(0~255)
print(raw.decode("latin-1"))            # 바이트 하나를 글자 하나로 억지로 보이면
print(raw.decode("utf-8"))              # 바이트 셋을 한글로 다시 읽으면
출력
[235, 176, 176]
ë°°
배
결과읽는 법
[235, 176, 176]"배" 한 글자가 바이트 3개로 저장됩니다
ë°°바이트 하나를 서양 글자 하나로 억지로 보이면 Qwen 의 토큰 조각과 같은 ë°° 가 됩니다. latin-1 은 바이트 하나를 서양 글자 하나에 짝지은 글자표입니다
배같은 바이트 셋을 UTF-8 로 읽으면 원래 글자로 돌아옵니다. decode 가 하는 일이 이것입니다

바이트 단위 토크나이저는 이렇게 바이트를 글자 하나씩으로 바꿔 적어 두기 때문에 조각이 낯설게 보입니다. 앞의 Ġ 는 같은 방식으로 띄어쓰기 바이트를 나타낸 표시입니다. 글이 깨진 것이 아니므로 걱정하지 않아도 됩니다.

주의할 점

  • 토크나이저와 모델은 반드시 같은 이름으로 불러옵니다. 다른 모델의 토크나이저를 쓰면 번호표가 달라 엉뚱한 글이 나옵니다.
  • 기본으로 float32 로 불러오면 0.5B 모델이 메모리 2GB 쯤을 씁니다. dtype=torch.float16 을 주면 절반이 되지만, CPU 에서는 float32 가 안전합니다.
← 이전 절4장 · 모델 카드와 라이선스다음 절 →4장 · 생성 설정