트랜스포머·PEFT 2일 과정6장 · Qwen 모델 준비와 텍스트 생성6 / 17← 이전목차다음 →MetaContents

6장. Qwen 모델 준비와 텍스트 생성

문장 이어 쓰기

끝말잇기와 비슷한 "말 이어 붙이기" 놀이를 떠올려 봅니다. 앞사람이 "대한민국의 수도는 서울" 까지 말하면, 다음 사람은 그 뒤에 가장 자연스러운 말을 하나 붙입니다. LLM 이 하는 일이 정확히 이것입니다. 지금까지의 글을 보고 다음에 올 토큰의 점수를 매긴 뒤, 하나를 골라 붙입니다.

Decoder 의 마지막 벡터가 Linear 층을 지나 사전 속 토큰마다 점수(로짓)가 되고, Softmax 를 거쳐 합이 1 인 확률분포가 되는 강사자료 그림

강사자료 그림을 왼쪽부터 읽습니다. Decoder 블록을 다 지난 마지막 벡터(d_model 칸)가 Linear 층에서 사전 크기만큼의 점수(로짓)로 바뀝니다. Qwen 이면 896칸이 15만 칸 남짓의 점수표가 됩니다. 이 점수를 Softmax 로 확률로 바꾸면 가장 오른쪽 막대처럼 합이 1 인 분포가 됩니다. 그림에서는 "학생"이 0.67 로 가장 높습니다. 이 확률에서 하나를 고르는 것이 다음 절과 그다음 절의 이야기입니다.

이어 쓰기에 쓰는 두 가지 방법

방법코드입력출력쓰는 곳
pipelinepipeline("text-generation", model=model, tokenizer=tokenizer)글자 그대로입력 + 이어 쓴 글실습 3, 빠르게 맛보기
generatemodel.generate(**inputs, max_new_tokens=...)토큰 번호 텐서입력 + 새 토큰 번호실습 2의 chat, 프로젝트

pipeline 은 토큰화, 생성, 글자로 되돌리기를 한 번에 해 주는 편의 도구입니다. 그 안에서도 결국 generate 가 돕니다. pipeline 에 글자를 그대로 넣으면 Chat Template 을 입히지 않으므로, 모델은 질문에 답한다기보다 "글을 이어 쓰는" 쪽으로 움직입니다.

짧은 예시

Python
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 를 쓰겠다고 알리는 안내입니다.
← 이전 절6장 · 모델 크기와 GPU 메모리다음 절 →6장 · 생성은 한 토큰씩 이어집니다