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

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

생성은 한 토큰씩 이어집니다

징검다리를 건너는 사람을 떠올려 봅니다. 한 번에 강을 건너뛰지 않고, 지금 선 돌에서 다음 돌 하나를 골라 디디고, 다시 거기서 다음 돌을 고릅니다. generate() 도 문장을 한 번에 만들지 않습니다. 다음 토큰 하나 고르기 → 입력 뒤에 붙이기를 되풀이합니다.

입력, 점수, 확률, 고르기, 붙이기의 다섯 단계를 화살표로 이은 흐름도

그림의 다섯 상자가 한 바퀴입니다. 지금까지의 토큰을 넣으면(1) 모델이 사전의 모든 후보에 점수를 매기고(2), Softmax 로 확률을 만들고(3), 하나를 고르고(4), 입력 뒤에 붙여 다시 1번으로 갑니다(5). max_new_tokens 만큼 돌거나 끝 토큰(<|im_end|>)이 나오면 멈춥니다. do_sample=False 이면 4번에서 늘 확률이 가장 큰 후보를 고릅니다. 이것이 Greedy 입니다.

한 바퀴의 각 단계

단계하는 일크기(Qwen 0.5B)징검다리로 치면
1. 입력지금까지의 토큰 번호처음 8개 → 한 바퀴마다 1개씩 늘어남지금까지 디딘 돌
2. 점수다음 토큰 후보마다 로짓사전 크기만큼(15만 칸 남짓)앞에 보이는 돌마다 점수
3. 확률Softmax 로 합 1같은 크기점수를 비율로
4. 고르기Greedy 면 가장 큰 것, 샘플링이면 뽑기토큰 1개디딜 돌 하나 고르기
5. 붙이기입력 뒤에 이어 붙인다길이 + 1돌을 디디고 다시 둘러보기

짧은 예시

Python
# numpy = 숫자 배열 계산 도구
import numpy as np

# 장난감 모델: "마지막 토큰" 을 보고 다음 토큰 후보와 확률을 알려 주는 표(설명용 숫자)
next_probs = {
    "서울": {"입니다": 0.6, "이다": 0.3, "시": 0.1},
    "입니다": {".": 0.8, ",": 0.2},
    ".": {"<끝>": 0.7, "서울": 0.3},
}

tokens = ["대한민국의", "수도는", "서울"]  # 1. 처음 입력
for step in range(5):  # max_new_tokens = 5 와 같은 뜻
    cands = next_probs[tokens[-1]]  # 2~3. 마지막 토큰을 보고 후보와 확률을 받는다
    names = list(cands)
    probs = np.array(list(cands.values()))
    pick = names[int(np.argmax(probs))]  # 4. Greedy: 확률이 가장 큰 후보(argmax)
    if pick == "<끝>":  # 끝 토큰이 나오면 멈춘다
        break
    tokens.append(pick)  # 5. 뒤에 붙이고 다시 돈다
    print(step + 1, tokens)
# 결과: 1 [..., '서울', '입니다'] → 2 [..., '입니다', '.'] 에서 다음이 <끝> 이라 멈춘다

이 코드가 뜻하는 것

징검다리를 건너는 사람이 매번 "점수가 가장 높은 돌"만 디디는 모습을 표 하나로 흉내 냈습니다. 실제 Qwen 은 표 대신 신경망이 15만 칸의 확률을 매번 새로 계산하지만, 돌고 붙이고 멈추는 뼈대는 같습니다.

줄하는 일쉽게 말하면
next_probs[tokens[-1]]마지막 토큰을 보고 후보 확률을 받는다지금 선 돌에서 앞을 둘러보기
np.argmax(probs)가장 큰 확률의 자리Greedy 로 하나 고르기
tokens.append(pick)고른 토큰을 붙인다돌을 디디기
if pick == "<끝>": break끝 토큰이면 멈춘다건너편에 닿음

다섯 바퀴를 줬지만 두 바퀴 만에 끝 토큰이 나와 멈췄습니다. 실제 생성에서도 max_new_tokens 는 "최대"이므로 답이 일찍 끝날 수 있습니다.

주의할 점

  • Greedy 는 같은 입력과 설정이면 늘 같은 답을 냅니다. 학습 전후를 견줄 때 쓰기 좋아서 실습 2의 chat 함수가 do_sample=False 를 씁니다.
  • Greedy 의 단점은 같은 말을 되풀이하기 쉽다는 것입니다. 작은 모델일수록 심합니다. 그래서 repetition_penalty=1.2 로 이미 나온 토큰을 불리하게 합니다.
  • 실제 모델은 한 바퀴마다 앞의 계산을 저장해 두고(KV 캐시) 새 토큰 부분만 계산합니다. 그래도 토큰 수만큼 바퀴를 돌아야 하므로 긴 답일수록 오래 걸립니다.
← 이전 절6장 · 문장 이어 쓰기다음 절 →6장 · 디코딩 전략: temperature, top-k, top-p