GPT

Jaemyeong Lee·2026년 1월 21일

AI

목록 보기
1/1

1. 자연어 처리 기초

1.1 학습 목표

1.1.1 GPT-3 등장

  • 하나의 모델로 다양한 업무를 하려는 흐름
  • Pretrain → Transfer
  • Few-shot / Zero-shot

1.1.2 Transformer의 중요성

  • RNN/LSTM의 한계를 Attention으로 해결

1.1.3 NLP의 핵심 난제

  • 순서가 의미를 바꿈
  • 단어 하나 변화가 의미 및 라벨을 뒤집음 (ex: “안”)
  • 토큰화와 OOV(사전에 없는 단어)가 실무 난이도를 크게 좌우

1.1.4 기초 수식

  • 언어 모델 확률(체인 룰)
  • 내적 = 유사도
  • softmax가 확률이 되는 이유

1.2 GPT-3

1.2.1 GPT-3 방향성

  • Task마다 모델을 새로 만들고 라벨을 많이 모아 학습하는 방식은 비용이 큼
  • 큰 모델을 미리 학습(Pretrain)해두고, 적은 예시(Few-shot) 또는 예시 없이(Zero-shot) 다양한 Task를 수행하게 하려는 방향

1.2.2 GPT-3 핵심 동기

  • Transformer가 번역에서 성공 → “Transformer 구조로 더 잘할 수 없을까?”
  • Task 및 Domain이 바뀌면 성능이 떨어지는 문제
  • 다양한 데이터로 미리 학습하면 새로운 Task 적응이 쉬워진다로 개념 발전

1.3 Transformer 핵심

  • Attention
  • Positional Encoding

1.3.1 Self-Attention

  • 문장 안의 각 토큰이 문장 내 다른 토큰들을 참고해서 자기 표현을 업데이트
토큰 i의 새 표현 = (토큰 1을 보는 비율)*v1
               + (토큰 2를 보는 비율)*v2
               + ...
               + (토큰 n을 보는 비율)*vn

1.3.2 Positional Encoding

  • Transformer는 구조적으로 순서 정보가 자동으로 들어가지 않음
  • 토큰 위치 정보를 숫자 벡터로 추가해서 순서를 인지하게 만들어야 함

1.4 데이터 관점 비교

1.4.1 Tabular vs Vision vs NLP

구분Tabular(테이블)Vision(이미지)NLP(자연어)
핵심 구조피처(열) 기반픽셀 로컬리티(근처가 중요)토큰 순서/의존성(멀리도 중요)
위치 변화 영향보통 “열 의미 고정”이동해도 비슷(완전 불변은 아니지만 CNN이 강함)위치 바뀌면 의미 크게 변함
작은 변화의 영향열 하나 변화는 보통 점진적픽셀 1개 변화는 대체로 영향 작음(일반적)단어 1개(“안”)가 라벨 뒤집기도
대표 모델 가정독립/약한 상관 가정이 쉬움locality, (translation) equivariancelong-range dependency, order-sensitive

1.5 토큰화

1.5.1 토큰화란

  • 문장을 모델이 먹을 수 있는 단위로 쪼개고 각 조각을 숫자로 바꾸는 과정

1.5.2 토큰화 단위

  • Character

    • 예: 나는 → [나, 는]
    • 장점: OOV 거의 없음
    • 단점: 길이 폭증, 의미 단위가 약함
  • Space

    • 예: I love apples → [I, love, apples]
    • 장점: 단순함
    • 단점: “tokenization!” vs “tokenization” 같은 변형에 취약, 한국어는 공백이 의미 단위와 안 맞는 경우가 많음
  • Punctuation

    • 구두점 기준 분리
    • 장점: 일부 개선
    • 단점: 근본 해결은 아님
  • Subword

    • 예: unbelievable → [un, believe, able]
    • OOV를 크게 줄이면서 길이 폭증도 완화
    • 대표: GPT 계열(BPE), BERT 계열(WordPiece)

1.6 언어 모델

  • 문장을 확률로 모델링

1.6.1 문장 확률

  • 체인 룰(Chain Rule)로 분해
  • 문장을 단어들의 나열로 보면 길이 (T)인 문장은 다음처럼 표현 가능
(W1,W2,,WT)(W_1, W_2, \ldots, W_T)
  • 문장 전체 결합확률은 체인 룰로 다음처럼 분해
P(W1,W2,,WT)=t=1TP(WtW<t)P(W_1, W_2, \ldots, W_T) = \prod_{t=1}^{T} P(W_t \mid W_{<t})
  • 여기서 (W_{<t})는 “(t)번째 단어 이전까지의 모든 단어들”을 의미

    • P(W1)P(W_1) : 첫 단어가 나올 확률
    • P(W2W1)P(W_2 \mid W_1) : 첫 단어가 주어졌을 때 두 번째 단어 확률
    • P(W3W1,W2)P(W_3 \mid W_1, W_2) : 앞의 두 단어가 주어졌을 때 세 번째 단어 확률
    • P(WTW1,,WT1)P(W_T \mid W_1, \ldots, W_{T-1}) : 이전 단어들이 주어졌을 때 마지막 단어 확률
  • 언어 모델은 한 문장을 한 번에 통째로 외우는 게 아님

  • 즉, “지금까지 단어들이 주어졌을 때 다음 단어 확률”을 반복적으로 예측하고 그 확률들을 곱해서 문장 전체 확률을 구성


1.7 평가 지표

  • 왜 번역/생성은 “정답률(Accuracy)”로 끝나지 않나

  • 번역/요약/생성 태스크는 정답이 한 가지로 고정되지 않음

  • 같은 의미라도 표현이 여러 가지가 가능하므로, “정확히 일치”만 보는 정답률로는 평가가 어려움

  • 따라서 BLEU/ROUGE 같은 자동 평가 지표가 등장

1.7.1 핵심 지표 정리

  • BLEU

    • 핵심: n-gram precision(겹치는 조각 비율) + brevity penalty(짧은 번역 패널티)
    • 장점: 자동 평가 가능
    • 한계: 의미가 같아도 표현이 다르면 낮게 나올 수 있음
  • ROUGE

    • 요약에서 많이 사용
    • 성격: recall에 가까움(참고 요약의 내용이 얼마나 포함됐나)
    • 대표: ROUGE-N, ROUGE-L
  • METEOR

    • 정렬(alignment) 관점이 강하고, 어간(stemming), 동의어 등을 고려(세부는 설정/버전에 따라 차이)
  • Human Evaluation

    • 여전히 중요
    • 기준 예시: Adequacy(의미), Fluency(자연스러움)
    • pairwise 비교(둘 중 더 좋은 것 선택)가 안정적

1.8 트랜스포머 이전: RNN/LSTM 인코더-디코더(Seq2Seq)

  • “문맥(context)을 하나로 요약하고 싶다” → 인코더-디코더 구조가 자연스럽게 등장

1.8.1 RNN 구조(시간축으로 펼침)

x1 -> [RNN] -> h1
            -> (다음으로 전달)
x2 -> [RNN] -> h2
x3 -> [RNN] -> h3
...
  • (x_t): t번째 입력(토큰 임베딩)
  • (h_t): t번째 은닉 상태(문맥 누적 정보)

1.8.2 인코더-디코더(번역) 개념

(Encoder)  한국어 토큰들 -> h1,h2,...,hT -> (context 요약)
(Decoder)  context + 이전 출력 -> 다음 단어 생성 -> ...
  • 인코더: 입력 문장을 읽고 표현을 만듦
  • 디코더: 인코더 요약(context) + 이전 출력 토큰을 바탕으로 다음 토큰 생성

1.8.3 한계가 생기는 이유

  • 정보 병목(Bottleneck): 긴 문장을 하나의 context 벡터로 압축 → 앞부분 정보 손실
  • 순차 처리의 한계: 병렬화가 어려움
  • 장기 의존성 문제: 멀리 떨어진 정보 연결이 어렵고 학습이 불안정(대표: vanishing gradient)

1.9 Attention

  • 어느 단어(토큰)에 더 집중할지 학습하여 중요한 정보에 더 큰 가중치를 주는 메커니즘

  • 강의 요지

    • “I do not like …”에서 핵심은 not
    • 번역은 단어 정렬(alignment)이 중요 (한국어 앞 단어가 영어 뒤로 갈 수도 있음)

1.9.1 디코더-인코더 Attention 직관(Seq2Seq Attention)

  • 디코더가 출력 토큰 하나(시점 (j))를 만들 때,
  • 인코더의 모든 상태 ((h_1, \ldots, h_T)) 중 어디를 얼마나 참고할지(가중치)를 계산한다.

(1) 유사도 점수(score) 계산

scorej,i=similarity(sj,hi)\text{score}_{j,i} = \mathrm{similarity}(\mathbf{s}_j, \mathbf{h}_i)

(2) softmax로 가중치(attention weight) 만들기

αj,i=exp(scorej,i)k=1Texp(scorej,k)\alpha_{j,i} = \frac{\exp(\text{score}*{j,i})} {\sum*{k=1}^{T}\exp(\text{score}_{j,k})}

(3) 가중합으로 컨텍스트 벡터(context vector) 만들기

cj=i=1Tαj,i,hi\mathbf{c}*j = \sum*{i=1}^{T} \alpha_{j,i},\mathbf{h}_i

기호 의미

  • sj\mathbf{s}_j : 디코더의 (j)번째 상태(hidden state)

  • hi\mathbf{h}_i : 인코더의 (i)번째 상태(hidden state)

  • αj,i\alpha_{j,i} : (j)번째 출력 생성 시 (i)번째 입력을 얼마나 참고할지 나타내는 가중치

    • i=1Tαj,i=1\sum_{i=1}^{T}\alpha_{j,i} = 1
  • cj\mathbf{c}_j : 디코더 (j)시점의 컨텍스트 벡터(입력 정보를 정렬+요약해서 제공)

1.9.2 전사본 표현 교정(중요)

  • 핵심 흐름은 동일: 유사도 점수 → softmax → 가중합
  • 다만 실제 구현은 여러 변형이 존재한다.

(1) 전통 Seq2Seq Attention의 대표 변형

  • Dot-product(내적 기반)
similarity(sj,hi)=sjhi\mathrm{similarity}(\mathbf{s}_j, \mathbf{h}_i) = \mathbf{s}_j^{\top}\mathbf{h}_i
  • Additive(Bahdanau, MLP 기반)
similarity(sj,hi)=vtanh(Wssj+Whhi)\mathrm{similarity}(\mathbf{s}_j, \mathbf{h}_i) = \mathbf{v}^{\top}\tanh(W_s\mathbf{s}_j + W_h\mathbf{h}_i)

(2) 트랜스포머 Attention과의 연결

  • 트랜스포머는 같은 아이디어를 (Q, K, V)로 재구성해 효율적으로 만든 형태다.
Attention(Q,K,V)=softmax(QKdk)V\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\left(\frac{QK^{\top}}{\sqrt{d_k}}\right)V

1.10 선형대수 기초

  • 목표

수식을 봤을 때 “아 유사도구나 / 아 확률로 바꾸는구나”를 즉시 캐치하기

1.10.1 벡터/행렬/전치(Transpose)

  • 벡터(열벡터)
hRd×1\mathbf{h} \in \mathbb{R}^{d \times 1}
  • 전치(Transpose)
hR1×d\mathbf{h}^{\top} \in \mathbb{R}^{1 \times d}
  • 내적(Dot product): 결과는 스칼라
hgR\mathbf{h}^{\top}\mathbf{g} \in \mathbb{R}

1.10.2 내적이 왜 “유사도” 느낌인가?

(1) 코사인 유사도에 내적이 포함됨

cos(θ)=aba,b\cos(\theta) = \frac{\mathbf{a}^{\top}\mathbf{b}}{\lVert \mathbf{a}\rVert,\lVert \mathbf{b}\rVert}
  • 방향이 비슷할수록 값이 커짐
  • 정규화하면 내적이 곧 “방향 유사도”처럼 동작

(2) 거리(distance) 전개에도 내적이 등장

xy2=xx2xy+yy\lVert \mathbf{x}-\mathbf{y}\rVert^{2} = \mathbf{x}^{\top}\mathbf{x} - 2\mathbf{x}^{\top}\mathbf{y} + \mathbf{y}^{\top}\mathbf{y}
  • xy\mathbf{x}^{\top}\mathbf{y} 가 커질수록(더 비슷할수록) 거리는 작아지는 구조
  • 그래서 내적은 “유사도”로 자주 쓰인다

1.10.3 softmax가 왜 “확률”이 되나?

  • softmax 정의
softmax(zi)=ezikezk\mathrm{softmax}(z_i) = \frac{e^{z_i}}{\sum_{k} e^{z_k}}
  • 항상 0보다 큼
  • 전체 합이 1
  • 미분이 깔끔해 학습에 유리

✅ 실무 팁(수치 안정성)

softmax(z)i=ezimax(z)kezkmax(z)\mathrm{softmax}(\mathbf{z})*i = \frac{e^{z_i - \max(\mathbf{z})}}{\sum*{k} e^{z_k - \max(\mathbf{z})}}
  • overflow 방지를 위해 보통 (\max(\mathbf{z}))를 빼고 계산
  • 정규화 구조 때문에 결과 확률은 동일하게 유지된다

1.11 트랜스포머로 돌아오기: 왜 GPT/BERT가 여기서 나왔나?

  • 트랜스포머는 RNN의 순차 처리를 버리고, Attention으로 문장 내 관계를 한 번에 계산할 수 있게 만든 구조

1.11.1 트랜스포머 Attention 블록(자체완결)

입력 X (토큰 임베딩 + 포지션)  [n x d]

Q = XWq
K = XWk
V = XWv

A = softmax( QK^T / sqrt(dk) )   [n x n]  // 토큰-토큰 관계표
출력 = A V                        [n x d]
  • (A): 토큰-토큰 관계(어느 토큰이 어느 토큰을 얼마나 참고하는지)

1.11.2 Multi-Head가 왜 필요?

  • 한 번의 관계표만으로는 관계의 종류를 다양하게 담기 어려움
  • 여러 헤드가 서로 다른 관점(문법/의미/지시어/장거리 의존 등)으로 관계를 학습

1.12 GPT vs BERT: 같은 트랜스포머지만 목표가 다르다

모델구조학습 목표강점
GPT 계열Decoder-only다음 토큰 예측(Autoregressive)생성, 프롬프트 기반 적응(Few/Zero-shot)
BERT 계열Encoder-only마스크 채우기(Masked LM)분류/추출(QA span 등)에서 강함

1.12.1 전사본 표현 교정(중요)

  • 트랜스포머도 임베딩 레이어(토큰 ID → 벡터)는 반드시 존재
  • 다만 word2vec처럼 임베딩을 따로 만들고 고정하기보다,
  • 모델 학습 과정에서 임베딩까지 end-to-end로 같이 최적화하는 경우가 일반적
    → “임베딩을 따로 튜닝하는 비중이 줄었다”로 이해하면 자연스럽다

아래는 네가 준 내용을 강의 흐름 그대로 유지하면서, Velog에서 수식이 절대 안 깨지게 $$ ... $$로 통일하고, ASCII/표/shape 추적/핵심 교정까지 “교재” 톤으로 완성한 최종본이야.
(원문에 있던 [ ] 수식 표기, 괄호/슬래시/루트 표기 흔들림, 인덱스 표기 혼동을 전부 정리했어.)


2. Transformer

1) Transformer

1.1 트랜스포머는 “인코더-디코더” 구조

  • 입력 문장(소스)을 Encoder가 이해(표현 벡터로 변환)
  • 출력 문장(타겟)을 Decoder가 생성(한 토큰씩)

슬라이드의 큰 흐름은 다음처럼 잡으면 된다.

Input (token + position)
 -> Encoder blocks (self-attention + FFN)
 -> Decoder blocks (masked self-attention + cross-attention + FFN)
 -> Linear + Softmax
 -> Output tokens

1.2 트랜스포머가 RNN보다 유리했던 이유

  • 병렬 처리 가능: 토큰을 순차적으로 처리하지 않고, 한 번에 행렬 연산으로 처리
  • 번역 태스크에서 성능(BLEU)과 효율이 강점으로 제시됨
  • 이후 BERT/GPT가 트랜스포머 블록을 채택하면서 “사전학습 → 적응”의 표준이 됨

2) Positional Encoding

2.1 왜 필요한가?

  • RNN은 입력이 x1 → x2 → x3 ... 순서대로 들어오므로 순서 정보가 구조에 내장
  • 트랜스포머는 병렬 처리로 토큰을 동시에 다루므로, 그냥 두면 토큰의 위치를 모름
  • 그래서 토큰 임베딩에 위치 정보를 더해 순서를 주입한다

입력 단계(개념)

token ids -> Embedding(d_model)
          -> + PositionalEncoding(d_model)
          -> Encoder/Decoder blocks

2.2 “그럼 위치를 숫자로 주면 되지 않나?”가 왜 위험한가

(A) 그냥 0,1,2,3… 더하기

  • 값 스케일이 커지며 학습 안정성(초기 분포, 스케일)이 흔들릴 수 있음

(B) 0~1 정규화 (예: 0, 0.33, 0.66, 1)

  • 문장 길이가 바뀌면 같은 “2번째 토큰”도 값이 바뀜
    같은 위치가 일관된 의미를 갖기 어려움

(C) 원-핫/이진 벡터

  • 길이에 무관하게 같은 위치에 같은 벡터를 할당 가능
  • 하지만 위치 간 상대 거리/기하학적 관계를 표현하기가 까다로움(왜곡 가능)

2.3 Sinusoidal Positional Encoding (원 논문 정석)

  • 짝수 차원에는 sin, 홀수 차원에는 cos를 번갈아 사용
PE(pos,2i)=sin(pos100002idmodel)PE(pos, 2i) = \sin\left(\frac{pos}{10000^{\frac{2i}{d_{model}}}}\right)
PE(pos,2i+1)=cos(pos100002idmodel)PE(pos, 2i+1) = \cos\left(\frac{pos}{10000^{\frac{2i}{d_{model}}}}\right)

직관(강의 흐름 정리)

  • sin/cos 범위는 대략 ([-1, 1]) → 스케일 폭주 방지
  • 차원마다 주파수가 달라서 짧은/긴 거리 관계를 다양한 해상도로 표현
  • “위치 변화가 벡터를 회전시키는 것처럼” 이해해도 직관적으로 도움이 됨

2.4 (실전) Positional Encoding 구현 예시 (이해용)

import numpy as np

def positional_encoding(max_len: int, d_model: int) -> np.ndarray:
    pos = np.arange(max_len)[:, None]              # (max_len, 1)
    i = np.arange(d_model)[None, :]                # (1, d_model)

    angle_rates = 1 / (10000 ** (2 * (i // 2) / d_model))
    angles = pos * angle_rates                     # (max_len, d_model)

    pe = np.zeros_like(angles)
    pe[:, 0::2] = np.sin(angles[:, 0::2])          # even
    pe[:, 1::2] = np.cos(angles[:, 1::2])          # odd
    return pe                                      # (max_len, d_model)

3) Self-Attention / Scaled Dot-Product Attention

3.1 Q, K, V를 한 문장으로

  • Query(Q): “지금 내가 무엇을 찾고 싶은가?”
  • Key(K): “각 토큰이 어떤 특징을 갖고 있어 매칭 기준이 되는가?”
  • Value(V): “매칭되면 실제로 가져올 정보(내용)는 무엇인가?”

요약하면, 관계의 기준(Q/K)과 실제 내용(V)을 분리하면 표현력이 좋아진다는 흐름이다.


3.2 수식(정석)

Attention(Q,K,V)=softmax(QKdk)V\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\left(\frac{QK^{\top}}{\sqrt{d_k}}\right)V

“Scaled(/sqrt(d_k))”의 의미 (중요)

  • 내적 (QK^\top)는 차원 (d_k)가 커질수록 값의 분산이 커지기 쉬움
  • 그대로 softmax에 넣으면 값이 과도하게 커져 softmax가 포화(거의 0/1) → 학습 불안정
  • 그래서 (\sqrt{d_k})로 나눠 스케일을 안정화한다

3.3 차원(shape) 추적 (구현 실수 방지 핵심)

시퀀스 길이 (L), 모델 차원 (d_{model}), 헤드 차원 (d_k, d_v)

항목shape
입력 (X)((L, d_{model}))
(W^Q, W^K)((d_{model}, d_k))
(W^V)((d_{model}, d_v))
(Q=XW^Q)((L, d_k))
(K=XW^K)((L, d_k))
(V=XW^V)((L, d_v))
(QK^\top)((L, L))
(\mathrm{softmax}(QK^\top/\sqrt{d_k}))((L, L))
출력 ((\cdot)V)((L, d_v))

강의의 “(3×4)·(4×2)=(3×2)” 감각은 맞지만, 실제로는 X와 W의 shape를 일관되게 유지하는 게 핵심이다.


4) Masked Self-Attention (왜 디코더에서만 마스크?)

4.1 이유: 생성(Autoregressive)은 “미래 토큰”을 보면 안 됨

  • 디코더는 다음 단어를 예측해야 함
  • 예: I love you에서 love를 예측할 때, 미래 토큰 you를 보면 치팅
  • 그래서 디코더 self-attention에는 look-ahead mask(상삼각 마스크)를 적용한다

마스크 직관

허용: 과거/현재
금지: 미래

t=2일 때 볼 수 있는 범위: [1..2]

4.2 구현 관점(핵심)

  • 마스크로 가려지는 위치의 score에 매우 작은 값을 더함(실제로는 (-\infty)에 가까운 값)
  • softmax를 거치면 해당 확률이 거의 0이 되어 영향이 사라짐

5) Multi-Head Attention (왜 헤드를 여러 개 쓰나?)

5.1 직관(강의 흐름)

  • 어떤 헤드는 주어-동사 관계를 강하게 보고
  • 어떤 헤드는 지시어/대명사 관계를 보고
  • 어떤 헤드는 구문 패턴을 본다
    → 한 가지 attention만으로 모든 관계를 잡기 어렵기 때문에 여러 관점(헤드)으로 본다

5.2 수식(정석)

headi=Attention(QWiQ,;KWiK,;VWiV)\mathrm{head}_i = \mathrm{Attention}(QW_i^Q,; KW_i^K,; VW_i^V)
MultiHead(Q,K,V)=Concat(head1,,headh)WO\mathrm{MultiHead}(Q, K, V) = \mathrm{Concat}(\mathrm{head}_1, \ldots, \mathrm{head}_h)W^O

5.3 차원 설계 (Residual을 위한 “차원 맞추기”)

  • residual add를 하려면 입력/출력 차원이 같아야 함
  • 보통 (d_{model})을 헤드 수 (h)로 나눔
dk=dv=dmodelhd_k = d_v = \frac{d_{model}}{h}
  • 각 헤드 출력 concat → 다시 ((L, d_{model}))로 돌아와 residual add 가능

6) Skip Connection + Layer Normalization (Add & Norm)

슬라이드에서도 “성능 향상: Skip / LayerNorm”을 따로 강조한다.

6.1 Residual(Skip) Connection

  • 목적: 깊은 네트워크에서 그라디언트 흐름 개선 + 학습 안정화
y=x+SubLayer(x)y = x + \mathrm{SubLayer}(x)

6.2 LayerNorm (BatchNorm과 차이)

  • BatchNorm: 배치 통계에 의존 → 배치 작으면 불안정
  • LayerNorm: 토큰(샘플) 내부 feature 차원 기준 정규화 → 배치 크기에 덜 민감
방법평균/분산을 어디서 계산?NLP에서 선호
BatchNorm배치 차원배치 작아지면 불리
LayerNormfeature((d_{model})) 차원트랜스포머 표준

7) Encoder/Decoder 블록 전체 흐름 한 장 요약

7.1 Encoder (한 층)

X
 -> Multi-Head Self-Attention
 -> Add & Norm (Residual + LayerNorm)
 -> Feed Forward
 -> Add & Norm

7.2 Decoder (한 층)

Y (shifted right)
 -> Masked Multi-Head Self-Attention
 -> Add & Norm
 -> Encoder-Decoder Attention (Q: decoder, K/V: encoder)
 -> Add & Norm
 -> Feed Forward
 -> Add & Norm

8) (다음 챕터 대비) GPT vs BERT에서 어디가 달라지나?

  • BERT: Encoder-only (양방향 문맥 이해)
  • GPT: Decoder-only (masked self-attention 기반, 다음 토큰 생성)

따라서 이번 파트의 “Positional Encoding, (Masked) Multi-Head Attention, LayerNorm, Residual”은 그대로 GPT/BERT 이해의 기반이 된다.


아래는 네 원문을 강의 흐름 그대로 유지하면서, Velog에서 수식이 깨지지 않도록 전부 $$ ... $$로 통일하고, 표/ASCII/shape 추적/단계별 정리까지 “교재” 톤으로 완성한 최종본이야. 그대로 복붙하면 돼.


3. Transformer for Computer Vision (ViT, DETR)

0) 이 강의에서 얻어야 하는 것 (학습 목표)

  1. 왜 비전에서 트랜스포머를 쓰려 했는지
  2. ViT 핵심 아이디어: 이미지를 토큰 시퀀스로 바꿔 Transformer Encoder에 넣기
  3. DETR 핵심 아이디어: Detection을 집합(set) 예측으로 바꾸고 NMS 제거
  4. 두 모델 모두에서 Positional Encoding/Embedding이 왜 필수인지
  5. 면접/실무에서 말할 수 있게: 장점·단점·언제 쓰는지

1) 도입: “NLP에서 되면 CV에서도 되지 않을까?” + CNN의 Inductive Bias

1.1 CNN이 강한 이유(Inductive Bias)

CNN은 이미지에 맞는 “가정”이 구조적으로 들어가 있어서, 비교적 적은 데이터에서도 잘 학습되는 경향이 있습니다.

  • 가정 1: 지역성(Locality)
    가까운 픽셀들이 의미를 만든다 → 작은 커널로도 잘 배움
  • 가정 2: 가중치 공유(Weight Sharing)
    같은 패턴(엣지 등)은 위치가 달라도 같은 필터로 잡힌다
  • 가정 3: Translation Equivariance
    물체가 이동하면 feature map도 같이 이동
    (완전한 invariance는 pooling/구조 설계로 얻는 경우가 많음)

1.2 CNN의 취약점(강의 예시를 정확히 정리)

강의의 “눈/코/입 위치가 이상해도 얼굴로 인식” 요지는 다음처럼 정리하면 더 정확합니다.

  • CNN은 국소 패턴은 매우 잘 잡지만,
  • 전역 관계(눈-코-입의 상대 위치)를 “자동으로 강제”하진 않음
  • 따라서 데이터/학습 조건에 따라 부분만 맞으면 전체를 맞다고 착각하는 문제가 생길 수 있음

2) ViT (Vision Transformer) — “이미지를 토큰으로 만든다”

핵심 문장: 이미지를 패치로 쪼개서, 각 패치를 토큰처럼 만들어 Transformer Encoder에 입력한다.


2.1 ViT 전체 흐름 (Step-by-step)

Step 1) Patchify: 이미지를 P×P 패치로 쪼갠다

  • 입력 이미지:
XRH×W×CX \in \mathbb{R}^{H \times W \times C}
  • 패치 크기: (P \times P)
  • 패치 개수:
N=HPWPN = \frac{H}{P}\cdot \frac{W}{P}
  • 각 패치를 펼치기(flatten):
xp,iRP2Cx_{p,i} \in \mathbb{R}^{P^2\cdot C}

shape 추적(예시)

  • 이미지: (224\times224\times3)
  • 패치: (16\times16)
  • 패치 개수: (N=(224/16)^2=14^2=196)
  • 패치 벡터 차원: (16^2\cdot3=768)

Step 2) Linear Projection: 패치를 D차원 토큰으로 바꾼다

  • 학습 가능한 선형 변환(프로젝션):
zi=xp,iWE+b,ziRDz_i = x_{p,i}W_E + b,\quad z_i \in \mathbb{R}^{D}
  • 행렬 차원:
WER(P2C)×DW_E \in \mathbb{R}^{(P^2C)\times D}

Step 3) [CLS] 토큰 붙이기 + Positional Embedding 더하기

  • 분류를 위해 맨 앞에 [CLS] 토큰 추가:
Z0=[zcls;;z1;;;;zN]Z_0 = [z_{\text{cls}};; z_1;; \dots;; z_N]
  • 위치 정보를 잃기 때문에 Positional Embedding을 더함:
Z=Z0+EposZ = Z_0 + E_{\text{pos}}

여기서

EposR(N+1)×DE_{\text{pos}} \in \mathbb{R}^{(N+1)\times D}

Step 4) Transformer Encoder 통과

  • 표준 Encoder 블록(MHSA + FFN + Residual + LayerNorm)을 (L)번 반복

Step 5) MLP Head로 분류

  • 마지막 층 출력에서 [CLS] 위치 벡터를 뽑아 분류:
y^=MLP(Zcls(L))\hat{y} = \mathrm{MLP}(Z^{(L)}_{\text{cls}})

2.2 (중요) ViT는 왜 큰 데이터가 필요했나?

강의의 “그냥 쓰면 훈련이 잘 안 된다”는 말을 원인-결과로 정확히 정리하면:

  • CNN은 이미지에 맞는 inductive bias(지역성/공유/계층)가 있어서
    상대적으로 적은 데이터에서도 안정적으로 학습되는 편
  • 초기 ViT는 그 bias가 약해서
    “무슨 패턴을 우선 배워야 하는지”를 데이터에서 더 많이 배워야 했음
  • 그래서 논문에서 대규모 데이터로 pretrain 후 fine-tune을 강조(JFT-300M 등)

2.3 ViT 시각화 결과(강의 포인트 3가지)

  1. Embedding filter가 low-level 패턴을 학습
  • CNN 1층이 엣지/텍스처를 배우듯, ViT 초기 층에서도 유사 패턴이 나타남
  1. Positional embedding 이후 공간 구조가 드러남
  • 위치 정보가 들어가면서 “가까운 패치끼리 비슷하게 보는 경향” 같은 구조가 관찰
  1. Layer가 깊어질수록 attention distance가 커짐
  • 초기층은 근처 패치, 후반층은 먼 패치까지 보며
    CNN의 receptive field가 넓어지는 느낌과 유사한 현상

2.4 ViT 한 장 요약(면접용)

  • 한 줄: “이미지를 패치 토큰 시퀀스로 바꿔 Transformer Encoder로 분류한다.”
  • 장점: 전역 관계를 MHSA로 직접 모델링
  • 단점(초기 ViT 관점): CNN bias가 약해 큰 데이터/사전학습 의존도가 큼

3) DETR — “Detection을 Set Prediction으로 바꿔 NMS 제거”

강의에서 “DETI”처럼 들린 건 DETR이 맞습니다.
(End-to-End Object Detection with Transformers, ECCV 2020)


3.1 기존 Detection의 골칫거리: 후보 박스가 많아 NMS 필요

  • 앵커/후보가 많아 같은 물체에 박스가 여러 개 겹쳐 나옴
  • 그래서 후처리로 NMS(Non-Maximum Suppression)로 중복 제거

3.2 DETR의 핵심 아이디어 (Step-by-step)

Step 1) Backbone(CNN)으로 feature map 추출

  • ViT처럼 처음부터 패치 토큰화하는 게 아니라,
  • CNN으로 feature map을 뽑고 Transformer에 입력

예:

FRH×W×CF \in \mathbb{R}^{H' \times W' \times C'}

Step 2) feature map을 시퀀스로 펼치고(Flatten), 2D Positional Encoding 추가

  • Flatten 후 시퀀스 길이:
L=HWL = H'\cdot W'
  • 펼친 형태(개념):
XRL×CX \in \mathbb{R}^{L \times C'}
  • 2D 위치 정보를 유지하기 위해 positional encoding을 더함:
XX+EposX \leftarrow X + E_{\text{pos}}

Step 3) Transformer Encoder로 전역 컨텍스트 통합

  • Encoder가 이미지 전체 정보를 통합한 표현을 만든다

Step 4) Decoder에 “Object Queries”를 넣는다 (DETR 감성 핵심)

  • 고정 개수 (N_q)개의 학습 가능한 query 벡터
QRNq×dmodelQ \in \mathbb{R}^{N_q \times d_{model}}
  • 각 query가 “하나의 물체 슬롯”처럼 동작하도록 학습된다

Step 5) 각 query 출력에서 (클래스, 박스) 예측

  • 각 query마다 출력:

    • class logits: (K) classes + no-object
    • box: ((c_x, c_y, w, h)) (보통 정규화)

3.3 no-object 클래스는 왜 필요?

고정 개수 query를 쓰면, 이미지에 물체가 2개여도 query는 예를 들어 100개일 수 있습니다.

  • 남는 query들은 “아무 물체도 담당하지 않음”이어야 함
  • 그래서 no-object 클래스가 필요하다

3.4 NMS를 없애는 핵심 장치: Bipartite Matching + Hungarian Algorithm

핵심 목표

“각 GT(정답 물체)에 예측 query를 1개씩만 매칭하자.”
→ 그러면 같은 물체를 여러 query가 중복 예측하는 학습이 줄어듦 → NMS 의존이 감소

Step-by-step

  1. 예측 (Nq)개와 GT (N{gt})개의 비용(cost) 행렬 구성
  2. 비용 합이 최소가 되는 1:1 매칭을 찾음 (Hungarian Algorithm)
  3. 그 매칭 결과로 loss를 계산하고 학습

3.5 DETR Loss를 “직관”으로 이해하기

보통 손실은 다음 두 덩어리로 이해하면 충분합니다.

  • Class loss: 각 query가 어떤 클래스인지(or no-object인지)

  • Box loss: 박스 좌표가 얼마나 맞는지

    • L1 loss
    • IoU 계열 손실(GIoU 등)을 함께 쓰는 경우가 많음

헝가리안 매칭은 “loss를 최소화하는 1:1 매칭을 고르는 과정”으로 이해하면 정확합니다.


4) ViT vs DETR vs CNN 한 번에 정리

구분CNN(전통)ViTDETR
입력 표현픽셀→컨볼루션패치→토큰 시퀀스CNN feature map→시퀀스
핵심 강점적은 데이터에도 강함(bias)전역 관계 모델링이 깔끔NMS 제거, end-to-end set prediction
포지션 처리구조적으로 내재(공간)pos embedding 필수2D pos encoding 필수
주 용도분류/검출/세그 전반분류(원형)오브젝트 디텍션

4. Transformer for Time Series (Informer 중심)

0) 이 파트 한 줄 목표

시계열 예측은 입력 길이 (L)이 매우 길어지기 쉬워서 Self-Attention 비용이 (O((O(L2L^2)))) 로 폭증한다.
Informer(AAAI 2021) 는 이를 줄이기 위해 중요한 Query만 골라 계산하는 ProbSparse Attention으로 효율을 높여 Long Sequence Forecasting을 가능하게 하려는 모델이다.


1) 용어/발화 오류 교정 (강의 이해 필수)

강의에서 들린 표현올바른 표현설명
“트리플 AI”AAAI인공지능 분야 주요 학회 (AAAI Conference)
“리스트 / NS팀”LSTM시계열에서 전통적으로 많이 쓰던 RNN 계열
“인포멀/인포먼트”InformerLong sequence time-series forecasting 모델
“커다리티/쿼드리티”Quadratic complexity길이 (L)에서 비용이 (O(L^2))로 증가
“프로보스/프로모션 어텐션”ProbSparse Attention활성 Query만 골라 attention 계산
“확인 페이스”Hugging Face모델/코드 공유 플랫폼
“기타에서 다운”GitHub에서 다운코드 저장소

✅ 중요한 정정 1 — 샘플링 예시 숫자

강의에서 “30초 + 100kHz → 3000개 입력”이라고 했다면 수치가 어긋나 있어요.

  • 100kHz = 초당 100,000 샘플
  • 30초면:
L=30×100,000=3,000,000L = 30 \times 100{,}000 = 3{,}000{,}000

3,000,000개가 맞습니다.
“3000개”라는 발화는 실제 의도가 100Hz(초당 100샘플) 정도였을 가능성이 큽니다.


2) 왜 시계열은 Transformer가 힘든가? (핵심 논리 Step-by-step)

Step 1) 시계열은 입력 길이 (L)이 매우 길어지기 쉽다

  • 자연어 문장은 보통 수십~수백 토큰
  • 센서/로그/계측 데이터는 초당 샘플이 누적되어 수천~수백만 포인트까지 늘어남

Step 2) Self-Attention은 (L\times L) 어텐션 행렬이 생긴다

기본 self-attention은 다음을 계산한다.

A=softmax(QKdk)A = \mathrm{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)

여기서 (A)의 shape는:

ARL×LA \in \mathbb{R}^{L \times L}

Step 3) 그래서 계산/메모리가 (O(L^2))로 증가한다

예를 들어 (L=3000)이면,

L2=3000×3000=9,000,000L^2 = 3000 \times 3000 = 9{,}000{,}000

어텐션 행렬만 900만 원소가 된다.
여기에 레이어 수, 헤드 수, 배치 크기까지 곱해지면 시계열에서는 큰 부담이 된다.


3) Informer 핵심 아이디어: “모든 Query를 다 계산하지 말자”

강의의 직관은 다음으로 요약할 수 있다.

3.1 Lazy Query vs Active Query

  • Lazy Query: 모든 Key에 대한 attention 분포가 거의 균등(평평)
    → 계산해도 얻는 정보가 적다
  • Active Query: 특정 Key에 attention이 강하게 몰림
    → 중요한 상호작용이므로 계산 가치가 크다
Lazy:   [0.02 0.02 0.02 0.02 ...]  (거의 균등)
Active: [0.60 0.20 0.10 0.05 ...]  (특정 키에 집중)

4) ProbSparse Attention: “Active Query만 뽑아서 계산”

4.1 핵심 아이디어

  • 전체 Query 중에서 상위 (u)개(활성 Query)만 골라 attention을 계산
  • 나머지는 근사/생략하여 비용을 줄인다

강의에서 “Top 6 query” 같은 표현은 보통 다음을 의미한다.

  • 전체 Query 중 상위 (u)개만 attention 계산
  • (u)는 고정 숫자일 수도 있고, 길이 (L)에 따라 정해질 수도 있음(설계/실험에 따라)

✅ 중요한 정정 2 — “uniform처럼 만들자”가 아니라 “uniform에서 멀수록 중요”

강의에서 “uniform(1/Lk)처럼 만들도록 loss를 준다”처럼 들렸다면 오해가 생길 수 있어요.
이 파트는 보통 아래 흐름으로 이해하는 게 자연스럽습니다.

  1. 어떤 Query의 attention 분포가 uniform에 가까우면 (lazy) 정보량이 적다
  2. uniform에서 멀수록 (active) 특정 Key에 집중하므로 중요하다
  3. 따라서 uniform에서 많이 벗어난 Query를 골라 계산한다

즉 결론은:

“uniform처럼 만들자”가 아니라
“uniform에서 많이 벗어난(active) Query를 골라 계산하자” 가 핵심입니다.


5) Informer 예측 구조: Encoder–Decoder 입력 구성

시계열 예측에서는 디코더 입력을 다음처럼 구성하는 방식이 흔합니다.

5.1 Encoder input / Decoder input

  • Encoder input ((X_{enc})): 과거 관측 시계열(긴 구간)

  • Decoder input: 두 부분으로 구성

    1. 과거 끝부분 일부(known tail): 실제 관측값 일부를 넣어 시작점을 제공
    2. 미래 구간 placeholder: 예측할 길이만큼 0 또는 마스크 값으로 자리만 확보

5.2 전체 흐름(그림)

flowchart LR
  A[Past series X_enc] --> Enc[Encoder]
  B[Known tail tokens] --> DecIn[Decoder input]
  C[Future placeholders (zeros/mask)] --> DecIn
  Enc --> Dec[Decoder]
  DecIn --> Dec
  Dec --> Yhat[Forecast Y_hat]
  Ytrue[Ground truth future] --> Loss
  Yhat --> Loss

5.3 학습은 어떻게 진행되나?

  • 디코더 출력 (\hat{Y})를 실제 미래 (Y)와 비교해 loss(MSE 등)를 최소화하도록 학습

예:

L=1Tt=1T(YtY^t)2\mathcal{L} = \frac{1}{T}\sum_{t=1}^{T} (Y_t - \hat{Y}_t)^2

핵심은 “긴 시퀀스를 다 보는 대신, 계산할 attention을 줄여 효율을 확보”하는 방향입니다.


6) 차원(shape) 추적 (구현 시 실수 방지)

시퀀스 길이 (L), 모델 차원 (d_{model}), 헤드 차원 (d_k)

항목shape
입력 (X)((L, d_{model}))
(Q, K, V)((L, d_k)), ((L, d_k)), ((L, d_v))
(QK)(QK^\top)((L, L))
(A=softmax(QK/dk))(A=\mathrm{softmax}(QK^\top/\sqrt{d_k}))((L, L))
출력 (AV)((L, d_v))

Informer는 여기서 모든 Query에 대해 (L×L)(L\times L) 계산을 하지 않도록 줄이는 게 핵심이다.


5 BERT & GPT

5.1 이 교재 사용법

  1. [타임라인 ↔ 슬라이드]로 “지금 강의가 어느 페이지인지” 먼저 잡습니다.
  2. 각 파트는 아래 순서로 공부하면 가장 안정적으로 이해가 됩니다.
  • 정확 용어/정의(발화 오류 교정 포함)
  • 핵심 직관(그림/표로 요약)
  • 수식(슬라이드/논문식 형태로 정확 표기 + 의미 해설)
  • 면접/실무 답변 템플릿(15초 요약)

5.2 강의 음성 TXT ↔ 슬라이드 싱크 맵 (PDF 페이지 기준)

음성(대략)PDF 페이지주제싱크 포인트(음성 키워드)
00:02–02:51p2–p4왜 BERT/GPT가 중요해졌나“레이블 만들기 어렵다”, “자연어는 데이터는 많다”
02:51–07:22p3–p4레이블링 난이도/데이터 특성 비교번역/요약 “정답 정의가 애매”, “투표/다수결”
07:22–14:44p5–p6(CV 예시로) 프리트레인–파인튜닝 / 트랜스퍼러닝“로우레벨/하이레벨”, “파라미터 고정(Freeze)”
15:38–18:19p7few-shot / zero-shot 직관“서포트셋/쿼리셋”, “유사도 기반”
18:34–24:01p8–p10용어가 엄밀하지 않다 + 도메인/러닝 패러다임 정의“도메인=joint distribution”, “소스/타겟”
24:29–34:20p11–p19GPT-1“Generative Pre-Training”, “2-stage”, “L1/L2/L3”
35:14–50:18p20–p35BERT“bi-directional”, “MLM + NSP”, “segment embedding”
50:18–58:56p36–p44GPT-2“WebText”, “BPE”, “zero-shot”
58:56–01:05:03p45–p49GPT-3 + 요약“few-shot”, “gradient update 없이”, “정리 표”

5.3 강의에서 자주 헷갈린 용어/표현 정정 표

음성에서 들리는 표현정식 용어한 줄 정의
“버터”BERTEncoder 기반 + MLM(마스크 토큰 복원) 중심 사전학습
“지피티”GPTDecoder 기반 + Causal LM(다음 토큰 예측) 중심
“언슈퍼바이즈 프리트레이닝”Self-supervised pretraining레이블 없이 예측 과제(MLM/다음토큰)로 학습
“트랜스포머 러닝” (문맥상)Transfer learning소스에서 학습한 표현/가중치를 타겟 태스크로 전이
“어블레이션”Ablation study요소를 제거/변형하며 성능 기여도를 확인
“바이디렉셔널”Bidirectional (BERT)좌/우 문맥을 함께 보며 표현학습
“레프트-투-라이트”Causal / Autoregressive (GPT)과거 토큰만 보고 다음 토큰을 예측(미래는 마스킹)

5.4 Part A. 왜 BERT/GPT가 폭발했나 (p2–p4)

5.4.1 강의 핵심 논리 (Step-by-step)

Step 1) NLP는 입력 데이터 (X)가 매우 많다

  • 웹/문서/댓글/로그 등 텍스트는 무한히 쌓인다(강의 요지)

Step 2) 하지만 레이블 (Y)를 만들기 어렵다

  • 번역/요약/NLI 등은

    • “정답의 정의” 자체가 애매하거나
    • 사람마다 기준이 달라 합의(투표/다수결/가이드라인)가 필요

Step 3) 결론: “레이블 없이도 학습되는 과제”로 먼저 크게 학습한다

  • Self-supervised(자기지도) 과제(MLM/다음토큰예측)로 표현을 먼저 학습
  • 이후 필요한 태스크에 소량 레이블로 적응(파인튜닝/프롬프트)

5.4.2 (p4) “NLP vs Bio/CV”가 말하는 진짜 포인트

항목Bio/CV(예: MRI 세그멘테이션)NLP(예: 요약/의미/추론)
입력 데이터 (X)상대적으로 적음(수집 비용 큼)매우 많음
레이블 (Y)전문가가 만들면 “정답 정의가 비교적 명확”“정답 정의 자체가 애매”한 경우 많음
병목데이터 수집/품질레이블링 + 정답 정의
자연스러운 전략전이학습/파인튜닝대규모 사전학습 → 범용 표현 → 적응

5.5 Part B. Pretrain → Finetune / Transfer / Few-shot·Zero-shot (p5–p10)

5.5.1 (p5) CV 예시로 이해하는 “프리트레인–파인튜닝”

강의의 “로우레벨/하이레벨 필터”를 NLP로 대응하면:

  • 로우레벨: 기본 문법/표현/일반 문맥 패턴(범용)
  • 하이레벨: 특정 태스크(감성/QA/NER/분류)에 맞는 결정 경계(특화)

파라미터 고정(Freeze) 직관

[Pretrained Backbone]
Layer1  (freeze)  <- 범용 패턴
Layer2  (freeze)
Layer3  (train)   <- 타겟 태스크에 맞게 조정
Head    (train)   <- 태스크 출력층

실무 팁: 데이터가 적을수록 “하단 레이어 freeze + 상단만 학습”이 안정적인 출발점입니다.


5.5.2 (p6) Transfer learning vs Finetuning 정리

용어실무적으로 가장 정확한 정의강의 예시 연결
Pretraining대규모 데이터로 범용 표현 학습(대개 자기지도)웹 텍스트로 LM 학습
Finetuning타겟 태스크 데이터로 추가 학습(파라미터 업데이트)“영-한 번역 데이터로 맞춘다”
Transfer learning소스에서 학습한 표현/가중치를 타겟에 전이하는 전체 전략“영-일로 먼저 배우고 영-한으로”

5.5.3 (p7) Few-shot / One-shot / Zero-shot (NLP 프롬프트로 정확 대응)

정의(시험/면접)

  • Zero-shot: 예시 0개
  • One-shot: 예시 1개
  • Few-shot: 예시 (k)개

NLP 구현(강의 “번역 원샷”을 정확 프롬프트로)

[예시(1-shot)]
한국어: 나는 배고프다
영어: I am hungry

[문제]
한국어: 오늘 날씨가 좋다
영어:

핵심:

  • 파라미터 업데이트(gradient update) 없이
  • 프롬프트(지시 + 예시 + 질의)만으로 조건부 생성을 수행

5.5.4 (p8–p10) Domain/러닝 패러다임 혼동 방지(필수 2개)

(1) Domain이란?

도메인 (D)는 보통 데이터가 생성/샘플링되는 분포(환경)를 의미합니다.

(2) Transfer vs (In-context) Zero/Few-shot을 가르는 가장 쉬운 기준

  • Transfer(파인튜닝 포함): 타겟 데이터로 파라미터 업데이트 있음
  • Zero/Few-shot(in-context): 프롬프트에 예시가 있을 뿐 파라미터 업데이트 없음

5.6 Part C. GPT-1 (p11–p19) — Generative Pre-Training + Fine-tuning

5.6.1 (p11) GPT-1 큰 그림

  • GPT = Generative Pre-Training
  • 철학: (1) LM으로 먼저 크게 학습 → (2) 태스크별로 약간만 맞춤
flowchart LR
  A[Large unlabeled text] --> B[Stage 1: LM Pretraining]
  B --> C[Transformer Decoder (shared)]
  D[Labeled dataset per task] --> E[Stage 2: Supervised fine-tuning]
  C --> E
  E --> F[Downstream performance]

5.6.2 (p14) Stage 1: Causal Language Modeling 수식(정확 표기)

토큰 시퀀스를 (U=(u_1,\dots,u_n))라 할 때, GPT의 언어모델은 과거 토큰만 조건으로 다음 토큰을 예측합니다.

(1) 최대화 관점(로그우도)

[
\max{\theta}\ \sum{i=1}^{n}\log P(ui \mid u{<i};\theta)
]

(2) 손실(최소화) 관점(음의 로그우도)

[

L_{\text{LM}}(\theta)

-\sum{i=1}^{n}\log P(u_i \mid u{<i};\theta)
]

강의의 “레프트-투-라이트(미래 못 봄)”는 (u_{<i})만 쓰는 조건부 확률을 뜻합니다.


5.6.3 (p15) Stage 2: Supervised Fine-tuning + LM 보조항

타겟 태스크 데이터 (C)가 ((x,y)) 쌍의 집합일 때:

(1) 태스크 손실(예: 분류)

[

L_{\text{task}}(\theta)

-\sum_{(x,y)\in C}\log P(y\mid x;\theta)
]

(2) 최종 손실(슬라이드의 (\lambda) 결합을 “손실 형태로” 정확히)

[

L(\theta)

L_{\text{task}}(\theta)

  • \lambda\ L_{\text{LM}}(\theta)
    ]
  • (\lambda)가 작은 이유(강의 의도):

    • 태스크 성능에 집중하되
    • LM 일반성(표현)을 조금 유지해 과적합 완화에 도움

5.6.4 (p16) “입력 구조만 바꾸면 다양한 태스크에 적용”의 의미

모델(디코더 트랜스포머)은 그대로 두고, 태스크 입력을 텍스트 시퀀스로 ‘포맷팅’합니다.

태스크입력 포맷(예시)출력/판정
문장 분류[BOS] textclass
문장쌍(NLI/유사도)[BOS] premise [SEP] hypothesisentail/neutral/contradict
QA(간단형)[BOS] question [SEP] contextanswer span / 생성
다지선다각 옵션별 [BOS] question [SEP] option_i 점수화argmax option

5.6.5 (p17–p19) Ablation 요지(강의 포인트 유지)

  • 프리트레인(LM) + 파인튜닝 조합이 성능에 기여
  • 모델 깊이/규모 증가가 성능을 밀어올림
  • LSTM 대비 Transformer가 여러 태스크에서 더 강한 경향

5.7 Part D. BERT (p20–p35) — Bidirectional Encoder + MLM(+NSP)

5.7.1 (p21–p23) GPT vs BERT 구조 차이(핵심 1줄)

  • GPT: Decoder + Causal(미래 마스킹) → 생성에 유리
  • BERT: Encoder + Bidirectional(좌/우 문맥) → 이해/표현학습에 유리
GPT (Causal):
t3는 (t1,t2)만 봄, (t4,t5)는 마스킹

BERT (Bidirectional):
t3는 (t1,t2,t4,t5) 모두 볼 수 있음
(단, MLM에서는 일부 토큰이 [MASK]로 가려짐)

5.7.2 (p24–p26) Pretrain 1: Masked Language Model(MLM)

목적

입력 토큰 일부를 가리고, 가려진 토큰을 맞추며 양방향 문맥 표현을 학습합니다.

마스크 위치 집합을 (M)이라 할 때:

[

L_{\text{MLM}}(\theta)

-\sum{i\in M}\log P(x_i \mid x{\backslash M};\theta)
]

80/10/10 규칙(강의 싱크 강함)

마스크 후보로 뽑힌 토큰(보통 전체의 15% 내외)에 대해:

  • 80% → [MASK]로 치환
  • 10% → 랜덤 토큰으로 치환
  • 10% → 원래 토큰 유지

이유

  • 파인튜닝/추론에서는 [MASK]가 없을 수 있으므로
    [MASK]에만 과적응하는 것을 방지

5.7.3 (p27) Pretrain 2: Next Sentence Prediction(NSP)

두 문장 A, B가 주어졌을 때:

  • IsNext: 실제 코퍼스에서 A 다음에 B가 이어짐
  • NotNext: B를 다른 문서/문맥에서 랜덤 샘플

목표는:
[

L_{\text{NSP}}(\theta)

-\sum \log P(\text{label} \mid A,B;\theta)
]

강의 기준에서는 NSP를 핵심 구성으로 설명하므로 그대로 따라가면 됩니다.


5.7.4 (p28) BERT 입력 임베딩 3종 합(시험 단골)

토큰 위치 (i)에서 최종 입력 임베딩:

[

\mathbf{e}_i

\mathbf{e}^{token}_i

  • \mathbf{e}^{pos}_i
  • \mathbf{e}^{segment}_i
    ]
  • (\mathbf{e}^{token}): 토큰 의미(서브워드)
  • (\mathbf{e}^{pos}): 위치 정보
  • (\mathbf{e}^{segment}): 문장 A/B 구분(문장쌍 입력)

5.7.5 (p29) Fine-tuning 패턴 2가지(문장 단위 vs 토큰 단위)

(1) Sequence-level(문장/문장쌍 분류)

  • [CLS] 출력 벡터 (\mathbf{h}_{CLS}) → 분류기 → label

[
\hat{y}=\text{softmax}(W\mathbf{h}_{CLS}+b)
]

(2) Token-level / Span-level

  • NER: 각 토큰 벡터 (\mathbf{h}_i)에 분류기
  • SQuAD(QA): start/end 위치 예측

SQuAD 스팬 점수화(강의의 dot product를 수식으로 정리)

[
\text{score}{start}(i)=\mathbf{h}i^\top \mathbf{s},\quad
\text{score}{end}(i)=\mathbf{h}i^\top \mathbf{e}
][ P(start=i)=\text{softmax}(\text{score}*{start}),\quad P(end=i)=\text{softmax}(\text{score}*{end}) ]


5.7.6 (p30–p33) 벤치마크가 의미하는 것(강의 흐름 유지)

슬라이드벤치마크태스크 타입잘하면 좋아지는 능력
p30GLUE문장/문장쌍 분류 묶음범용 문맥 이해(일반화)
p31SQuAD지문 기반 QA(스팬)정보 위치 찾기 + 토큰 이해
p32SWAG상식 기반 이어쓰기(다지선다)문장 흐름/상식 추론
p33CoNLL NER토큰 태깅개체 인식(사람/장소/기관 등)

5.7.7 (p34–p35) Ablation 해석(강의 요지 그대로)

  • 당시 설정에서는 MLM/NSP가 성능에 기여
  • 특히 MLM이 “문맥 표현”을 강하게 밀어줌

5.8 Part E. GPT-2 (p36–p44) — 더 큰 데이터 + BPE + Zero-shot

5.8.1 (p36–p38) GPT-2가 강조한 3가지

  1. 더 큰 데이터(WebText 등)로 LM 학습
  2. 스케일(모델/데이터) 증가
  3. 파인튜닝 없이도(혹은 최소화) zero-shot 성능을 보여줄 수 있다

5.8.2 (p39–p43) BPE(Byte Pair Encoding) — 완전 정리

왜 필요한가?

  • 단어 단위 토크나이징은 OOV(사전에 없는 단어)가 빈번
  • 서브워드(BPE/WordPiece 등)를 쓰면 “처음 보는 단어”도 분해/조합 가능

BPE 알고리즘(정확 Step-by-step)

  1. 초기 vocabulary를 문자(또는 바이트) 단위로 시작
  2. 말뭉치에서 가장 빈번한 연속 pair를 찾음
  3. 그 pair를 merge하여 하나의 토큰으로 추가
  4. 목표 vocab 크기까지 반복

강의의 “트위터 이모지” 맥락은, byte-level 계열 토크나이징이 특수문자/이모지 처리에 유리하다는 직관으로 이해하면 됩니다.


5.8.3 (p36–p44) Zero-shot 프롬프트화(강의 요지)

  • 분류 문제도 “라벨을 출력 토큰으로 생성”하는 형태로 바꿔서 수행 가능
  • 즉, 헤드(softmax classifier)를 학습하지 않고 프롬프트로 태스크를 기술

5.9 Part F. GPT-3 (p45–p49) — 스케일 + In-context learning

5.9.1 (p45) GPT-3 핵심 메시지(강의 표현 그대로)

  • GPT-2 철학을 확장: 더 큰 모델 + 더 큰 데이터 → 더 강한 일반화
  • 프롬프트에 예시를 넣어 zero/one/few-shot 수행
  • 중요한 포인트: gradient update 없이(학습 없이) 추론에서 해결

5.9.2 In-context learning 흐름(도식)

flowchart LR
  A[Instruction: task description] --> M[Pretrained GPT]
  B[Examples: (x1->y1)...(xk->yk)] --> M
  C[Query: x?] --> M
  M --> D[Generated answer y?]

5.9.3 (p49) 강의 요약을 “한 줄”로

  • BERT: 문장을 “이해/표현”하는 데 강한 인코더
  • GPT: 문장을 “생성/연속 예측”하는 데 강한 디코더

5.10 Part G. 실무/연구 동향 (강의 위에 최소 확장)

5.10.1 PEFT(예: LoRA) — “가볍게 적응시키는 파인튜닝”

  • 대형 모델 전체를 업데이트하면 비용/메모리가 큼
  • 그래서 일부 저랭크 어댑터만 학습해 빠르게 적응
  • 대표: LoRA (arXiv:2106.09685)

면접용 한 줄

  • “요즘은 full fine-tuning 대신 LoRA 같은 PEFT로 비용을 줄이고 빠르게 도메인 적응한다.”

5.10.2 RAG — “모르는 지식은 검색으로 보강”

  • 모델 파라미터에 지식을 ‘다’ 넣기보다
    검색으로 관련 문서(근거)를 가져와 생성에 결합
  • 대표 개념 정리로 널리 인용되는 축: RAG (arXiv:2005.11401)

면접용 한 줄

  • “최신/사내 지식과 근거가 필요하면 RAG로 문서를 붙여 환각을 줄인다.”

5.11 Part H. (시험/면접 대비) 15초 답변 템플릿 6개

5.11.1 왜 프리트레인이 필요한가?

“자연어는 입력 데이터는 많지만 레이블이 만들기 어려워서, 자기지도 과제로 대규모 사전학습을 하고 소량의 레이블로 다운스트림 태스크에 적응시키는 프리트레인–파인튜닝 전략이 강해졌습니다.”

5.11.2 GPT와 BERT의 구조 차이?

“GPT는 디코더 기반 causal LM이라 과거만 보고 다음 토큰을 생성하고, BERT는 인코더 기반 양방향 self-attention으로 좌우 문맥을 함께 보며 표현을 학습합니다.”

5.11.3 GPT-1의 2-stage는?

“1단계에서 언레이블 텍스트로 LM을 프리트레인하고, 2단계에서 태스크 레이블로 파인튜닝하며 필요하면 LM 손실을 (\lambda)로 섞어 일반성을 유지합니다.”

5.11.4 BERT의 MLM 80/10/10 이유?

“추론 때 [MASK]가 없으므로 [MASK]에 과적응하지 않게 랜덤/원토큰을 섞어 견고한 문맥 표현을 학습합니다.”

5.11.5 Zero-shot/Few-shot의 핵심?

“파라미터 업데이트 없이, 프롬프트에 지시문과 예시를 넣어 조건부 생성으로 태스크를 수행하는 방식입니다.”

5.11.6 요즘 현업 파인튜닝/운영 흐름?

“대형 모델은 LoRA 같은 PEFT로 일부만 학습해 비용을 줄이고, 최신 지식/근거가 필요하면 RAG로 검색 문서를 결합합니다.”


5.12 Part I. 연습문제 + 채점 기준

5.12.1 개념 퀴즈 8문항

  1. (p4) 자연어에서 “레이블링이 어렵다”는 말이 의미하는 두 가지를 쓰시오.
  2. (p5) 프리트레인–파인튜닝에서 freeze를 하는 이유를 데이터 크기 관점에서 설명하시오.
  3. (p7) zero-shot과 transfer learning을 구분하는 가장 쉬운 기준은?
  4. (p14) GPT의 Causal LM은 어떤 조건부 확률을 최대화하는가?
  5. (p15) (L=L{\text{task}}+\lambda L{\text{LM}})에서 (\lambda)를 작게 두는 직관은?
  6. (p28) BERT 입력 임베딩 3종과 역할을 각각 쓰시오.
  7. (p29) SQuAD에서 start/end를 예측하는 점수화는 어떤 형태인가?
  8. (p39–p43) BPE가 OOV를 줄이는 원리를 2~3줄로 설명하시오.

5.12.2 채점 기준(핵심만)

  • 3번: 파라미터 업데이트 유무를 말하면 정답
  • 5번: “태스크에 집중하면서도 LM 일반성을 조금 유지(과적합 완화)”면 정답
  • 7번: “각 토큰 벡터와 start/end 벡터의 dot product(선형 점수) 후 softmax”면 정답

6. Hugging Face Library

아래는 네가 정리해둔 실습 코드를 교재형으로 “형식/수식(표기)/코드(실행가능)”까지 통일해서, 앞뒤 흐름이 끊기지 않게 다시 엮은 최종본이야.
(마지막에 바로 실행 가능한 .ipynb / .py 파일도 같이 줌)


6.1 이 장의 목표

6.1.1 우리가 “정확히” 하려는 것

  1. pipeline()으로 즉시 추론(inference) 하기
  2. AutoTokenizer토큰화 → id 변환 → 텐서 입력 흐름 이해하기
  3. datasets.load_dataset()TSV/JSON 데이터 로드하기
  4. map()으로 전처리(예: HTML unescape) 하기
  5. PyTorch로 학습 루프(training loop) + scheduler까지 최소 단위로 돌려보기

6.2 실습 준비

6.2.1 설치(로컬/코랩 공통)

pip install -U transformers datasets accelerate torch tqdm

6.2.2 디바이스 선택(공통)

  • GPU가 있으면 cuda, 없으면 cpu
import torch
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device

6.3 Pipeline 빠른 시작

6.3.1 Pipeline이 해주는 일(한 줄 정의)

pipeline(task)는 내부적으로 아래를 자동으로 묶어준다.

[
\text{pipeline} = \text{Tokenizer} \circ \text{Model} \circ \text{PostProcess}
]

즉, 토크나이징 → 모델 forward → 후처리(확률/디코딩) 까지 “한 방”에 처리한다.


6.3.2 (실습 1) fill-mask

from transformers import pipeline

unmasker = pipeline("fill-mask")
unmasker("This course will teach you all about <mask> models", top_k=2)

핵심 포인트

  • 문장 안에 <mask>를 넣으면, pipeline이 해당 모델의 mask 토큰으로 맞춰서 처리한다.
  • 재현성을 올리려면 모델을 명시하는 게 좋다:
unmasker = pipeline("fill-mask", model="bert-base-uncased")

6.3.3 (실습 2) sentiment-analysis (docx 텍스트 코드 반영)

from transformers import AutoTokenizer, pipeline

model_name = "klue/roberta-base"
tokenizer = AutoTokenizer.from_pretrained(model_name)
classifier = pipeline("sentiment-analysis", model=model_name, tokenizer=tokenizer)

classifier("이 강의 진짜 도움 많이 됐어요!")

6.4 Tokenizer → id → Model 입력

6.4.1 토크나이저의 역할(정확 정의)

텍스트 (x)가 들어오면, 모델이 먹을 수 있는 텐서 묶음으로 변환한다.

[
x ;\rightarrow; {\text{input_ids},;\text{attention_mask},;\text{token_type_ids(optional)}}
]

  • input_ids: 토큰 id 시퀀스
  • attention_mask: 패딩(0) vs 실제 토큰(1)
  • token_type_ids: 문장쌍(A/B) 구분(BERT류에서 주로 사용)

6.4.2 (실습 3) docx 이미지 예시 그대로 + 실패 라인 유지

import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)

sequence = "I've been waiting for a HuggingFace course my whole life."

tokens = tokenizer.tokenize(sequence)
ids = tokenizer.convert_tokens_to_ids(tokens)
input_ids = torch.tensor(ids)

# This line will fail.
model(input_ids)

왜 실패하나? (원인 “정확히”)

대부분의 Transformer 모델 입력은 배치 차원(batch dimension) 을 기대한다.

  • 지금 input_ids shape:
    [
    (seq_len,)
    ]
  • 모델이 기대하는 기본 shape:
    [
    (batch,;seq_len)
    ]

6.4.3 Fix(실행되게 만들기): 배치 차원 추가

input_ids = torch.tensor([ids])   # (batch, seq_len)
model(input_ids)

6.4.4 실무/실습에서 “정석”(추천): tokenizer가 바로 텐서 만들게 하기

이게 제일 덜 틀리고, attention_mask도 자동으로 들어가서 안정적이다.

import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)

sequence = "I've been waiting for a HuggingFace course my whole life."

inputs = tokenizer(sequence, return_tensors="pt")  # dict of tensors
outputs = model(**inputs)

logits = outputs.logits                    # (batch, num_labels)
pred = logits.argmax(dim=-1).item()

print("pred:", pred, "label:", model.config.id2label[pred])

출력 텐서 shape(시험/디버깅 핵심)

  • 분류 모델이면:

[
\text{logits shape} = (batch,;num_labels)
]


6.5 Tokenizer 내부 구조(backend_tokenizer) + normalizer

6.5.1 왜 보나?

  • “토큰화가 내부에서 어떻게 동작하는지”를 실제로 확인하는 용도
  • 특히 normalize_str악센트/특수문자 정규화 같은 전처리 감각을 잡기 좋다.

6.5.2 (실습 4) backend_tokenizer + normalizer

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
print(type(tokenizer.backend_tokenizer))

print(tokenizer.backend_tokenizer.normalizer.normalize_str("Héllò hôw are ü?"))

6.6 Datasets 로드

6.6.1 TSV 로드(drugsCom 예시)

from datasets import load_dataset

data_files = {"train": "drugsComTrain_raw.tsv", "test": "drugsComTest_raw.tsv"}
drug_dataset = load_dataset("csv", data_files=data_files, delimiter="\t")

빠른 확인

drug_dataset["train"]["condition"][:3]

6.6.2 JSON 로드(SQuAD_it 예시)

from datasets import load_dataset

data_files = {"train": "SQuAD_it-train.json", "test": "SQuAD_it-test.json"}
squad_it_dataset = load_dataset("json", data_files=data_files, field="data")

샘플 1개 확인:

squad_it_dataset["train"][0]

6.6.3 단일 JSON 로드(일반형)

from datasets import load_dataset
load_dataset("json", data_files="myfile.json")

6.7 map()으로 전처리(HTML unescape)

6.7.1 목적

리뷰 텍스트에 &amp;, &quot; 같은 HTML 엔티티가 남아있으면 모델 입력이 지저분해진다.
html.unescape로 정리한다.

6.7.2 (실습 5) batched map 적용

import html

new_drug_dataset = drug_dataset.map(
    lambda x: {"review": [html.unescape(o) for o in x["review"]]},
    batched=True,
)
new_drug_dataset

핵심 포인트

  • batched=Truex["review"]가 리스트 단위로 들어오므로, 리스트를 리턴해야 한다.

  • 실무에서는 이후에 보통:

    • remove_columns
    • rename_column("label", "labels")
    • set_format("torch")
      같은 정리 루틴이 붙는다.

6.8 Training loop (tqdm) + Scheduler

6.8.1 학습 루프가 하는 일(정확 구조)

각 스텝에서:

  1. 배치 텐서를 디바이스로 이동
  2. forward: ( \hat{y} = f_\theta(x) )
  3. loss 계산 (보통 Cross Entropy)
  4. backward: ( \nabla_\theta L )
  5. optimizer step
  6. scheduler step
  7. grad reset

분류의 표준 loss는:

[
L = -\sum_{c} y_c \log(\text{softmax}(\text{logits})_c)
]


6.8.2 (실습 6) 진행바 포함 training loop (네 코드 흐름 그대로)

from tqdm import tqdm

progress_bar = tqdm(range(num_training_steps))

model.train()
for epoch in range(num_epochs):
    for batch in train_dataloader:
        batch = {k: v.to(device) for k, v in batch.items()}
        outputs = model(**batch)
        loss = outputs.loss
        loss.backward()

        optimizer.step()
        lr_scheduler.step()
        optimizer.zero_grad()
        progress_bar.update(1)

6.8.3 (실습 7) get_scheduler로 LR Scheduler 만들기

from transformers import get_scheduler

num_epochs = 3
num_training_steps = num_epochs * len(train_dataloader)
lr_scheduler = get_scheduler(
    "linear",
    optimizer=optimizer,
    num_warmup_steps=0,
    num_training_steps=num_training_steps,
)
print(num_training_steps)

linear 스케줄 직관

  • 학습이 진행될수록 LR을 선형으로 줄이는 형태
  • warmup을 쓰면 초반엔 LR을 점점 올린 뒤, 이후 감소

6.9 실습에서 제일 많이 터지는 오류 TOP 6 (바로 해결형)

  1. 배치 차원 누락

    • 해결: torch.tensor([ids]) 또는 tokenizer(..., return_tensors="pt")
  2. attention_mask 없음

    • 해결: 수동 입력 말고 tokenizer() 출력 dict 사용
  3. 모델/토크나이저 mismatch

    • 해결: 같은 checkpoint로 둘 다 로드
  4. fill-mask에서 마스크 토큰 혼동

    • 해결: pipeline에는 <mask> 쓰면 안전, 직접이면 tokenizer.mask_token 확인
  5. datasets.map에서 batched 처리 실수

    • 해결: batched면 리스트를 리턴해야 함
  6. GPU 사용 시 device 인자 미지정

    • 해결: pipeline은 device=0, torch는 .to(device)

6.10 바로 실행 가능한 파일

원하면 다음 단계로 HuggingFace실습.docx 이미지들을 “이미지 번호별 → 코드 셀로 정렬 → 중복 제거 → 실행 순서로 재배치” 해서, docx 전체를 1개의 완성 노트북으로 합치는 버전도 바로 만들어줄게.

profile
李家네_공부방

0개의 댓글