미세 조정

**미세 조정**은 기존 모델을 가져와서 자신의 예제에 대해 계속 학습시켜 기본 동작을 원하는 방향으로 변경하는 것입니다. 이 장에서는 이것이 무엇을 변경하는지, 무엇에 좋은지, 그리고 프롬프팅이나 검색 대신 언제 사용해야 하는지에 대한 실질적인 그림을 제시합니다.
학습이 실제로 하는 일
미세 조정이 무엇을 변경하는지 보려면 모델이 어디서 나오는지 아는 것이 도움이 됩니다. 모델은 크게 두 단계로 구축됩니다.
첫 번째는 **사전 학습**입니다: 모델은 엄청난 양의 텍스트를 읽고 다음 토큰을 예측하는 것을 반복적으로 배우며, 문법, 사실, 추론 패턴이 부작용으로 정착됩니다. 그 결과는 기반 모델로, 유창하지만 초점이 없습니다. 텍스트를 계속 이어갈 수 있지만 질문에 답하는 도움이 되는 어시스턴트로 훈련되지 않았습니다.
두 번째 단계는 사후 학습입니다: 기반 모델은 좋은 응답의 엄선된 예제와 어떤 답변이 더 좋은지에 대한 인간의 피드백에 대해 추가로 훈련됩니다. 이것이 원시 텍스트 예측기를 실제로 대화하는 도움이 되는 어시스턴트로 변환합니다. API에서 호출하는 모델은 이미 두 단계를 모두 거친 것입니다.
두 단계 모두 동일한 메커니즘으로 작동합니다: 모델에 예제를 보여주고 내부 숫자인 매개변수 또는 가중치를 조정하여 예측이 그 예제에 더 가까워지도록 합니다. 학습은 모델을 영구적으로 변경하는 예측 연습입니다.
미세 조정이란
미세 조정은 그 두 번째 단계의 작은, 표적화된 버전으로, 당신에 의해 실행됩니다. 이미 훈련된 모델을 가져와서 자신의 예제 집합에 대해 계속 훈련시키며, 각 예제는 입력과 원하는 출력이 쌍을 이룹니다. 충분한 예제 후에 모델의 가중치는 이 종류의 응답이 기본값이 되도록 이동하며, 프롬프트에서 매번 요청할 필요가 없습니다.
프롬프팅 및 RAG와의 실제 차이는 변경이 어디에 사는지입니다. 프롬프팅 및 RAG는 모델을 동결시키고 호출 시점에 제공하는 컨텍스트를 통해 이를 조종합니다. 미세 조정은 모델 자체를 변경하므로 새로운 동작이 구워지고 짧은 프롬프트에서도 나타납니다. 런타임에 더 나은 지시를 주지 않습니다; 이미 원하는 방식으로 기울어진 모델을 출시하고 있습니다.
실제로는 공급자에게 예제 대화 파일을 제공하고, 이는 훈련 작업을 실행하며, 새로운 **모델 id**를 반환합니다. 그 id를 다른 모델처럼 정확히 호출하면, 그 응답은 훈련한 내용을 반영합니다. 미세 조정은 동작을 모델로 이동하며, 프롬프팅과 RAG는 동결된 것을 조종합니다.
무엇이 좋은지, 무엇이 나쁜지
미세 조정은 프롬프트가 내리기에 어려운 **일관된 동작**이 필요할 때 자리를 차지합니다: 매번 정확한 출력 형식, 특정 톤 또는 집 스타일, 또는 수천 개의 호출에서 안정적으로 수행되는 분류와 같은 좁은 작업. 또한 그렇지 않으면 긴 프롬프트에 명시할 동작이 모델에 구워지므로 프롬프트가 짧아지기 때문에 호출을 더 싸고 빠르게 만들 수 있습니다.
이것이 실패하는 곳은 지식입니다. 미세 조정은 모델에 새로운 사실을 가르치는 데 별로이며, 변하는 사실에는 더 나쁩니다. 훈련 예제는 정확한, 조회 가능한 항목으로 저장되기보다 일반적인 패턴으로 흐려지므로, 미세 조정된 모델은 여전히 세부 정보를 발명하고 정보가 업데이트되는 순간 구식이 됩니다. 가격이나 정책이 변경될 때마다 재훈련하는 것은 느리고 비용이 많이 듭니다. 문제가 "모델이 X를 모른다"일 때, 답은 거의 항상 미세 조정이 아니라 RAG입니다.
경험의 법칙: 형식을 변경하려면 미세 조정하고 사실을 추가하려면 하지 마세요. 모델에 답변하는 방법을 가르치고 검색이 무엇으로 답변할지 처리하도록 합니다.
프롬프팅, RAG, 또는 미세 조정?
대부분의 경우 당신은 여기서 시작하지 않습니다. 세 기술은 **사다리**를 형성하며, 변경하기에 가장 싸고 빠릅니다:
- 프롬프팅. 항상 이것을 먼저 시도하세요. 반복하는 데 즉시이고, 추가 비용이 없으며, 명확한 프롬프트와 몇 가지 예제는 사람들이 예상하는 것보다 더 많이 해결합니다. 프롬프트를 작동하게 만들지 않았다면, 미세 조정할 준비가 되지 않은 것입니다.
- RAG. 간격이 지식일 때 이것에 도달하세요: 모델은 사실이 필요하며, 이는 변합니다. RAG는 질문 시점에 이들을 제공하고 모델을 건드리지 않습니다.
- 미세 조정. 간격이 동작이고 프롬프팅이 충분히 일관되게 만들 수 없을 때 또는 당신의 프롬프트가 너무 길어져서 지시를 모델로 구우면 규모에서 더 싸고 빠를 때 이것에 도달하세요.
이들은 상호 배타적이지 않으며, 가장 강력한 시스템이 이들을 결합합니다: 형식과 톤에 대해 모델을 미세 조정하고, 런타임에 RAG를 사용하여 현재 사실을 제공합니다. 훈련에서의 동작, 검색에서의 지식.
따라서 미세 조정 전에 빠른 테스트입니다. 더 나은 프롬프트로 거기에 도달할 수 있습니까? 그렇다면 그렇게 하세요. 간격이 지식이 없습니까? 그렇다면 RAG입니다.
사다리를 올라가세요; 미세 조정은 첫 번째가 아니라 마지막 계단입니다. 프롬프트가 이미 올바르고, 사실이 이미 사용 가능하고, 모델이 여전히 충분히 일관되게 동작하지 않을 때만 미세 조정이 맞는 도구가 됩니다.
실제로
미세 조정 데이터는 특이하지 않습니다. 각 예제는 런타임에 보내는 정확한 형태의 짧은 대화로, 모델이 주었기를 원하는 답변으로 끝납니다:
# 여기에 몇 가지가 표시되어 있습니다; 실제 데이터 세트는 수백에서 수천 개의 예제이고,
# 런타임에 예상하는 입력의 전체 범위를 다룹니다.
training_examples = [
{"messages": [
{"role": "system", "content": "티켓의 긴급도를 낮음, 중간, 높음으로 분류하세요."},
{"role": "user", "content": "이번 주에 두 번 청구되었고 오늘 해결이 필요합니다."},
{"role": "assistant", "content": "높음"},
]},
{"messages": [
{"role": "system", "content": "티켓의 긴급도를 낮음, 중간, 높음으로 분류하세요."},
{"role": "user", "content": "어디선가 다크 모드 설정이 있나요?"},
{"role": "assistant", "content": "낮음"},
]},
# ...
]이들을 파일에 저장하고, 공급자로 훈련 작업을 시작하고, 완료될 때까지 기다립니다. 반환되는 것은 새로운 모델 id로, 다른 모델처럼 정확히 호출합니다:
# 미세 조정된 모델은 다른 id입니다; 다른 모든 것은 변경되지 않습니다.
response = client.chat.completions.create(
model="your-org/urgency-classifier-v1",
messages=[
{"role": "system", "content": "티켓의 긴급도를 낮음, 중간, 높음으로 분류하세요."},
{"role": "user", "content": "내보내기 단추를 클릭할 때 작동하지 않습니다."},
],
)
# response.choices[0].message.content -> "낮음" (레이블만, 훈련한 동작)승리는 동작이 이제 모델에 산다는 것입니다. 지시는 더 짧을 수 있으며, 형식은 수천 개의 호출에서 유지되며, 거기에 도달하기 위해 프롬프트를 늘릴 필요가 없습니다. 비용은 그 주변의 모든 것입니다: 당신은 품질 데이터 세트, 훈련 실행, 그리고 배운 것을 변경하려고 할 때마다 신선한 작업이 필요합니다. 이는 정확히 왜 이것이 사다리의 맨 아래에 앉습니다. 예제를 업로드하고, 모델 id를 얻고, 다른 모델처럼 호출합니다.
이것은 모델이 예측하도록 책상을 배열한 마지막 방법입니다. 다음 장에서는 이를 행동하는 능력을 제공합니다: 도구 사용에서 모델은 자신의 함수를 호출하며, 그 후 에이전트로 루프에서 실행합니다.

