[LLM] Fine-tuning

CHOI HYUK·2025년 8월 23일
0

AI

목록 보기
5/6
post-thumbnail

🖥️ Fine-tuning

Transformer 구조를 이해했으니, 이제 자연스럽게 "그럼 이렇게 만들어진 모델을 어떻게 내 태스크에 맞게 쓰는가?" 라는 질문이 생긴다. 바로 여기서 Fine-tuning(파인튜닝) 이라는 개념이 나온다.

LLM이나 Transformer 모델은 처음에 Corpus 로 학습된다. 이 과정에서 모델은 언어의 전반적인 패턴, 문법, 의미 관계를 배우게 되는데, 이걸 사전학습(Pre-training) 이라고 한다. 앞의 글에서 살펴본 Transformer 과정이 사전학습을 진행하는 과정이다. 하지만 이렇게 학습된 모델을 바로 특정 태스크에 쓰기는 어렵다. 그 이유는 모든 도메인 지식을 아우를 수는 없기 때문이다. Corpus를 통해 LLM들은 방대한 양의 지식을 가지고 있지만 새로 생성된 지식이나, 특정 구조에 맞춰서 입력을 만들어야하는 모델이 필요하다면, 기존의 LLM 모델들을 자신의 목적에 맞게 업그레이드(?) 하고 싶을 것이다.

그래서 하는 게 바로 Fine-tuning이다. 물론 엄밀히 말하면 업그레이드는 아니다. 원리를 간단히 말하면 이렇다.

Transformer 내부는 기본적으로 Attention, FFN, Embedding 같은 블록으로 구성되어 있고, 이 블록들 안에는 수많은 가중치(Weight) 가 들어있다. Pre-training에서 이미 이 가중치들이 언어를 잘 다룰 수 있게 학습되어 있다. Fine-tuning에서는 이렇게 이미 구성된 LLM내 태스크 데이터셋을 다시 넣고, 역전파(Backpropagation) 를 통해 가중치를 조금씩 조정한다. 여기서 역전파를 많이 들어봤을텐데. 사실 Pre-training 과정에서 이미 모델은 역전파를 통해 가중치를 조정한다. 파인튜닝은 이러한 역전파를 새로운 데이터셋으로 시도하는 것이라 보면 된다. Transformer 에서 모델을 완성하기 위해 최초의 Corpus로부터 각 layer의 가중치를 업데이트 하는 것을 반복하는 것이 Pre-training에서 진행되는 과정 이고, Fine-tuning은 완성된 모델을 다시 원하는 출력을 만드는 모델로 바꾸기 위해 새로운 입력을 넣고 가중치를 업데이트 하는 것을 반복하는 것 이다. 따라서 이전 글의 Transformer의 구조만 잘 이해하고 있으면, Fine-tuning은 이해하기 쉬울 것이다. 그러므로 이번 글에서는 Fine-tuning 자체 보다는 역전파(Backpropagation) 의 과정을 설명할 생각이다.


🖇️ 역전파(Backpropagation)

사실 Fine-tuning이라는 개념은 Transformer가 등장하기 전부터 존재했다. 예전에는 CNN 같은 컴퓨터 비전 모델을 학습할 때도, 대규모 데이터셋으로 학습된 모델의 가중치를 가져와 새로운 이미지 분류 작업에 맞게 일부 층만 조정하는 방식으로 활용했다. 즉, fine-tuning 자체는 오래된 개념이지만, 현대 LLM에서는 Transformer 아키텍처 위에서 이루어진다는 점이 다르다. 따라서 우리는 현대 모델들이 사용하는Transformer 구조를 기반으로 이해하면 된다.

Transformer를 기반으로 하는 Fine-tuning을 구체적으로 보면 Self-Attention, Multi-head Attention 같은 구조는 그대로 두고, 내부 가중치 행렬 WQ,WK,WVW^Q, W^K, W^V, 그리고 Feed Forward Network(FFN)의 W1,W2W_1, W_2 같은 파라미터들이 다시 학습 대상이 된다. 이때 학습 과정은 Pre-training 때와 똑같이 순전파 → 손실 계산 → 역전파 → 가중치 업데이트로 돌아간다. 차이는 단지 데이터셋의 목적이다. Pre-training 때는 일반 텍스트 전체, Fine-tuning 때는 특정 태스크에 맞는 데이터라는 점이 다르다.

용어들에 대해서 헷갈릴 것 같은데, 정리를 해보겠다.

  • 순전파(Forward Propagation): 입력 데이터를 모델에 넣어서 예측값을 뽑아내는 과정. Transformer라면 입력 토큰이 Self-Attention, Multi-head Attention, FFN 등을 거쳐서 최종 출력 확률로 바뀌는 걸 의미.

  • 손실(Loss): 모델의 예측과 정답 사이의 차이를 수치로 나타낸 값. Cross-Entropy 같은 걸 많이 쓰고, 이 값이 클수록 모델이 정답과 멀리 있는 것.

  • 역전파(Backpropagation): 손실 값을 기준으로 어떤 가중치가 얼마나 잘못했는지 를 계산해서 뒤로 흘려보내는 과정. 각 층의 WQ,WK,WV,W1,W2W^Q, W^K, W^V, W_1, W_2 같은 파라미터가 손실에 얼마나 기여했는지 기울기를 구함.

  • 가중치 업데이트(Weight Update): 역전파로 구한 기울기를 바탕으로 실제 파라미터 값을 조금씩 수정하는 단계. 보통 SGD, Adam 같은 옵티마이저 가 이 역할을 담당.

손실 계산부터 어떻게 파인튜닝이 진행되는지 살펴보자

손실 계산

예측 확률 pp와 정답 레이블 yy를 비교해서 손실 \ell을 구한다.

  • Cross-Entropy 손실 기준으로는 =ylogp\ell = -\sum y \log p.

음의 로그 함수를 사용해서, 정답 클래스의 pp를 음의 로그 스케일로 보면, 정답 확률이 0에 가까워 지면, 손실 \ell은 무한대로 증가하고 1에 가까워지면 \ell은 0에 가까워질 것이다.


오차 신호(Gradient) 계산

손실을 로짓 zz에 대해 미분하면

z=py\frac{\partial \ell}{\partial z} = p - y

이 값이 나온다 (값을 도출하는 것은 논문이나 다른 글에서 확인바람...). 이게 바로 역전파로 흘러가는 오차 신호다. 로짓 zz예측 확률 pp 를 소프트맥스를 하여 확률 분포로 나타내기 직전의 상태 이다. 따라서 확률 데이터가 아닌, 단순히 점수(score)로서 정답과 얼마나 가까운지를 상대적으로 보여주는 값 이라 보면 된다. 따라서 "손실률에 대해 로짓을 미분했다" 는 것은, 로짓 값이 바뀔 때 손실이 얼마나 영향을 받는지를 수치로 나타내는 것 이다.

클래스를 개(dog), 고양이(cat), 소(cow)로 두고 예시를 들어보자. 정답은 고양이라고 하자.

1. 모델이 낸 로짓 (점수)

z=[2.0,  1.0,  0.5]z = [2.0,\; 1.0,\; -0.5]
  • 개 = 2.0
  • 고양이 = 1.0
  • 소 = -0.5

로짓은 아직 확률이 아니라 “점수” 같은 거라 보면 된다. 여기서는 개가 가장 높은 점수를 가지고 있다. 따라서 오차가 있는 출력 값이다.

2. 소프트맥스 → 확률 분포

p=softmax(z)=[0.62,  0.34,  0.04]p = \text{softmax}(z) = [0.62,\; 0.34,\; 0.04]
  • 개일 확률 = 62%
  • 고양이일 확률 = 34%
  • 소일 확률 = 4%

정답은 고양이인데, 모델은 개가 더 맞다고 본 상황이므로 이를 통해서 오차 신호를 계산할 수 있다.

3. 오차 신호 계산

py=[0.620,  0.341,  0.040]=[0.62,  0.66,  0.04]p-y = [0.62-0,\; 0.34-1,\; 0.04-0] = [0.62,\; -0.66,\; 0.04]

4. 해석

  • 개(dog): +0.62+0.62 → 정답이 아닌데 너무 높게 잡았다. 점수를 내려야 한다.
  • 고양이(cat): 0.66-0.66 → 정답인데 확률이 낮다. 점수를 올려야 한다.
  • 소(cow): +0.04+0.04 → 정답이 아닌데 살짝 점수를 줬다. 조금 줄여야 한다.

결국 pyp-y는 단순한 차이가 아니라, 가중치를 어느 방향으로 바꿔야 하는지 알려주는 오차 신호다.

  • 정답 클래스는 음수 → 점수를 올려야 한다.
  • 오답 클래스는 양수 → 점수를 내려야 한다.

역전파 진행

이 오차 신호가 FFN, Multi-head Attention, Embedding까지 거꾸로 내려가면서 각 파라미터의 기울기 W\frac{\partial \ell}{\partial W}를 계산한다.

경사하강법으로 가중치 업데이트

계산된 기울기를 바탕으로 옵티마이저가 가중치를 업데이트한다. 가장 기본적인 SGD는 다음과 같다.

WWηWW \leftarrow W - \eta \cdot \frac{\partial \ell}{\partial W}
  • η\eta: 학습률(learning rate).
  • 기울기가 양수면 가중치를 줄이고, 음수면 가중치를 늘려서 손실을 줄이는 방향으로 움직인다.

위의 예시로 다시 살펴보면 이렇게 된다.

g  =  py  =  [0.62,  0.66,  0.04]g \;=\; p-y \;=\; [\,0.62,\; -0.66,\; 0.04\,]
b=g,\frac{\partial \ell}{\partial b} = g,\qquad
WWηW,bbηbW \leftarrow W - \eta\,\frac{\partial \ell}{\partial W} \quad,\quad b \leftarrow b - \eta\,\frac{\partial \ell}{\partial b}

예를 들어 η=0.1\eta=0.1이면

b=b0.1[0.62,  0.66,  0.04]=[b10.062,  b2+0.066,  b30.004]b' = b - 0.1\,[\,0.62,\; -0.66,\; 0.04\,] = \big[b_1-0.062,\; b_2+0.066,\; b_3-0.004\big]
  • 개(dog): g1=+0.62b1g_1=+0.62\Rightarrow b_1 감소(점수↓)
  • 고양이(cat): g2=0.66b2g_2=-0.66\Rightarrow b_2 증가(점수↑)
  • 소(cow): g3=+0.04b3g_3=+0.04\Rightarrow b_3 소폭 감소(점수↓)

gk>0g_k>0 (오답을 과대평가) ⇒ zkz_k 감소

gk<0g_k<0 (정답을 과소평가) ⇒ zkz_k 증가

이후 zz'에 softmax를 다시 적용하면, 고양이 확률이 올라가고 개/소는 내려가는 방향으로 조정된다.

한마디로 요약하자면

정답인데 확률을 높여야 된다!

  • 로짓 zz를 크게 만들어서 손실률을 줄여야 하므로 기울기 gg가 음수
  • 기울기가 음수 이므로 경사하강법 WηgW -\eta{g} 적용 했을 때, 가중치가 증가 함

오답인데 확률이 너무 높다!

  • 로짓 zz를 작게 만들어서 손실률을 줄여야 하므로 기울기 gg가 양수
  • 기울기가 양수이므로 경사하강법 WηgW -\eta{g} 적용 했을 때, 가중치가 감소 함

반복

이 과정을 수천~수억 번 반복하면서 모델은 점점 내 데이터셋에 맞게 적응한다. 결국 Fine-tuning은 손실을 계산하고, 그걸 역전파로 풀어내서, 경사하강법으로 가중치를 조금씩 고쳐나가는 과정이다. 새로운 모델을 처음부터 만드는 게 아니라, 이미 언어 감각을 익힌 Transformer를 내가 원하는 태스크에 맞게 조금씩 조율하는 작업이라고 보면 된다. 그리고 이러한 반복을 epoch 이라고 한다


😘 마무리

이번에는 파인튜닝의 역전파의 기본 원리에 대해 알아보았다. 다음글에서는 현대 모델에서 표준으로 자리잡은 파인튜닝 기법인 LoRA(Low-Rank Adaptation) 를 살펴보고, 실제 코드와 함께 파인튜닝 과정을 정리해보겠다.

0개의 댓글