SK플래닛 ai활용 데이터엔지니어 과정 2기/ML & DL

DL 6 - 트랜스포머 기반 학습 모델 가져오기

dev-lee 2026. 5. 27. 21:24

1. 개요

트랜스포머 기반 사전 학습 모델을 가져와서 별도 학습 없이 그대로 사용하는 제로샷 러닝(Zero-shot Learning) 방식으로 한국어 문장 생성을 실습함. 업스트림은 GPT2 다국어 모델, 다운스트림은 SKT가 한국어로 파인튜닝한 KoGPT2를 사용한다.

1.1 핵심 개념

  • 업스트림 모델(Upstream) — GPT2, 다국어 기준 문장 생성 모델
  • 다운스트림 모델(Downstream) — skt/kogpt2-base-v2, 한국어에 최적화되게 파인튜닝된 모델
  • 제로샷 러닝(Zero-shot Learning) — 추가 학습 없이 사전 학습된 모델을 그대로 사용
  • 파인튜닝(Fine-tuning) — 사전 학습 모델에 특정 도메인 데이터를 추가 학습시켜 성능 향상

1.2 문장 생성 절차

  • 1. 프롬프트 제시 — 단어 또는 단문 입력
  • 2. 토큰화 — 입력을 벡터로 변환
  • 3. 모델 주입 — 다음 토큰의 확률 분포 예측
  • 4. 토큰 선택 — Top-K 중 선택 (1등 선택 = 결정적, 랜덤 선택 = 창의적)
  • 5. 누적 반복 — 생성된 토큰을 입력에 누적하며 다음 토큰 예측 반복

제로샷 러닝은 "이미 잘 학습된 모델을 그대로 가져다 쓴다"는 발상. 별도 학습 데이터 없이도 즉시 활용 가능하다는 점에서 LLM 시대의 기본 사용 패턴이 됨. ChatGPT를 별도 학습 없이 그대로 쓰는 것이 정확히 이 방식이다.


2. KoGPT2 모델 정보

SKT가 GPT2 아키텍처에 한국어 데이터를 학습시켜 공개한 모델. 허깅페이스 허브에서 누구나 다운로드 가능하다.

2.1 모델 메타 정보

항목 
레포 skt/kogpt2-base-v2
URL huggingface.co/skt/kogpt2-base-v2
베이스 아키텍처 GPT2 (디코더 기반 트랜스포머)
언어 한국어 특화
라이선스 CC-BY-NC-SA 4.0 (비상업적 사용)
어휘 크기 51,200 토큰

2.2 트랜스포머 계열에서의 위치

  • 인코더 기반 — BERT, ELECTRA (이해 중심)
  • 인코더-디코더 — BART (변환 중심)
  • 디코더 기반GPT 계열 (생성 중심) ← KoGPT2 위치

KoGPT2는 디코더 기반이라 "다음 토큰 예측"에 특화됨. BERT 계열이 문장 분류·개체명 인식에 강하다면, GPT 계열은 자유로운 문장 생성에 강하다. 이 분기가 LLM 시대 디코더 모델 주도의 출발점이다.


3. 모델 로드

허깅페이스 `transformers` 라이브러리는 토크나이저와 모델을 분리해서 로드함. 두 객체가 짝을 이뤄야 정상 동작한다.

3.1 환경 설정

!pip install -q transformers==4.57.3
  • 버전 고정 — 트랜스포머는 API 변경이 잦아 학습 환경 재현성을 위해 버전 명시 권장
  • PyTorch와 TensorFlow 모두 지원 — 본 실습은 TF 버전 사용

3.2 토크나이저와 모델 로드

from transformers import AutoTokenizer, TFGPT2LMHeadModel

# 1. 레포 주소 준비
repo = 'skt/kogpt2-base-v2'

# 2. 토크나이저 로드
tokenizer = AutoTokenizer.from_pretrained(repo)

# 3. 모델 로드 (PyTorch 가중치를 TF로 변환)
model = TFGPT2LMHeadModel.from_pretrained(repo, from_pt=True)
  • AutoTokenizer — 레포에 맞는 토크나이저를 자동 선택
  • TFGPT2LMHeadModel — TensorFlow용 GPT2 모델, LM Head 포함 (다음 토큰 예측용)
  • from_pt=True — PyTorch로 저장된 가중치를 TF로 변환해 로드

LMHead는 "Language Model Head"의 줄임말. 트랜스포머 본체 위에 어휘 크기(51,200) 차원의 출력층을 얹은 구조로, 다음 토큰의 로짓을 출력함. 분류 태스크라면 ForSequenceClassification, 생성이라면 LMHead로 헤드를 갈아끼우는 게 트랜스포머 활용 패턴이다.


4. 기본 문장 생성

`model.generate()` 한 줄로 자동 생성이 가능함. 내부에서 토큰 예측 → 누적 → 재예측을 자동으로 반복해준다.

4.1 생성 흐름 코드

# 1. 프롬프트 입력
text = input('초기 문장을 제시하시오\n').strip()

# 2. 인코딩 (자연어 → 토큰 벡터)
input_vector = tokenizer.encode(text)

# 3. 모델 입력 형태로 변환 (2D 텐서)
input_vector = tf.convert_to_tensor([input_vector])

# 4. 모델로 문장 생성 요청
output = model.generate(
    input_vector,
    max_length=64,
    use_cache=True,
)

# 5. 응답 벡터 추출 후 디코딩 (토큰 → 자연어)
res_vector = output.numpy().tolist()[0]
print(tokenizer.decode(res_vector))

4.2 주요 파라미터

  • max_length — 생성할 최대 토큰 수 (입력 + 생성 토큰 합계)
  • use_cache — KV 캐시 사용 여부, 반복 계산을 줄여 추론 속도 향상
  • tokenizer.encode — 자연어를 토큰 ID 시퀀스로 변환
  • tokenizer.decode — 토큰 ID를 다시 자연어 문장으로 복원

model.generate는 토큰 예측·누적·다음 입력 구성·종료 조건 체크를 전부 캡슐화한 고수준 API. 내부적으로는 greedy search·beam search·sampling 등 다양한 디코딩 전략을 지원하지만, 파라미터 없이 호출하면 기본값(greedy)으로 동작한다.


5. 스트리밍 + Top-K 샘플링

`model.generate`를 쓰면 결과만 받지만, 직접 루프를 짜면 토큰 단위로 출력을 받을 수 있음(스트리밍). 동시에 Top-K 중 랜덤 선택으로 창의성도 부여 가능하다.

5.1 모델 출력 구조

output = model(input)
output.logits.shape  # (1, 4, 51200)
차원  의미
1 문장 개수 (배치 크기)
4 입력 토큰 개수
51200 각 토큰 위치에서 어휘 전체에 대한 로짓
`output.logits[0, -1]`로 마지막 토큰 위치의 51,200개 로짓을 꺼내면, 그게 곧 "다음 토큰 확률 분포"가 된다.

5.2 Top-K 추출

top5 = tf.math.top_k(output.logits[0, -1], k=5)
# TopKV2(
#   values=array([10.48, 10.18, 10.05, 10.02, 9.90]),
#   indices=array([10635, 23879, 12201, 11649, 9745])
# )
  • values — 상위 5개 토큰의 로짓 값
  • indices — 상위 5개 토큰의 사전 인덱스
  • 랜덤 선택 — 5개 중 무작위 1개를 골라 다음 토큰으로 채택

5.3 스트리밍 생성 루프

import random
import numpy as np

text = '안녕하세요, 반갑습니다'
input_vector = tokenizer.encode(text)
start_token_size = len(input_vector)
MAX_TOKEN = 100

while len(input_vector) < (start_token_size + MAX_TOKEN):
    input = np.array([input_vector])
    output = model(input)

    # 마지막 토큰 위치의 Top-5 추출
    top5 = tf.math.top_k(output.logits[0, -1], k=5)

    # Top-5 중 랜덤 선택 (의외성 부여)
    token_id = random.choice(top5.indices.numpy())

    # 입력 벡터에 누적
    input_vector.append(token_id)

    # 토큰 단위 출력 (스트리밍)
    print(tokenizer.decode(token_id), end=' ')

5.4 결정적 vs 창의적 선택

방식  선택 기준 결과 특성
1등 선택 (greedy) 가장 높은 로짓 1개 결정적, 안정적, 단조로움
Top-K 랜덤 상위 K개 중 무작위 의외성, 창의성, 다양성
Top-K + temperature 분포 조정 후 샘플링 창의성 정밀 제어

LLM의 temperature 파라미터(0.0 ~ 1.0)가 정확히 이 개념의 일반화. 0이면 항상 1등(greedy), 높을수록 분포가 평탄해져 다양한 토큰이 뽑힐 확률이 올라간다. ChatGPT API의 top_p, top_k도 모두 같은 계열의 샘플링 파라미터다.


6. 응답 결과 분석

6.1 실제 생성 예시

입력:  죽을뻔했다, 이새끼

생성:  가 왜 이 걸 안 쓰 냐 . 이 거 야 말로 내가 너 한테 한 소리 할
       자격이 있 냐 " 며 "이 렇게 깽 판이 났 는데도 너 를 믿고
       사랑 해 주 신 많은 분 께 머리 끝 을 쥐 었다
       "고 울 부 불 끓 어 오르는 마음을 전 하며 눈물을 훔 치기도 했다.
  • 자연스러운 한국어 — 조사·어미 결합이 어색하지 않음
  • 맥락 유지 — "이새끼"라는 거친 입력에 대응되는 갈등 상황 묘사가 이어짐
  • 의외성 — 같은 입력이라도 매번 다른 결과 (Top-K 랜덤이라 비결정적)

6.2 토큰 단위 띄어쓰기

생성 결과를 보면 토큰 단위로 띄어쓰기가 분리됨. KoGPT2는 BPE(Byte Pair Encoding) 기반 서브워드 토크나이저를 쓰기 때문에 "깽/판이", "머리/끝/을"처럼 형태소보다 작은 단위로 쪼개진다.

토큰 단위 출력이 어색해 보일 수 있지만, 실제로는 후처리 단계에서 토큰을 이어 붙이고 정규화한다. 모델 자체는 "다음 토큰" 예측만 충실히 수행할 뿐, 사람이 읽기 좋은 형태로 다듬는 건 별개 작업이다.


7. 제로샷 러닝의 의미

7.1 학습 패러다임 비교

방식  데이터 필요량 시간/비용 활용도
처음부터 학습 매우 많음 매우 큼 도메인 한정
파인튜닝 적당량 중간 도메인 적용
퓨샷 러닝 소량(예시 몇 개) 작음 즉시 적용 가능
제로샷 러닝 0 0 범용 사용

7.2 제로샷이 가능한 이유

  • 사전 학습의 일반화 — 대규모 코퍼스로 학습하면 다양한 패턴이 내장됨
  • 트랜스포머의 표현력 — 어텐션이 토큰 간 관계를 직접 모델링해 맥락 일반화
  • 언어의 통계적 본질 — 다음 토큰 예측이라는 단일 태스크가 거의 모든 NLP 태스크를 포괄

제로샷 러닝이 작동하는 이유는 "충분히 큰 모델은 학습 중에 다양한 태스크 패턴을 자연스럽게 흡수한다"는 발견 때문. GPT3에서 이 특이점이 명확히 드러나면서 비공개로 전환되고, 본격적인 LLM 시대가 시작됐다. KoGPT2는 그 흐름의 한국어 버전 입문 사례다.


8. 요약

  • 제로샷 러닝 — 사전 학습된 모델을 추가 학습 없이 그대로 사용하는 방식, 별도 데이터·시간 없이 즉시 활용 가능
  • 업스트림 / 다운스트림 — GPT2(다국어) → KoGPT2(한국어 파인튜닝)의 전이 학습 흐름
  • 모델 로드 패턴 — AutoTokenizer.from_pretrained() + TFGPT2LMHeadModel.from_pretrained() 두 객체 짝으로 사용
  • model.generate — 토큰 예측·누적·종료 조건을 캡슐화한 고수준 API, 간편하지만 출력 제어가 제한적
  • 스트리밍 + Top-K — 직접 루프를 짜면 토큰 단위 출력과 창의성 제어가 모두 가능, LLM의 temperature와 동일 원리
  • 모델 출력 shape — (batch, seq_len, vocab_size)에서 마지막 토큰 위치의 로짓이 곧 다음 토큰 확률 분포
단계  generate 방식 수동 루프 방식
출력 형태 완성된 문장 한 번에 반환 토큰 단위 스트리밍
선택 전략 파라미터로 제어 직접 구현 (Top-K, 랜덤 등)
창의성 제어 temperature, top_k 파라미터 코드 레벨에서 자유롭게
개발 편의성 높음 낮음 (직접 토큰 누적 관리)

문장 생성의 본질은 "다음 토큰 확률 분포에서 어떻게 하나를 뽑을 것인가"의 문제로 귀결됨. 모델은 51,200개 어휘에 대한 로짓을 출력할 뿐이고, 그중 어떤 토큰을 어떤 전략으로 고르느냐가 생성 품질의 다양성을 결정한다. 결정적 선택은 단조롭고, 완전 랜덤은 의미를 잃는다. 그 사이의 균형이 LLM API의 temperature·top_k·top_p 파라미터로 추상화돼 있으며, 본 실습은 이 추상화 안쪽에서 벌어지는 일을 직접 구현해서 확인하는 과정이었다.

'SK플래닛 ai활용 데이터엔지니어 과정 2기 > ML & DL' 카테고리의 다른 글

LLM 2 - 서비스 구축 실습  (0) 2026.05.29
LLM 1 - 프롬프트, 컨텍스트  (1) 2026.05.28
DL 5 - NLP 실습  (0) 2026.05.27
DL 4 - NLP 모델  (0) 2026.05.26
DL 3 - CNN  (0) 2026.05.26