6장. Qwen 모델 준비와 텍스트 생성
문장 이어 쓰기
끝말잇기와 비슷한 "말 이어 붙이기" 놀이를 떠올려 봅니다. 앞사람이 "대한민국의 수도는 서울" 까지 말하면, 다음 사람은 그 뒤에 가장 자연스러운 말을 하나 붙입니다. LLM 이 하는 일이 정확히 이것입니다. 지금까지의 글을 보고 다음에 올 토큰의 점수를 매긴 뒤, 하나를 골라 붙입니다.
강사자료 그림을 왼쪽부터 읽습니다. Decoder 블록을 다 지난 마지막 벡터(d_model 칸)가 Linear 층에서 사전 크기만큼의 점수(로짓)로 바뀝니다. Qwen 이면 896칸이 15만 칸 남짓의 점수표가 됩니다. 이 점수를 Softmax 로 확률로 바꾸면 가장 오른쪽 막대처럼 합이 1 인 분포가 됩니다. 그림에서는 "학생"이 0.67 로 가장 높습니다. 이 확률에서 하나를 고르는 것이 다음 절과 그다음 절의 이야기입니다.
이어 쓰기에 쓰는 두 가지 방법
| 방법 | 코드 | 입력 | 출력 | 쓰는 곳 |
|---|---|---|---|---|
| pipeline | pipeline("text-generation", model=model, tokenizer=tokenizer) | 글자 그대로 | 입력 + 이어 쓴 글 | 실습 3, 빠르게 맛보기 |
| generate | model.generate(**inputs, max_new_tokens=...) | 토큰 번호 텐서 | 입력 + 새 토큰 번호 | 실습 2의 chat, 프로젝트 |
pipeline 은 토큰화, 생성, 글자로 되돌리기를 한 번에 해 주는 편의 도구입니다. 그 안에서도 결국 generate 가 돕니다. pipeline 에 글자를 그대로 넣으면 Chat Template 을 입히지 않으므로, 모델은 질문에 답한다기보다 "글을 이어 쓰는" 쪽으로 움직입니다.
짧은 예시
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B-Instruct")
prompt = "대한민국의 수도는 서울" # 실습 3의 입력
full = "대한민국의 수도는 서울입니다. 서울은 대한민국의 중심지로," # 실습 3의 출력
# 글자를 토큰 번호 리스트로 바꾼다
prompt_ids = tokenizer(prompt)["input_ids"]
full_ids = tokenizer(full)["input_ids"]
# 번호 하나씩을 다시 글자로 바꿔 블록 모양을 본다
print([tokenizer.decode([i]) for i in prompt_ids])
# 결과: ['대', '한', '민', '국', '의', ' 수도', '는', ' 서울']
print(len(prompt_ids), len(full_ids), len(full_ids) - len(prompt_ids))
# 결과: 8 20 12이 코드가 뜻하는 것
말 이어 붙이기 놀이에서 앞사람이 낸 블록이 몇 개였고, 모델이 몇 개를 더 붙였는지 세어 본 것입니다. 입력은 블록 8개, 출력은 20개이므로 모델이 12개를 붙였습니다. 실습 3에서 준 max_new_tokens=12 와 딱 맞습니다. 그래서 출력 문장이 "중심지로," 에서 뚝 끊깁니다.
| 줄 | 하는 일 | 쉽게 말하면 |
|---|---|---|
tokenizer(prompt)["input_ids"] | 글자를 토큰 번호로 | 문장을 레고 블록으로 쪼개기 |
tokenizer.decode([i]) | 번호 하나를 글자로 | 블록 하나에 적힌 글 읽기 |
len(full_ids) - len(prompt_ids) | 새로 붙은 토큰 수 | 모델이 보탠 블록 수 |
글이 문장 중간에서 끊기는 것은 모델이 모자라서가 아니라 max_new_tokens 에서 멈췄기 때문입니다.
주의할 점
max_new_tokens는 글자 수가 아니라 토큰 수입니다. 한국어는 한 글자가 토큰 하나가 되는 일이 많아 생각보다 짧게 끊깁니다.pipeline의 출력(generated_text)에는 입력 문장이 앞에 그대로 붙어 있습니다. 실습 3의sample함수가replace(prompt, "", 1)로 앞부분을 떼는 까닭입니다.- 실습 3의 첫 출력 줄 "Device set to use cuda:0" 은 오류가 아니라 pipeline 이 GPU 를 쓰겠다고 알리는 안내입니다.