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

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

실습 3 — 문장 이어 쓰기와 temperature 비교

pipeline 으로 문장 뒤를 이어 쓰게 하고, 같은 문장을 temperature 두 값으로 두 번씩 뽑아 견줍니다. 원본 노트북의 셀 11, 16 입니다. 실습 1의 두 셀을 먼저 실행해 둡니다.

코드를 단계별로 따라가기 전에 실행 흐름을 한 장으로 봅니다.

실습 3 코드의 실행 흐름도. 이미 올린 모델로 text-generation pipeline 을 만들어 Greedy 로 12토큰을 이어 쓰고, 2단계에서 새 문장과 sample 함수를 정한 뒤 temperature 0.05 와 1.2 로 두 번씩 뽑아 견준다
단계하는 일반복과 조건핵심 한 줄
1pipeline 으로 문장을 Greedy 로 이어 쓴다없음result = generate(prompt, max_new_tokens=12, do_sample=False)
2temperature 두 값으로 두 번씩 뽑는다없음. sample 을 네 번 차례로 부른다generate(prompt, max_new_tokens=30, do_sample=True, temperature=temperature)
  • 한 줄기 흐름: 2단계의 sample 함수는 1단계에서 만든 generate(pipeline)를 그대로 씁니다. 그래서 1단계를 먼저 실행합니다.
  • 반복문 대신 네 줄: 2단계는 for 없이 print(sample(0.05)) 두 줄, print(sample(1.2)) 두 줄을 차례로 적었습니다. 그림에서도 온도마다 네모 하나로 묶었습니다.
  • 결과는 실행마다 다릅니다: 마지막 두 네모의 결과는 교안을 만들 때 한 번 돌린 출력입니다. do_sample=True 라 직접 돌리면 다른 문장이 나옵니다.

1단계. pipeline 으로 문장 이어 쓰기

말 이어 붙이기 놀이에서 앞부분만 주고 뒤를 맡기는 일입니다. 대본 양식 없이 글자 그대로 주므로, 모델은 질문에 답하기보다 글을 자연스럽게 이어 씁니다.

Python · GPU 필요 (출력은 RTX 3080 에서 실행한 결과)
# 입력한 문장 뒤에 모델이 어떤 단어를 이어 쓰는지 확인합니다.
# pipeline = 토큰화, 생성, 글자로 되돌리기를 한 줄로 묶은 간편 도구
from transformers import pipeline  # 텍스트 생성을 간단히 호출합니다.

# "text-generation" = 글 이어 쓰기 일. 이미 불러 둔 model 과 tokenizer 를 그대로 쓴다
generate = pipeline("text-generation", model=model, tokenizer=tokenizer)  # 생성 파이프라인을 만듭니다.
prompt = "대한민국의 수도는 서울"  # 이어 쓸 문장 앞부분입니다.
# max_new_tokens=12 = 새 토큰 12개까지, do_sample=False = Greedy(늘 1등 후보)
result = generate(prompt, max_new_tokens=12, do_sample=False)  # 최대 12토큰을 탐욕적으로 생성합니다.
# result 는 [{"generated_text": 입력 + 이어 쓴 글}] 꼴의 리스트
# 결과: Device set to use cuda:0 / 대한민국의 수도는 서울입니다. 서울은 대한민국의 중심지로,
print(result[0]["generated_text"])
출력
Device set to use cuda:0
대한민국의 수도는 서울입니다. 서울은 대한민국의 중심지로,

2단계. temperature 두 값으로 두 번씩 뽑기

점심 메뉴를 늘 가던 집만 고르는 사람(0.05)과 모험을 즐기는 사람(1.2)에게 같은 질문을 두 번씩 해 보는 일입니다. do_sample=True 라 제비뽑기로 고르므로 실행할 때마다 문장이 달라집니다.

Python · GPU 필요 (출력은 RTX 3080 에서 실행한 결과)
# 같은 문장을 두 temperature로 두 번씩 생성
prompt = "한국에서 여행하기 좋은 도시 한 곳은"  # 여러 번 이어 쓸 같은 문장입니다.

# temperature 를 받아 문장 하나를 뽑는 함수
def sample(temperature):  # 주어진 온도로 답변 하나를 생성합니다.
    # do_sample=True = 확률에 따라 제비뽑기. temperature = 로짓을 나누는 값(모험심 다이얼)
    result = generate(prompt, max_new_tokens=30, do_sample=True, temperature=temperature)  # 확률적으로 다음 토큰을 고릅니다.
    # replace(prompt, "", 1) = 앞의 입력 문장을 한 번만 지운다. replace("\n", " ") = 줄바꿈을 빈칸으로
    return result[0]["generated_text"].replace(prompt, "", 1).strip().replace("\n", " ")  # 프롬프트를 뺀 뒷부분만 한 줄로 정리합니다.

# 낮은 온도: 1등 후보에 거의 몰린다. 결과: 두 번 모두 "서울입니다." 로 시작
print("--- temperature=0.05 (낮음) ---")
print(sample(0.05))
print(sample(0.05))

# 높은 온도: 확률이 고르게 퍼진다. 결과: 두 번이 서로 전혀 다른 문장
print("--- temperature=1.2 (높음) ---")
print(sample(1.2))
print(sample(1.2))
출력
--- temperature=0.05 (낮음) ---
서울입니다. 서울은 한국의 중심지로, 다양한 문화와 레스토랑을 찾는 것이 좋습니다. 또한,
서울입니다. 서울의 주요 도시 중 하나인 강남구는 한국의 가장 큰 중심지로, 다양한 문화와 �
--- temperature=1.2 (높음) ---
? (2) - 월간 '미디어 뉴스' 기자 정진환 코리아일 블
광주입니다. 한국을 여행하는데 광주에 도달하는 방법과 장소, 광주에 가는

이 실습이 뜻하는 것

같은 앞부분을 주고 "늘 1등만 고르기"와 "제비뽑기"를 견준 실습입니다. 1단계의 Greedy 는 "서울입니다. 서울은 대한민국의 중심지로," 처럼 무난하게 이어 쓰고, 12토큰에서 멈춥니다. 2단계의 temperature 0.05 는 두 번 모두 "서울입니다." 로 시작해 거의 Greedy 처럼 굴었고, 둘째 문장부터 조금씩 갈라졌습니다. temperature 1.2 는 한 번은 "? (2) - 월간 '미디어 뉴스' ..." 처럼 엉뚱한 글이, 한 번은 "광주입니다. ..." 처럼 다른 도시가 나왔습니다. 이 셀은 do_sample=True 라 실행할 때마다 문장이 달라집니다. 직접 돌리면 교안과 다른 문장이 나오는 것이 정상입니다.

단계출력뜻
1단계Device set to use cuda:0pipeline 이 GPU 를 쓴다는 안내
1단계대한민국의 수도는 서울입니다. 서울은 대한민국의 중심지로,Greedy 로 12토큰 이어 쓰기
2단계temperature 0.05: 두 번 모두 "서울입니다."1등에 몰려 거의 같은 시작
2단계temperature 1.2: 엉뚱한 글, "광주입니다."퍼진 분포에서 다양하게, 때로 엉뚱하게

temperature 를 낮추면 안정적이고, 높이면 다양하지만 엉뚱해질 수 있습니다.

코드 설명

  • pipeline("text-generation", model=model, tokenizer=tokenizer) 는 이미 GPU 에 올린 모델을 그대로 씁니다. 모델을 새로 불러오지 않으므로 메모리가 늘지 않습니다.
  • pipeline 에 글자를 그대로 넣으면 Chat Template 을 입히지 않습니다. 그래서 질문 답변이 아니라 "글 이어 쓰기"가 됩니다. 실습 2의 chat 과 다른 점입니다.
  • max_new_tokens=12 는 토큰 12개입니다. 본문에서 센 것처럼 입력 8토큰 + 새 12토큰 = 20토큰이라 "중심지로," 에서 끊깁니다.
  • sample 함수에는 temperature 만 줬으므로 모델 기본값 top_k 20, top_p 0.8, repetition_penalty 1.1 이 함께 걸립니다. temperature 1.2 에서도 아주 낮은 확률의 후보는 이 두 거르개에 걸러집니다.
  • 두 번 뽑은 문장이 서로 다른 것은 씨앗을 주지 않았기 때문입니다. torch.manual_seed 로 씨앗을 주면 같은 PC 에서는 다시 같은 문장을 볼 수 있습니다. 프로젝트에서 해 봅니다.
← 이전 절6장 · 실습 2 — chat 함수로 질문하기다음 절 →6장 · 프로젝트 1 — 디코딩 설정 비교표