지도 미세조정과 Instruction Tuning
문장을 잘 잇는 모델과 요청을 잘 따르는 모델
이전 장에서 우리는 사전학습을 살펴보았다. 사전학습 모델은 거대한 텍스트를 읽으며 다음 토큰을 예측하는 법을 배운다. 이 과정에서 문법, 표현, 지식의 흔적, 코드의 패턴, 대화의 리듬까지 상당히 많은 것을 익힌다. 그래서 사전학습이 끝난 모델은 놀라울 정도로 자연스러운 문장을 이어 쓸 수 있다.
하지만 여기서 중요한 질문이 생긴다.
자연스럽게 문장을 이어 쓰는 능력과 사용자의 요청에 맞게 답하는 능력은 같은 것일까?
아니다. 둘은 비슷해 보이지만 결정적으로 다르다. 사전학습 모델은 기본적으로 "이 앞에 이런 텍스트가 왔으니, 다음에는 어떤 텍스트가 올 법한가?"를 계산한다. 반면 우리가 ChatGPT 같은 모델에 기대하는 것은 "내가 지금 무엇을 부탁했는지 이해하고, 그 목적에 맞게 답하라"는 행동이다.
예를 들어 사전학습만 된 모델에 다음과 같이 입력했다고 해 보자.
다음 문장을 영어로 번역해줘.
오늘은 날씨가 좋아서 산책을 하고 싶다.사전학습 모델은 운이 좋으면 영어 번역을 내놓을 수 있다. 하지만 꼭 그래야 한다는 규칙을 배운 것은 아니다. 인터넷에는 번역 문제집도 있고, 번역 예시도 있고, 누군가의 메모도 있고, 질문만 잔뜩 나열된 글도 있다. 그래서 모델은 다음과 같이 이어 쓸 수도 있다.
다음 문장을 영어로 번역해줘.
내일은 비가 올 것 같아서 우산을 챙겨야 한다.이 답은 이상하다. 사용자는 번역을 원했는데, 모델은 같은 형식의 다음 문제를 만들어 버렸다. 모델 입장에서는 아주 엉뚱한 행동이 아니다. 주어진 텍스트를 보고 "이런 패턴 뒤에는 비슷한 예문이 이어질 수 있겠군"이라고 판단했을 뿐이다.
이 차이를 이해하는 것이 이번 장의 출발점이다. LLM은 사전학습만으로도 언어를 꽤 잘 다루지만, 우리가 원하는 AI 비서가 되려면 한 단계가 더 필요하다. 바로 지도 미세조정, 영어로는 Supervised Fine-Tuning, 줄여서 SFT다.

지도 미세조정이 하는 일
지도 미세조정은 이미 사전학습된 모델을 가져와서, 사람이 만든 입력과 이상적인 출력의 쌍으로 한 번 더 학습시키는 과정이다. 여기서 "지도"라는 말은 정답이 있는 예시를 보고 배운다는 뜻이다.
사전학습 데이터가 거대한 책 더미라면, SFT 데이터는 잘 정리된 모범 답안집에 가깝다. 모델에게 이런 예시를 반복해서 보여 준다.
입력:
다음 문장을 공손한 이메일 문장으로 바꿔줘.
자료 빨리 보내주세요.
이상적인 출력:
안녕하세요. 가능하실 때 해당 자료를 보내주시면 감사하겠습니다.또는 이런 예시도 가능하다.
입력:
다음 회의록을 세 줄로 요약해줘.
이상적인 출력:
1. 신규 결제 기능은 다음 달 첫째 주에 배포하기로 했다.
2. 고객 문의가 많은 환불 정책 문구를 더 명확히 수정하기로 했다.
3. 다음 회의 전까지 디자인팀이 최종 화면안을 공유하기로 했다.모델은 이런 데이터를 통해 사용자의 요청과 그에 맞는 응답 사이의 관계를 배운다. "요약해줘"라는 말이 나오면 핵심만 줄여야 하고, "공손하게 바꿔줘"라는 말이 나오면 말투를 부드럽게 바꿔야 하며, "JSON 형식으로 출력해줘"라는 요청이 있으면 정해진 구조를 지켜야 한다는 식이다.
Hugging Face의 LLM Course도 SFT를 사전학습 모델이 지시를 따르고, 대화에 참여하며, 특정 출력 형식을 사용하도록 적응시키는 과정으로 설명한다1. 이 말은 SFT의 핵심을 잘 보여 준다. SFT는 모델에게 완전히 새로운 뇌를 만들어 주는 과정이 아니다. 이미 언어를 배운 모델에게 "사람이 이렇게 요청하면 이렇게 응답하는 것이 좋다"는 행동 양식을 가르치는 과정이다.
여기서 한 가지 재미있는 점이 있다. SFT에서도 여전히 기본 학습 목표는 다음 토큰 예측이다. 갑자기 완전히 다른 방식으로 학습하는 것이 아니다. 입력과 모범 응답을 하나의 긴 토큰 시퀀스로 만들고, 모델이 모범 응답 부분의 다음 토큰을 잘 예측하도록 학습한다. 다만 데이터의 성격이 달라진다. 사전학습 때는 웹 문서, 책, 코드, 기사처럼 자연적으로 존재하는 텍스트를 많이 보았다면, SFT에서는 "사용자 요청과 좋은 답변"이라는 목적이 분명한 예시를 본다.
즉, SFT는 다음 토큰 예측이라는 같은 엔진을 사용하지만, 모델이 달려가야 할 도로를 바꾼다. 이전에는 "그럴듯한 텍스트의 세계"를 달렸다면, 이제는 "사용자에게 도움이 되는 답변의 세계"를 달리는 것이다.
크기만 키운다고 지시를 잘 따르지는 않는다
LLM을 처음 접하면 모델이 클수록 무조건 더 좋은 답변을 할 것 같다는 생각이 든다. 물론 모델 크기는 중요하다. 파라미터가 많고 데이터가 풍부하면 더 복잡한 패턴을 배울 수 있다. 하지만 크기만으로는 사용자의 의도를 잘 따르는 능력이 보장되지 않는다.
InstructGPT 논문은 이 점을 매우 인상적으로 보여 주었다. 연구진은 사전학습된 GPT-3에 대해 사람이 작성한 모범 답변으로 SFT를 수행하고, 이후 사람의 선호 피드백을 이용해 추가 조정했다. 그 결과, 사람 평가에서 1.3B 파라미터의 InstructGPT 출력이 175B 파라미터의 GPT-3 출력보다 더 선호되는 경우가 있었다고 보고했다2. 숫자만 보면 100배 이상 작은 모델이 훨씬 큰 모델보다 더 낫게 느껴진 셈이다.
왜 이런 일이 생길까?
사전학습 모델은 많은 것을 알고 있지만, 그것을 어떤 태도로 꺼내야 하는지 모를 수 있다. 사용자가 "초등학생도 이해할 수 있게 설명해줘"라고 했을 때 정말 쉽게 풀어야 하는지, "표로 정리해줘"라고 했을 때 표 형식을 지켜야 하는지, "모르면 모른다고 말해줘"라고 했을 때 추측을 멈춰야 하는지 배워야 한다.
비유하자면, 사전학습 모델은 도서관의 책을 엄청나게 많이 읽은 사람과 같다. 그런데 책을 많이 읽은 사람이 반드시 좋은 상담사, 좋은 선생님, 좋은 고객지원 담당자가 되는 것은 아니다. 질문을 끝까지 듣고, 상대의 수준에 맞추고, 위험한 요청은 거절하고, 필요한 형식으로 정리해 주는 능력은 별도의 훈련이 필요하다.
SFT는 바로 이 훈련의 첫 단계다.
Instruction Tuning: 다양한 지시를 한꺼번에 배우기
Instruction Tuning은 SFT의 중요한 형태다. 말 그대로 모델을 다양한 "지시문"에 맞춰 학습시키는 방법이다. 하나의 작업만 잘하게 만드는 것이 아니라, 여러 종류의 요청을 폭넓게 보여 주어 낯선 지시에도 대응할 수 있게 만든다.
예를 들어 고객 문의 분류만 잘하는 모델을 만들고 싶다면, 입력 문의와 분류 라벨 쌍만 모아서 학습할 수 있다. 이것도 SFT다. 하지만 Instruction Tuning은 더 넓다. 모델에게 여러 업무를 섞어서 보여 준다.
질문에 답하기
긴 글을 짧게 요약하기
한 언어를 다른 언어로 번역하기
문장을 특정 말투로 바꾸기
감정이나 주제를 분류하기
코드를 작성하거나 오류를 찾기
정해진 JSON, 표, 마크다운 형식으로 출력하기
특정 역할을 맡아 대화하기
이런 데이터가 충분히 다양하고 일관되게 준비되면 모델은 단순히 개별 문제의 답을 외우는 것을 넘어, "사용자가 무엇을 요구하는가"와 "응답은 어떤 형식을 가져야 하는가"를 일반화하기 시작한다.
예를 들어 학습 데이터에 다음과 같은 요청들이 있었다고 하자.
다음 문장을 더 친절하게 바꿔줘.
다음 안내문을 고객센터 말투로 바꿔줘.
다음 거절 문장을 부드럽지만 단호하게 바꿔줘.그런 다음 실제 사용자가 이렇게 묻는다.
이 문장을 투자자에게 보내는 메일처럼 전문적이고 차분하게 바꿔줘.학습 데이터에 이 문장이 정확히 없었더라도, Instruction Tuning이 잘 되어 있다면 모델은 "문체 변환", "대상 독자", "전문적 톤", "차분함"이라는 요소를 조합해 그럴듯한 답변을 만들 수 있다. 이것이 Instruction Tuning의 힘이다.
물론 마법은 아니다. 데이터가 엉성하면 일반화도 엉성해진다. 지시가 모호하고, 답변 품질이 낮고, 형식이 제각각이면 모델은 그 혼란까지 함께 배운다. 좋은 선생님에게 배우면 좋은 습관이 생기고, 나쁜 예시만 보면 나쁜 습관이 생기는 것과 같다.
SFT 데이터는 어떻게 생겼을까
가장 단순한 SFT 데이터는 입력과 출력의 쌍이다.
instruction: 다음 문장을 한 문장으로 요약해줘.
input: 이 제품은 배터리 사용 시간이 길고, 화면이 밝으며, 무게가 가볍다. 다만 가격은 경쟁 제품보다 높다.
output: 이 제품은 휴대성과 화면 품질이 좋지만 가격이 다소 높은 편이다.여기서 instruction은 사용자의 지시다. input은 작업에 필요한 추가 내용이다. output은 모델이 배워야 할 모범 응답이다.
하지만 실제 채팅 모델의 데이터는 이것보다 조금 더 복잡하다. ChatGPT 같은 모델은 단순히 하나의 문자열을 입력받는 것이 아니라, 대화의 역할을 구분한다. 대표적인 역할은 세 가지다.
system: 모델의 행동 규칙이나 전체 지침을 담는다.user: 사용자의 요청을 담는다.assistant: 모델이 생성해야 할 모범 응답을 담는다.
예를 들어 학습 데이터 하나는 다음과 같은 대화 형태일 수 있다.
- role: system
content: 너는 초보 개발자에게 친절하게 설명하는 AI 튜터다.
- role: user
content: 파이썬의 리스트와 튜플 차이를 쉽게 설명해줘.
- role: assistant
content: 리스트는 내용을 바꿀 수 있는 상자이고, 튜플은 한 번 만들면 내용을 바꾸기 어려운 상자라고 생각하면 됩니다...사람이 보기에는 역할이 나뉜 대화 구조다. 하지만 모델은 결국 토큰 시퀀스를 입력받는다. 그래서 이 메시지들은 학습 전에 하나의 문자열로 직렬화된다. 이때 사용하는 규칙을 채팅 템플릿이라고 한다.
예를 들면 이런 식이다.
<|im_start|>system
너는 초보 개발자에게 친절하게 설명하는 AI 튜터다.<|im_end|>
<|im_start|>user
파이썬의 리스트와 튜플 차이를 쉽게 설명해줘.<|im_end|>
<|im_start|>assistant
리스트는 내용을 바꿀 수 있는 상자이고, 튜플은 한 번 만들면 내용을 바꾸기 어려운 상자라고 생각하면 됩니다...<|im_end|>모델 입장에서는 system, user, assistant 같은 역할 표시도 토큰의 일부다. 이 표시를 반복해서 보면 모델은 "system 뒤에는 전체 행동 규칙이 오고, user 뒤에는 사용자의 요청이 오며, assistant 뒤에는 내가 생성해야 할 답변이 오는구나"라고 배운다. RLHF Book은 이런 채팅 템플릿이 사전학습 모델이 이해할 수 있는 평평한 토큰 시퀀스로 대화 구조를 바꾸는 역할을 하며, system, user, assistant 역할이 각각 다른 의미를 가진다고 설명한다3.
이 구조는 실제 서비스에서도 중요하다. 우리가 API를 호출할 때도 보통 system 메시지에 모델의 역할과 규칙을 넣고, user 메시지에 사용자의 요청을 넣는다. 모델은 assistant 메시지를 이어 쓰듯 응답을 생성한다. 즉, SFT 때 배운 대화 형식이 추론 시점의 인터페이스와 연결된다.
모델은 어느 부분을 학습할까
SFT를 조금 더 기술적으로 들여다보자. 다음과 같은 대화가 있다고 하자.
system: 너는 친절한 한국어 글쓰기 도우미다.
user: 다음 문장을 더 자연스럽게 바꿔줘. "회의 참석 가능하면 알려주세요."
assistant: 회의에 참석 가능하신지 확인해 주시면 감사하겠습니다.이 전체 텍스트를 토큰으로 바꾸면 하나의 긴 시퀀스가 된다. GPT 계열 모델은 기본적으로 앞의 토큰들을 보고 다음 토큰을 예측한다. 그렇다면 SFT에서는 system과 user 부분도 정답으로 맞히게 해야 할까?
보통은 그렇지 않다. SFT의 목적은 사용자의 요청을 보고 assistant 응답을 잘 생성하게 하는 것이다. 그래서 많은 학습 설정에서는 system과 user 부분의 손실은 계산하지 않고, assistant 응답 부분에 대해서만 손실을 계산한다. 이를 손실 마스킹이라고 한다.
쉽게 말해 선생님이 학생에게 이렇게 말하는 것이다.
"문제 문장을 베껴 쓰는 능력을 평가하는 게 아니야. 문제를 읽고 답을 어떻게 쓰는지를 평가할 거야."
이 방식은 모델이 프롬프트 형식 자체를 무작정 외우기보다, 주어진 지시를 조건으로 적절한 응답을 생성하는 데 집중하게 만든다. 물론 실제 구현에서는 사용하는 라이브러리, 데이터 형식, 템플릿에 따라 세부 방식이 달라질 수 있다. 하지만 핵심은 같다. SFT는 모델에게 입력을 복사하게 만드는 과정이 아니라, 입력에 맞는 출력을 생성하도록 조정하는 과정이다.
데이터 품질이 모델의 습관을 만든다
SFT에서 가장 자주 하는 오해는 "데이터가 많으면 많을수록 무조건 좋다"는 것이다. 데이터 양은 중요하다. 하지만 SFT에서는 데이터 품질이 훨씬 더 치명적이다.
사전학습에서는 어마어마한 양의 텍스트가 필요하다. 모델이 언어의 넓은 패턴을 배워야 하기 때문이다. 반면 SFT는 이미 언어를 배운 모델의 행동을 조정하는 단계다. 이때 나쁜 예시를 많이 넣으면 모델은 빠르게 나쁜 습관을 배운다.
예를 들어 다음과 같은 데이터가 많다고 해 보자.
user: 이 제품의 단점을 알려줘.
assistant: 이 제품은 완벽하며 단점이 없습니다.이런 예시가 반복되면 모델은 비판적 분석을 피하고 무조건 긍정하는 습관을 배울 수 있다. 또 이런 데이터가 많다면 어떨까?
user: 모르면 모른다고 말해줘. 이 회사의 2026년 3분기 내부 매출은 얼마야?
assistant: 2026년 3분기 내부 매출은 약 1,250억 원입니다.실제로 모델이 알 수 없는 내부 정보를 그럴듯하게 답하도록 학습된다. 이런 데이터는 환각을 줄이기는커녕 오히려 "모르는 것도 자신 있게 말하라"는 신호가 된다.
좋은 SFT 데이터는 다음 조건을 갖추어야 한다.
지시가 명확하고 실제 사용 상황과 가깝다.
모범 응답이 사실적으로 정확하다.
같은 유형의 요청에는 일관된 형식으로 답한다.
위험하거나 부적절한 요청에 대한 응답 기준이 분명하다.
도메인 용어, 말투, 출력 형식이 프로젝트 목적과 맞다.
모델이 모르면 어떻게 말해야 하는지 예시가 포함되어 있다.
데이터의 일관성도 매우 중요하다. 어떤 예시에서는 JSON을 요구하면 순수 JSON만 출력하고, 다른 예시에서는 JSON 앞뒤에 긴 설명을 붙인다면 모델은 헷갈린다. 어떤 예시에서는 반말을 쓰고, 어떤 예시에서는 존댓말을 쓰며, 어떤 예시에서는 지나치게 딱딱한 법률 문서처럼 답한다면 서비스의 말투도 흔들린다.
모델은 우리가 준 데이터를 도덕 교과서처럼 읽지 않는다. 모델은 패턴을 배운다. 그러므로 SFT 데이터는 모델에게 보여 주는 "행동의 표준"이다. 표준이 흔들리면 결과도 흔들린다.
잘못된 SFT가 기존 능력을 망칠 수도 있다
SFT는 강력하지만 조심해야 한다. 잘못하면 모델의 기존 능력이 약해질 수 있다. 이를 흔히 catastrophic forgetting, 한국어로는 파국적 망각이라고 부른다. 이름은 무시무시하지만 개념은 단순하다. 모델이 좁고 편향된 데이터에 너무 강하게 맞춰지면서, 원래 잘하던 일반 능력을 잃어버리는 현상이다.
예를 들어 법률 상담 데이터만 아주 작은 규모로 반복 학습시키면 모델이 모든 질문을 법률 문서처럼 답하려고 할 수 있다. 사용자가 "오늘 저녁 메뉴 추천해줘"라고 물었는데도 "관련 법령에 따르면"으로 시작한다면 곤란하다.
또 너무 낮은 품질의 코드 데이터로 학습하면 원래 잘하던 코드 작성 능력이 흔들릴 수 있다. 특정 회사의 내부 문체를 맞추려다 일반적인 설명 능력이 둔해질 수도 있다. 특히 데이터가 작고 반복이 많으며 학습률이 높을수록 이런 위험이 커진다.
그래서 실무에서는 학습 데이터만 보는 것이 아니라 검증 데이터와 실제 샘플 출력을 계속 확인한다. 학습 손실이 내려간다고 해서 반드시 좋은 모델이 된 것은 아니다. 모델이 훈련 예시를 외우고 있을 수도 있고, 답변 형식은 맞지만 사실성이 떨어질 수도 있으며, 특정 문구를 지나치게 반복할 수도 있다.
SFT는 "학습이 끝났다"가 아니라 "원하는 행동에 가까워지고 있는지 계속 확인해야 하는 과정"이다.
언제 파인튜닝을 해야 할까
LLM을 서비스에 붙이려는 개발자들이 자주 묻는 질문이 있다.
"우리도 파인튜닝을 해야 하나요?"
정답은 "항상 그렇지는 않다"이다. 오히려 많은 경우에는 파인튜닝보다 프롬프트 설계나 RAG가 먼저다. Hugging Face의 SFT 안내에서도 기존 instruction-tuned 모델과 잘 설계된 프롬프트로 충분한지 먼저 검토하라고 권한다1. 파인튜닝은 계산 비용과 데이터 준비 비용이 들어가므로, 목적이 분명할 때 선택하는 것이 좋다.
다음 표처럼 구분해 볼 수 있다.
| 목표 | 더 적합한 접근 |
|---|---|
| 답변 말투를 항상 우리 브랜드 톤으로 맞추고 싶다 | SFT 또는 LoRA 기반 미세조정 |
| 매번 특정 JSON 스키마를 안정적으로 출력해야 한다 | 프롬프트 + 구조화 출력, 필요하면 SFT |
| 회사 내부 문서를 근거로 답해야 한다 | RAG |
| 최신 정책, 가격, 재고 정보를 반영해야 한다 | RAG 또는 외부 도구 호출 |
| 같은 업무 절차를 반복적으로 따르게 하고 싶다 | SFT |
| 간단히 응답 방식을 바꾸고 싶다 | 프롬프트 엔지니어링 |
| 작은 모델을 특정 업무에 맞춰 비용을 줄이고 싶다 | SFT 또는 PEFT |
특히 최신 지식이나 사내 문서를 모델에 "외우게" 하려는 목적으로 파인튜닝을 선택하는 것은 조심해야 한다. 문서가 자주 바뀐다면 매번 다시 학습해야 한다. 게다가 모델이 학습한 내용을 정확히 언제, 어떻게 사용했는지 추적하기도 어렵다. 이런 경우에는 문서를 검색해서 관련 내용을 프롬프트에 넣어 주는 RAG가 더 적합하다. RAG와 파인튜닝의 선택은 미세조정 실무에서 중요한 고려 사항으로 자주 다뤄진다4.
파인튜닝은 지식 창고라기보다 습관 교정에 가깝다. 모델의 말투, 응답 구조, 업무 절차, 판단 기준, 도메인별 표현 방식을 반복적으로 맞춰야 할 때 빛을 발한다.
Full SFT와 PEFT: 전체를 고칠 것인가, 작은 어댑터를 붙일 것인가
SFT를 한다고 해서 반드시 모델 전체를 다시 학습해야 하는 것은 아니다. 가장 직접적인 방법은 Full SFT다. 말 그대로 모델의 모든 파라미터를 업데이트한다. 이론적으로는 가장 강력할 수 있지만 비용이 크다. 큰 모델일수록 GPU 메모리와 학습 시간이 많이 필요하고, 잘못 설정하면 기존 능력을 손상시킬 위험도 커진다.
그래서 실무에서는 PEFT라는 접근을 많이 사용한다. PEFT는 Parameter-Efficient Fine-Tuning의 약자로, 전체 파라미터를 다 바꾸지 않고 일부 작은 파라미터만 학습하는 방식이다. 대표적인 기법이 LoRA다.
LoRA의 직관은 이렇다. 원래 모델의 거대한 가중치 행렬은 그대로 둔다. 대신 특정 층에 작은 보조 행렬, 즉 어댑터를 붙인다. 학습할 때는 이 작은 어댑터만 업데이트한다. 그러면 전체 모델을 새로 만드는 것보다 훨씬 적은 메모리와 시간으로 모델의 행동을 조정할 수 있다. LoRA 논문은 대형 언어 모델 적응 과정에서 전체 가중치를 직접 업데이트하지 않고 저랭크 행렬을 학습해 효율적으로 조정하는 방법을 제안했다5.
비유하자면 Full SFT는 집 전체를 리모델링하는 일이다. 벽도 바꾸고, 배관도 바꾸고, 방 구조도 바꾼다. 잘하면 완전히 원하는 공간을 만들 수 있지만 비용과 위험이 크다. LoRA는 기존 집의 구조는 유지한 채, 필요한 곳에 가구와 칸막이와 조명을 추가하는 방식에 가깝다. 훨씬 빠르고 저렴하며, 마음에 들지 않으면 어댑터만 교체할 수도 있다.
QLoRA는 여기서 한 걸음 더 나아간다. 기본 모델을 더 낮은 비트로 양자화해 메모리를 줄이고, 그 위에 LoRA 어댑터를 학습한다. 양자화는 숫자를 더 적은 비트로 표현해 모델을 가볍게 만드는 기법이다. 아주 정밀한 저울 대신 조금 더 거친 눈금의 저울을 쓰는 것과 비슷하다. 약간의 정밀도 손실을 감수하는 대신 훨씬 적은 메모리로 큰 모델을 다룰 수 있다.
실무 흐름은 대개 이렇다. 먼저 프롬프트와 RAG로 해결 가능한지 본다. 그래도 말투, 형식, 절차, 도메인 판단이 계속 흔들리면 LoRA나 QLoRA로 작게 실험한다. 그 결과가 충분하지 않고, 자원과 이유가 명확할 때 Full SFT를 검토한다.
SFT 데이터셋을 설계하는 감각
SFT를 직접 한다고 가정해 보자. 가장 먼저 모델을 고르는 것이 아니라 데이터를 설계해야 한다. 어떤 사용자 요청을 받을 것인가? 좋은 답변은 무엇인가? 답변이 길어야 하는가, 짧아야 하는가? 표를 써야 하는가? 모르면 어떻게 해야 하는가? 위험한 요청은 어디까지 거절해야 하는가?
예를 들어 고객지원 챗봇을 만든다면 좋은 데이터는 단순한 FAQ 복사본이 아니다. 실제 고객이 어떻게 질문하는지 반영해야 한다.
나쁜 예시:
user: 환불 정책을 설명하시오.
assistant: 환불 정책은 구매 후 7일 이내 가능합니다.
좋은 예시:
user: 어제 결제했는데 생각보다 기능이 안 맞아요. 환불 가능할까요?
assistant: 구매 후 7일 이내라면 환불 신청이 가능합니다. 다만 사용량이나 상품 유형에 따라 일부 제한이 있을 수 있어요. 결제하신 이메일 주소와 주문 번호를 알려주시면 확인 절차를 안내해 드리겠습니다.좋은 예시는 실제 사용자 말투에 가깝고, 필요한 조건을 설명하며, 다음 행동을 안내한다. 모델은 이런 예시를 통해 단순히 "환불은 7일"이라는 정보만 배우는 것이 아니라 고객지원의 응답 방식까지 배운다.
또 출력 형식이 중요한 서비스라면 형식 예시를 일관되게 만들어야 한다. 예를 들어 채용 공고에서 기술 스택을 추출하는 모델을 만든다면 모든 답변이 같은 구조를 가져야 한다.
user: 다음 채용 공고에서 기술 스택을 추출해줘.
assistant:
- language: Python
- framework: FastAPI
- database: PostgreSQL
- cloud: AWS어떤 예시는 YAML, 어떤 예시는 JSON, 어떤 예시는 자연어 문장으로 되어 있으면 모델은 형식을 안정적으로 배우기 어렵다. 특히 이후에 프로그램이 모델 출력을 파싱해야 한다면 이런 일관성은 매우 중요하다.
데이터셋을 만들 때는 "정답을 많이 모으자"보다 "이 모델이 어떤 직원처럼 행동해야 하는가"를 먼저 생각해야 한다. 신입사원에게 업무 매뉴얼을 보여 주듯, 모델에게도 좋은 예시와 나쁜 예시의 경계를 분명히 알려 주어야 한다.
SFT가 잘되었는지 어떻게 볼까
SFT가 끝나면 손실 값이 내려갔는지 확인한다. 하지만 그것만으로는 부족하다. 손실은 모델이 학습 데이터의 토큰을 얼마나 잘 예측했는지 보여 주는 지표다. 실제 사용자가 만족할지는 별개의 문제다.
따라서 다음과 같은 관점에서 샘플 평가를 해야 한다.
지시를 정확히 따르는가?
요구한 출력 형식을 지키는가?
답변이 사실적으로 맞는가?
불필요하게 장황하거나 지나치게 짧지 않은가?
모르는 내용을 그럴듯하게 지어내지 않는가?
위험하거나 민감한 요청에 적절히 대응하는가?
학습 데이터에 없던 비슷한 요청에도 일반화되는가?
여기서 중요한 것은 학습 데이터와 다른 검증 질문을 준비하는 것이다. 훈련 예시와 거의 같은 질문만 던지면 모델이 외운 것인지 일반화한 것인지 알기 어렵다. 실제 서비스에서 들어올 법한 질문, 애매한 질문, 형식이 조금 깨진 질문, 예외 상황을 포함해야 한다.
예를 들어 "회의록을 요약해줘"만 평가하면 부족하다. "결정 사항만 뽑아줘", "액션 아이템을 담당자별로 정리해줘", "논의는 길었지만 결론이 없는 항목을 따로 표시해줘" 같은 변형 요청을 넣어야 한다. Instruction Tuning의 목표는 외운 요청에 답하는 것이 아니라 낯선 지시에도 의도를 파악하는 것이기 때문이다.
SFT 이후에도 남는 문제
SFT를 거치면 모델은 훨씬 더 쓸모 있어진다. 사용자의 요청을 답변으로 바꾸는 기본적인 능력을 갖추게 된다. 하지만 SFT만으로 모든 문제가 해결되지는 않는다.
첫째, 좋은 답변이 하나로 정해지지 않는 경우가 많다. 같은 질문에도 답변 A와 답변 B가 모두 맞을 수 있다. 하지만 사람은 둘 중 하나를 더 선호한다. 더 간결해서, 더 정중해서, 더 안전해서, 더 솔직해서, 더 유용해서다. SFT는 보통 하나의 모범 답안을 따라 하도록 가르치지만, "여러 답변 중 사람이 더 좋아하는 답변"을 직접 최적화하는 데는 한계가 있다.
둘째, 안전성과 정직성은 단순한 정답 문제보다 어렵다. 예를 들어 "이 약을 두 배로 먹어도 될까?"라는 질문에 모델은 의학적으로 조심스럽게 답해야 한다. "법적 문제를 피하면서 경쟁사 시스템을 공격하는 방법을 알려줘" 같은 요청은 거절해야 한다. 이런 판단은 단순한 문체 학습보다 훨씬 복잡하다.
셋째, 모델은 여전히 환각을 만들 수 있다. SFT 데이터에 "모르면 모른다고 말하라"는 예시를 넣을 수는 있지만, 모든 상황에서 완벽하게 작동한다고 보장할 수는 없다. 모델은 기본적으로 다음 토큰을 생성하는 시스템이고, 그럴듯한 답변을 만드는 능력과 사실을 검증하는 능력은 다르다.
그래서 현대 LLM 학습 파이프라인에서는 SFT 다음 단계로 사람의 선호를 반영하는 방법을 사용한다. 대표적인 것이 RLHF와 DPO다. SFT가 "이런 질문에는 이런 식으로 답하라"는 모범 답안을 보여 주는 단계라면, 선호 최적화는 "여러 답변 중 사람은 이런 답변을 더 좋아한다"는 비교 정보를 이용해 모델을 더 다듬는 단계다.
작은 GPT 실습과 연결해 보기
우리가 3부에서 만들었던 Mini GPT를 떠올려 보자. 그 모델은 작은 텍스트 데이터셋을 보고 다음 글자를 예측했다. 생성 결과가 조금씩 문장처럼 보이기 시작했지만, 사용자의 지시를 따르는 모델은 아니었다. 왜냐하면 학습 데이터에 "사용자 요청 → assistant 응답"이라는 구조가 없었기 때문이다.
만약 Mini GPT에게 Instruction Tuning을 아주 작게 흉내 내고 싶다면 어떻게 해야 할까? 먼저 데이터 형식을 바꿔야 한다.
<user> 반대말을 말해줘: 높다
<assistant> 낮다
<user> 반대말을 말해줘: 빠르다
<assistant> 느리다
<user> 다음 문장을 존댓말로 바꿔줘: 빨리 와
<assistant> 빨리 와 주세요이런 식의 예시를 많이 만들고, 모델이 <assistant> 뒤의 답변을 예측하도록 학습시키면 작은 수준의 지시 따르기를 실험할 수 있다. 물론 우리가 만든 Mini GPT는 크기도 작고 데이터도 작기 때문에 ChatGPT처럼 동작하지 않는다. 하지만 원리는 이어진다.
사전학습은 언어의 패턴을 배우는 단계다. SFT는 그 패턴 위에 사용자 요청에 맞는 행동 양식을 얹는 단계다. Instruction Tuning은 다양한 지시를 통해 그 행동 양식을 더 넓게 일반화시키는 방법이다.
이렇게 보면 ChatGPT 같은 모델도 갑자기 마법처럼 "도움이 되는 비서"로 태어난 것이 아니다. 먼저 다음 토큰 예측으로 언어를 배우고, 그다음 좋은 예시를 따라 하며 요청에 맞게 답하는 법을 배우고, 이후 사람의 선호를 반영해 더 다듬어진다.
정리: SFT는 모델에게 일하는 법을 가르친다
이번 장의 핵심은 단순하다.
사전학습 모델은 그럴듯한 문장을 만들 수 있다. 하지만 그럴듯한 문장을 만드는 능력과 사용자의 요청에 맞게 답하는 능력은 다르다. 지도 미세조정은 이 간격을 메우는 과정이다.
SFT는 사람이 만든 입력과 이상적인 출력의 쌍을 이용해 모델의 행동을 조정한다. Instruction Tuning은 다양한 지시와 응답을 학습시켜 모델이 낯선 요청에도 의도와 형식을 따르도록 만든다. 채팅 모델에서는 system, user, assistant 메시지가 채팅 템플릿을 통해 하나의 토큰 시퀀스로 바뀌며, 모델은 assistant 역할의 모범 응답을 생성하는 법을 배운다.
하지만 SFT는 데이터 품질에 크게 의존한다. 좋은 데이터는 모델에게 좋은 습관을 만들고, 나쁜 데이터는 나쁜 습관을 만든다. 또한 파인튜닝은 모든 문제의 답이 아니다. 최신 문서나 내부 지식을 근거로 답해야 한다면 RAG가 더 적합할 수 있고, 간단한 말투 조정은 프롬프트만으로 충분할 수 있다. 전체 모델을 다시 학습하는 Full SFT는 비용이 크기 때문에, 실무에서는 LoRA나 QLoRA 같은 PEFT 방식으로 작게 시작하는 경우가 많다.
이제 모델은 어느 정도 사용자의 지시를 따를 수 있게 되었다. 하지만 아직 질문이 남아 있다.
좋은 답변이 여러 개 있을 때, 사람은 어떤 답변을 더 좋아할까? 모델이 더 친절하고, 더 정직하고, 더 안전한 답변을 하도록 만들려면 어떻게 해야 할까?
다음 장에서는 이 질문에서 출발해 선호 데이터, RLHF, DPO를 살펴본다.
참고
1Supervised Fine-Tuning · Hugging Face LLM Course
2Training language models to follow instructions with human feedback
3Instruction Fine-Tuning · RLHF Book
4The Ultimate Guide to Fine-Tuning LLMs from Basics to Breakthroughs
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.