들어가며
파인튜닝은 이미 학습된 모델을 특정 데이터로 한 번 더 학습시키는 과정이다. 다만 모델에게 새로운 지식을 외우게 하는 것이라기 보다는, 파인튜닝은 지식 주입보다는 모델의 행동 방식을 특정 목적에 맞게 조정하는 기술에 더 가까워 보인다.
이 글에서는 파인튜닝 자체를 길게 설명하기보다는, OpenAI 문서, Hugging Face PEFT 문서, LoRA/QLoRA 논문을 읽고 나서 보이는 흐름을 정리해보려고 한다.
파인튜닝 한 줄 요약
파인튜닝은 모델에게 매번 길게 설명하던 규칙을, 학습 데이터로 반복해서 보여주는 방식이다.
프롬프트 엔지니어링:
매번 요청할 때마다 규칙을 설명한다.
파인튜닝:
좋은 입력-출력 예시를 학습시켜서
모델이 그 패턴을 더 안정적으로 따르게 만든다.예를 들어 고객 문의 응답 모델을 만든다고 해보자. 프롬프트 방식은 매번 이런 규칙을 넣는다.
너는 친절한 고객센터 상담원이다.
환불 불가 상황에서도 단정적으로 거절하지 말고,
대체 가능한 선택지를 함께 안내해라.
항상 짧고 공손하게 답변해라.파인튜닝은 이런 좋은 예시를 여러 개 학습시킨다.
{
"input": "환불하고 싶어요.",
"output": "환불 가능 여부를 확인해드리겠습니다. 주문 상태와 사용 여부에 따라 처리 방식이 달라질 수 있어요."
}이렇게 보면 파인튜닝의 핵심은 단순하다. 좋은 답변의 패턴을 모델이 더 자주 재현하게 만드는 것이다.
OpenAI 문서
OpenAI의 문서를 보면 파인튜닝은 단독 기술이라기보다, 모델 최적화(model optimization) 의 한 방법으로 다뤄진다. 흥미로운 점은 파인튜닝을 언제 쓰는가보다 먼저 다른 방법으로 해결할 수 없는가를 생각하게 만든다는 점이다.
LLM 결과를 개선하는 방법은 여러 가지가 있다.
1. 프롬프트를 개선한다
2. 예시를 추가한다
3. 검색/RAG를 붙인다
4. 구조화 출력을 사용한다
5. 그래도 반복적으로 실패하면 파인튜닝을 고려한다즉, 첫 번째 선택지라기보다, 반복되는 실패 패턴이 확인된 뒤에 고려하는 선택지에 가깝다. 먼저 원인을 봐야 한다.
| 문제 | 먼저 의심할 것 |
|---|---|
| 최신 정보를 모른다 | RAG나 검색 연결 문제 |
| 답변 근거가 부족하다 | 문서 검색/컨텍스트 문제 |
| 지시를 잘 못 따른다 | 프롬프트 문제 |
| 출력 형식을 자주 깬다 | 구조화 출력 또는 파인튜닝 |
| 말투가 계속 흔들린다 | 예시 부족 또는 파인튜닝 |
| 특정 판단 기준을 못 따른다 | 데이터/평가 기준 문제 |
파인튜닝은 모델에게 모든 걸 더 잘하게 만드는 만능책?은 아니다. 오히려 반복적이고, 평가 가능하고, 좋은 예시를 만들 수 있는 문제에서 효과가 난다. 운영 방식에 가깝다는 생각이 들었는데, 모델을 학습시키기 전에 먼저 해야 하는 일은 좋은 답변이 무엇인지를 정의하는 것이다.
SFT는 좋은 답변을 보여주는 방식이다
OpenAI 문서에서 가장 기본적으로 다루는 방식은 Supervised Fine-Tuning, 즉 SFT다.
SFT는 입력과 그에 대한 좋은 출력을 짝으로 만들어 학습시키는 방식이다.
{
"messages": [
{
"role": "user",
"content": "배송이 너무 늦어요. 환불 가능한가요?"
},
{
"role": "assistant",
"content": "불편을 드려 죄송합니다. 주문 상태를 먼저 확인한 뒤 환불 가능 여부를 안내드리겠습니다."
}
]
}이 방식은 직관적이다. "이런 질문에는 이렇게 답하는 게 좋다"를 여러 번 보여주는 것이다.
SFT가 잘 맞는 경우는 대체로 이런 문제다.
- 고객 문의 답변
- 문서 요약
- 특정 포맷으로 변환
- 분류 작업
- 코드 리뷰 코멘트 생성
- 브랜드 톤에 맞는 문장 생성
- 반복적인 사내 업무 자동화
공통점은 좋은 예시를 만들 수 있다는 것이다.
반대로 좋은 예시를 만들기 어려운 문제에는 SFT가 애매해진다. 예를 들어 "창의적으로 좋은 아이디어를 내라" 같은 문제는 정답 출력 하나를 만들기 어렵다. 사람마다 좋은 답변의 기준도 다를 수 있다. 그래서 SFT는 "정답이 있는 문제"라기보다는, 우리가 원하는 출력 스타일을 예시로 보여줄 수 있는 문제에 잘 맞는다고 보는 게 더 정확해 보인다.
RFT는 정답보다 평가 기준이 중요할 때 등장한다
OpenAI 문서에는 Reinforcement Fine-Tuning, 즉 RFT도 나온다.
SFT가 좋은 답변 예시를 직접 보여주는 방식이라면, RFT는 모델의 답변을 어떤 기준으로 평가하고, 그 평가 신호를 바탕으로 모델을 조정하는 방식이다.
SFT:
좋은 답변 예시를 보여준다.
RFT:
답변을 생성하게 한 뒤,
그 답변이 얼마나 좋은지 평가한다.이 차이가 꽤 중요하다. 어떤 문제는 좋은 답변을 직접 쓰기 어렵지만, 답변이 좋은지 나쁜지는 평가할 수 있다. 예를 들어 코드 생성이 그렇다. 모든 정답 코드를 사람이 미리 작성하기는 어렵다. 하지만 생성된 코드가 테스트를 통과하는지는 확인할 수 있다.
수학 문제도 비슷하다. 풀이 과정은 다양할 수 있지만, 최종 답이 맞는지나 논리적으로 타당한지는 평가할 수 있다.
좋은 출력 예시를 만들기 쉽다 → SFT
좋은지 나쁜지 평가하기 쉽다 → RFT이 관점에서 보면 SFT와 RFT는 경쟁 관계가 아니라 문제 유형이 다르다.
- SFT는 "따라 할 좋은 예시"가 있을 때 유리하다.
- RFT는 "채점 가능한 기준"이 있을 때 유리하다.
다만 RFT는 더 조심스러워 보이는데, 평가 기준이 잘못되면 모델은 진짜 좋은 답변을 만드는 게 아니라, 점수를 잘 받는 답변을 만들 수 있기 때문이다. 모델은 우리가 의도한 품질을 직접 최적화하는 게 아니라, 우리가 설계한 보상 신호를 최적화한다. 결국 RFT에서 어려운 건 학습 자체보다 좋은 평가 기준을 만드는 일에 가까워 보인다.
Hugging Face 문서 - 전체를 다시 학습하지 말자
OpenAI 문서가 어떤 방식으로 모델 행동을 조정할 것인가를 보여준다면, Hugging Face PEFT 문서와 LoRA 논문은 다른 질문에서 출발한다.
이 거대한 모델을 꼭 전부 다시 학습해야 할까?
LLM은 너무 크다. 모델 전체를 파인튜닝하려면 비용이 크고, 메모리도 많이 필요하고, 모델 사본을 저장하는 것도 부담스럽다. 그래서 등장한 흐름이 PEFT(Parameter-Efficient Fine-Tuning) 다. 말 그대로, 적은 수의 파라미터만 학습해서 모델을 특정 작업에 적응시키는 방식이다.
이 흐름에서 가장 대표적인 방법이 LoRA(Low-Rank Adaptation) 다. LoRA의 아이디어는 단순하다.
기존 모델의 가중치는 그대로 둔다.
대신 작은 학습 가능한 행렬을 옆에 붙인다.
그 작은 부분만 학습한다.즉, 모델 전체를 고치는 게 아니라, 특정 작업을 위한 작은 어댑터를 붙이는 방식이다. 비유하자면 거대한 기계를 뜯어고치는 대신, 옆에 작은 조정 장치를 붙이는 느낌이다. 이 방식이 중요한 이유는 실용성 때문이다.
- 학습해야 할 파라미터 수가 줄어든다
- GPU 메모리 사용량이 줄어든다
- 태스크별 어댑터를 따로 저장할 수 있다
- 기본 모델을 여러 작업에 재사용할 수 있다
- 전체 파인튜닝보다 실험 비용이 낮아진다
파인튜닝을 제품 관점에서 생각하면 이 지점이 꽤 크다. 모델 하나를 서비스마다 통째로 다시 만들 수는 없다. 하지만 작은 어댑터를 작업별로 붙일 수 있다면 훨씬 실험하기 쉬워진다.
LoRA 논문이 말하는 핵심
LoRA 논문에서 인상적인 점은 문제 정의가 명확하다는 것이다. 거대한 모델을 특정 작업에 맞게 조정하고 싶은데, 전체 파라미터를 다시 학습하고 저장하는 건 너무 비싸다. 그러니 모델의 주요 가중치는 얼려두고, 작은 low-rank 행렬만 학습하자는 것이다.
여기서 중요한 단어는 low-rank다. 아주 단순하게 말하면, 큰 변화량을 그대로 학습하는 대신 더 작은 두 행렬의 곱으로 근사한다. 모델이 특정 작업에 적응하기 위해 필요한 변화가 생각보다 낮은 차원의 구조를 가질 수 있다는 가정에 기대는 방식이다.
큰 가중치 업데이트를 직접 학습하지 않고,
작은 두 행렬의 조합으로 표현한다.물론 실제 수식까지 깊게 들어가지 않아도, 실무적으로 중요한 메시지는 명확하다.
파인튜닝은 모델 전체를 수정하지 않아도 가능하다.
이 관점이 파인튜닝의 진입 장벽을 크게 낮춘다. 예전에는 파인튜닝이 거대한 인프라를 가진 팀의 영역처럼 느껴졌다면, LoRA 이후에는 훨씬 작은 자원으로도 실험할 수 있는 영역이 되었다.
QLoRA는 한 번 더 줄이는 시도다
QLoRA 논문은 여기서 한 단계 더 나아간다. LoRA가 전체 모델을 학습하지 말고 작은 어댑터만 학습하자였다면, QLoRA는 기본 모델 자체도 더 적은 메모리로 올리자에 가깝다. 핵심은 기본 모델을 4비트로 양자화하고, 그 위에서 LoRA 어댑터를 학습하는 것이다.
LoRA:
기본 모델은 얼리고,
작은 어댑터만 학습한다.
QLoRA:
기본 모델을 4비트로 양자화해서 메모리를 줄이고,
그 위에서 LoRA 어댑터를 학습한다.QLoRA 논문에서 흥미로운 점은 큰 모델을 파인튜닝하려면 엄청난 자원이 필요하다는 전제를 흔든다는 것이다. 논문에서는 65B 모델을 단일 48GB GPU에서 파인튜닝할 수 있을 정도로 메모리 사용량을 줄였다고 설명한다. 물론 이 말이 이제 누구나 쉽게 고품질 모델을 만들 수 있다는 뜻은 아니라고 하긴 하는데, 데이터 품질, 평가, 서빙 비용, 추론 속도, 안전성 문제는 여전히 남아 있다. (하지만 실험의 문턱은 낮아)
레퍼런스들을 관통하는 흐름
문서와 논문들을 같이 놓고 보면 파인튜닝의 흐름이 조금 다르게 보인다.
파인튜닝 = 모델을 특정 맥락에서 더 일관되게 행동하게 만드는 기술OpenAI 문서에서는 SFT, RFT처럼 어떤 신호로 모델을 조정할 것인가가 중요하다.
SFT: 좋은 답변 예시를 보여준다
RFT: 좋은 답변을 평가하는 신호를 준다Hugging Face와 LoRA/QLoRA 쪽에서는 얼마나 적은 비용으로 모델을 조정할 것인가가 중요하다.
LoRA: 전체 모델 대신 작은 어댑터만 학습한다
QLoRA: 양자화로 메모리까지 더 줄인다즉, 한쪽은 품질을 다루고, 다른 한쪽은 비용을 다룬다. 이 둘을 합치면 현재 파인튜닝의 실무적 질문은 대략 이렇게 정리된다.
우리가 원하는 행동은 무엇인가?
그 행동을 학습시킬 좋은 데이터가 있는가?
그 행동을 평가할 기준이 있는가?
그걸 감당 가능한 비용으로 학습시킬 수 있는가?이 네 질문에 답할 수 있어야 파인튜닝을 시작할 수 있다.
파인튜닝이 잘 맞는 문제
파인튜닝이 잘 맞는 문제는 생각보다 분명하다.
1. 출력 형식이 중요할 때
예를 들어 모델이 항상 정해진 JSON 형식으로 답해야 하는 경우다.
{
"category": "refund",
"priority": "high",
"summary": "배송 지연으로 인한 환불 문의"
}프롬프트로도 형식을 강제할 수 있지만, 요청이 복잡해지면 모델이 형식을 깨는 경우가 있다. 이런 형식 안정성이 중요하다면 파인튜닝이 도움이 될 수 있다. 다만 요즘은 구조화 출력 기능도 좋아지고 있어서, 단순한 JSON 강제만을 위해 무조건 파인튜닝을 할 필요는 없다. 구조화 출력, validation, 후처리로 해결 가능한지 먼저 보는 게 좋다.
2. 말투와 톤이 중요할 때
브랜드 톤을 안정적으로 유지해야 하는 경우도 파인튜닝 후보가 된다. 예를 들어 고객 응대에서 "친절하지만 과하게 사과하지 않기", "단정적으로 말하지 않기", "불가능한 요청에는 대안을 함께 제시하기" 같은 기준이 있을 수 있다. 이건 프롬프트로도 가능하지만, 서비스 전체에서 일관되게 유지하려면 좋은 답변 예시를 학습시키는 편이 더 안정적일 수 있다.
3. 같은 판단을 반복해야 할 때
분류, 태깅, 우선순위 판단처럼 같은 기준을 반복해서 적용해야 하는 문제에도 잘 맞는다.
고객 문의를 환불/배송/계정/결제 문제로 분류한다.
리뷰를 긍정/부정/중립으로 분류한다.
코드 변경 사항의 위험도를 낮음/중간/높음으로 판단한다.이런 문제는 좋은 라벨 데이터가 있으면 평가도 비교적 쉽다. 평가가 쉽다는 건 파인튜닝을 반복 개선하기 좋다는 뜻이다.
4. 프롬프트가 너무 길어질 때
매번 긴 시스템 프롬프트와 여러 개의 예시를 넣어야 한다면 비용과 지연 시간이 늘어난다. 파인튜닝은 반복되는 규칙 일부를 모델의 행동으로 옮겨서 프롬프트를 줄일 수 있다.
Before:
긴 시스템 프롬프트 + 여러 예시 + 유저 입력
After:
짧은 지시문 + 유저 입력물론 모든 규칙을 파인튜닝으로 옮길 수 있는 것은 아니다. 최신 정책, 동적으로 바뀌는 값, 사용자별 정보는 여전히 컨텍스트로 넣어야 한다.
파인튜닝이 잘 안 맞는 문제
반대로 파인튜닝이 어울리지 않는 문제도 있다.
1. 최신 정보를 넣고 싶을 때
파인튜닝은 최신 정보를 반영하는 데 좋은 방법이 아니다. 예를 들어 회사 정책, 제품 가격, 법률, 일정, 사용자별 데이터처럼 자주 바뀌는 정보는 파인튜닝보다 RAG나 데이터베이스 조회가 낫다. 파인튜닝은 학습 시점의 데이터를 모델에 반영한다. 정보가 바뀌면 다시 학습해야 한다. 반면 RAG는 참조 문서만 업데이트하면 된다.
지식이 문제라면 RAG
행동이 문제라면 파인튜닝이 구분이 제일 중요해 보인다.
2. 좋은 데이터가 없을 때
파인튜닝은 데이터 품질에 크게 의존한다. 나쁜 예시를 넣으면 나쁜 습관이 생긴다. 기준이 섞인 데이터를 넣으면 모델도 흔들린다. 그래서 파인튜닝에서 중요한 건 모델보다 데이터셋일 수 있다.
좋은 파인튜닝 = 좋은 데이터 + 명확한 기준 + 별도 평가셋데이터가 없다면 먼저 운영 로그를 모으고, 실패 사례를 분류하고, 좋은 답변 기준을 정리하는 게 먼저다.
3. 문제 정의가 흐릿할 때
"우리 서비스에 맞게 똑똑하게 해줘"는 파인튜닝하기 어렵다. 무엇이 좋은 답변인지, 어떤 답변은 피해야 하는지, 어떤 상황에서 거절해야 하는지, 어떤 형식을 지켜야 하는지 정의되어 있어야 한다. 파인튜닝은 모호한 요구를 알아서 해결해주는 기술이 아니라, 이미 정의된 기준을 더 안정적으로 수행하게 만드는 기술에 가깝다.
4. 평가 기준이 없을 때
파인튜닝을 했는데 좋아졌는지 나빠졌는지 판단할 수 없다면 위험하다. 몇 개 예시만 보고 "오, 좋아졌는데?"라고 느낄 수는 있다. 하지만 실제 운영에서는 특정 케이스에서만 좋아지고 다른 케이스에서는 나빠졌을 수 있다. 그래서 학습 데이터와 별도로 평가셋이 필요하다.
학습 데이터:
모델을 훈련하는 데 사용
검증 데이터:
학습 중 성능을 확인하는 데 사용
테스트 데이터:
최종 품질을 평가하는 데 사용평가 없는 파인튜닝은 감으로 하는 리팩터링과 비슷하다. 좋아진 것처럼 보이지만 실제로는 회귀가 생겼을 수 있다.
RAG와 파인튜닝을 같이 봐야 하는 이유
파인튜닝을 보다 보면 RAG와 계속 비교하게 된다. 둘은 해결하는 문제가 다르다.
RAG:
모델에게 필요한 정보를 찾아준다.
파인튜닝:
모델이 답하는 방식을 조정한다.예를 들어 사내 문서 기반 챗봇을 만든다고 해보자. 사내 정책, 복지 제도, 배포 프로세스 같은 정보는 계속 바뀐다. 이건 RAG가 맡는 게 자연스럽다.
하지만 답변을 항상 짧게 요약하고, 관련 문서 링크를 붙이고, 모르는 경우 추측하지 않고 "문서에서 찾지 못했다"고 말하게 하는 것은 파인튜닝의 영역일 수 있다.
RAG:
무엇을 참고할지 결정한다.
파인튜닝:
참고한 내용을 어떻게 답할지 결정한다.이렇게 보면 둘은 대체 관계가 아니다. 오히려 같이 쓰는 그림이 자연스럽다.
1. RAG로 최신 문서를 가져온다
2. 파인튜닝된 모델이 그 문서를 서비스 톤과 형식에 맞게 답한다
3. 구조화 출력/검증 로직으로 마지막 품질을 확인한다결국 문제는 RAG냐 파인튜닝이냐가 아니라, 지금 실패 원인이 지식인지 행동인지 구분하는 것이다.
실전!
1. 프롬프트로 먼저 해결해본다
2. few-shot 예시를 추가한다
3. RAG나 구조화 출력으로 해결 가능한지 본다
4. 반복적으로 실패하는 패턴을 모은다
5. 좋은 답변 기준을 문서화한다
6. 학습 데이터와 평가 데이터를 분리한다
7. 작은 범위로 SFT를 시도한다
8. 필요하면 LoRA/QLoRA 같은 PEFT 방식으로 비용을 낮춘다
9. 운영 로그로 계속 평가한다여기서 핵심은 4번이다.
파인튜닝은 "더 잘하게 만들고 싶다"에서 시작하면 막막하다. 대신 "모델이 반복적으로 이 상황에서 이런 실수를 한다"에서 시작하면 훨씬 명확해진다.
예를 들어 이런 식이다.
반복 실패:
환불 불가 상품에 대해 너무 차갑게 거절한다.
원하는 행동:
환불 불가 사유를 설명하되,
가능한 대안도 함께 제시한다.
좋은 답변:
"해당 상품은 정책상 환불이 어렵습니다. 다만 사용 전 상태라면 교환 가능 여부를 확인해드릴 수 있습니다."이렇게 실패 패턴, 원하는 행동, 좋은 예시가 있어야 파인튜닝 데이터가 된다.
파인튜닝은 제품 설계 문제에 가깝다
문서와 논문을 같이 보니, 오히려 제품 설계 문제에 가깝다는 생각이 들었다. 모델을 파인튜닝하려면 결국 이런 질문에 답해야 한다.
우리 서비스에서 좋은 답변은 무엇인가?
나쁜 답변은 무엇인가?
어떤 상황에서 거절해야 하는가?
어떤 톤을 유지해야 하는가?
어떤 형식을 반드시 지켜야 하는가?
어떤 실패를 가장 먼저 줄여야 하는가?이 질문들은 순수한 ML 질문이라기보다 제품, UX, 정책, 운영의 질문이다. 그래서 파인튜닝은 모델을 더 똑똑하게 만드는 일이라기보다, 제품이 원하는 행동 기준을 모델에게 전달하는 일에 가깝다. AI 제품에서 중요한 건 모델 성능 자체만이 아니다. 모델이 제품 안에서 어떤 캐릭터로 말하고, 어떤 기준으로 판단하고, 어떤 상황에서 멈추고, 어떤 형식으로 결과를 돌려주는지가 중요하다.
프롬프트는 그 기준을 빠르게 실험하는 도구다. RAG는 필요한 근거를 연결하는 도구다. 파인튜닝은 검증된 행동 패턴을 더 안정적으로 만드는 도구다.
프롬프트: 방향을 준다
RAG: 근거를 준다
파인튜닝: 습관을 만든다생각 정리
파인튜닝을 공부하기 전에는 "언제 파인튜닝을 해야 하지?"가 궁금했다. 그런데 레퍼런스들을 보고 나니 질문이 조금 바뀌었다.
우리는 모델에게 어떤 행동을 반복해서 시키고 싶은가?
그 행동을 좋은 데이터로 보여줄 수 있는가?
그 행동이 좋아졌는지 평가할 수 있는가?
그걸 감당 가능한 비용으로 실험할 수 있는가?결국 흐름은 두 방향으로 정리되는 것 같다.
1. 더 좋은 신호로 모델을 조정하기
- SFT
- RFT
- preference tuning
2. 더 적은 비용으로 모델을 조정하기
- PEFT
- LoRA
- QLoRA다음에는 실제로 작은 데이터셋을 만들어서, API 기반 SFT나 LoRA 방식으로 어떤 결과 차이가 나는지 실험해보면 재밌을 것 같다.