미세조정(fine-tuning)으로 모델 맞춤화하기

미세조정(fine-tuning)으로 모델 맞춤화하기

프롬프트 엔지니어링만으로는 원하는 품질이 안 나올 때, 다음 단계가 바로 **미세조정(fine-tuning)**이에요. 사용자 데이터로 모델 가중치를 직접 학습시켜서 프롬프트에 다 담을 수 없는 만큼의 예시를 모델에 새겨 넣는 방식이죠. Microsoft Foundry는 LoRA(저랭크 적응) 방식으로 복잡도를 줄여 더 빠르고 저렴하게 미세조정을 지원해요.

출처: 공식 문서 - Customize a model with fine-tuning

미세조정으로 얻는 것

  • 프롬프트 엔지니어링만으로 얻기 어려운 더 높은 품질의 결과.
  • 모델의 요청 컨텍스트 한도에 담을 수 있는 것보다 더 많은 예시로 학습.
  • 프롬프트가 짧아져 토큰 절약.
  • 특히 작은 모델을 쓸 때 응답 지연이 낮아짐.

Few-shot 학습과 달리 미세조정은 프롬프트에 들어갈 수 있는 것보다 더 많은 예시로 학습해서 성능을 끌어올려요. 가중치가 작업에 맞춰지므로 넣는 예시·지시가 줄어들고, 그만큼 호출당 토큰이 줄어 비용과 지연이 함께 내려갈 수 있어요.

사전 준비

  • 언제 미세조정을 쓸지 안내를 먼저 읽어요.
  • Azure 구독과 Foundry 프로젝트 리소스가 필요해요.
  • 미세조정에는 Foundry Owner 역할이 필요해요. Foundry User도 학습(미세조정)은 가능하지만 배포는 AI Owner만 가능해요.

지원 모델

다음 모델들이 미세조정을 지원해요. 주요 모델을 요약하면 아래와 같아요.

Model ID 방법 상태 모달리티
gpt-4o-mini (2024-07-18) SFT GA 텍스트→텍스트
gpt-4o (2024-08-06) SFT, DPO GA 텍스트·비전→텍스트
gpt-4.1 (2025-04-14) SFT, DPO GA 텍스트·비전→텍스트
gpt-4.1-mini (2025-04-14) SFT, DPO GA 텍스트→텍스트
gpt-4.1-nano (2025-04-14) SFT, DPO GA 텍스트→텍스트
o4-mini (2025-04-16) RFT GA 텍스트→텍스트
gpt-5 (2025-08-07) RFT GA* 텍스트→텍스트
Ministral-3B (2411) SFT 공개 미리보기 텍스트→텍스트
Qwen-32B SFT 공개 미리보기 텍스트→텍스트
Llama-3.3-70B-Instruct SFT 공개 미리보기 텍스트→텍스트
gpt-oss-20b SFT 공개 미리보기 텍스트→텍스트

*GPT-5의 강화학습 미세조정(RLHF 기반 RFT)은 GA지만 초대 기반으로 접근이 제한돼 있어요. 참여하려면 Microsoft 계정 팀에 문의하세요.

이미 미세조정된 모델도 다시 미세조정할 수 있어요. 그 경우 모델 ID는 base-model.ft-{jobid} 형태로 표시돼요.

데이터 준비

훈련·검증 데이터는 JSONL(JSON Lines) 형식이어야 하고, Chat Completions API가 쓰는 대화 형식이어야 해요. 파일은 UTF-8 인코딩에 BOM이 포함돼야 하고, 개별 파일 크기는 512MB 미만이어야 해요.

예시 파일 형식:

{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who discovered Antarctica?"}, {"role": "assistant", "content": "Some chaps named Fabian Gottlieb von Bellingshausen and Mikhail Lazarev, as if they don't teach that in every school!"}]}

한 줄에 여러 턴의 대화를 넣는 것도 지원돼요. 특정 assistant 메시지의 미세조정을 건너뛰려면 선택적 weight 키/값을 추가하면 되고, 현재 weight0 또는 1로 설정할 수 있어요.

{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the biggest city in France?"}, {"role": "assistant", "content": "Paris", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already.", "weight": 1}]}

비전 모델은 이미지 URL을 담은 image_url 콘텐츠 타입을 그대로 사용해요.

{"messages": [{"role": "user", "content": [{"type": "text", "text": "What's in this image?"}, {"type": "image_url", "image_url": {"url": "https://raw.githubusercontent.com/MicrosoftDocs/azure-ai-docs/main/articles/ai-services/openai/media/how-to/generated-seattle.png"}}]}, {"role": "assistant", "content": "The image appears to be a watercolor painting of a city skyline..."}]}

데이터셋 크기 고려사항

미세조정 작업은 훈련 예시가 최소 10개는 있어야 진행돼요. 다만 그 정도로는 모델 응답에 눈에 띄게 영향을 주기 어려워요. 성공적인 미세조정은 수백~수천 개의 예시를 권장하고, 잘 만들어진 예시 50개부터 시작하라고 권해요. 일반적으로 데이터셋을 2배로 늘리면 모델 품질이 선형적으로 오를 수 있지만, 저품질 예시가 많으면 오히려 성능이 나빠질 수 있으니 최고 품질 예시만 골라 쓰세요.

만들어진 모델 배포하기

미세조정이 끝난 모델은 관리 평면(control plane) REST API로 배포할 수 있어요. skustandard를, properties.model.formatOpenAI, name은 이전 호출에서 반환된 fine-tuned 모델 ID를 넣어요.

deploy_data = {
    "sku": {"name": "standard", "capacity": 1},
    "properties": {
        "model": {
            "format": "OpenAI",
            "name": "gpt-4.1-2025-04-14.ft-b044a9d3cf9c4228b5d393567f693b83",
            "version": "1"
        }
    }
}

request_url = f'https://management.azure.com/subscriptions/{subscription}/resourceGroups/{resource_group}/providers/Microsoft.CognitiveServices/accounts/{resource_name}/deployments/{model_deployment_name}'
r = requests.put(request_url, params={'api-version': "2024-10-01"}, headers=deploy_headers, data=json.dumps(deploy_data))

연속 미세조정

만든 모델을 다시 미세조정하며 점진적으로 다듬는 **연속 미세조정(continuous fine-tuning)**도 가능해요. 기본 모델 이름 대신 이전에 만든 미세조정 모델의 ID를 지정하면 돼요. ID는 gpt-4.1-2025-04-14.ft-5fd1918ee65d4cd38a5dcf6835066ed7처럼 생겼어요.

response = client.fine_tuning.jobs.create(
    training_file=training_file_id,
    validation_file=validation_file_id,
    model="gpt-4.1-2025-04-14.ft-5fd1918ee65d4cd38a5dcf6835066ed7"
)
print("Job ID:", response.id)

반복된 버전을 구분하기 쉽도록 suffix 파라미터를 쓰는 것도 좋아요. OpenAI Python API에서는 모델 이름에 최대 18자의 문자열을 덧붙일 수 있어요.

리소스 정리

더 이상 쓰지 않으면 배포, 맞춤화된 모델, 훈련 파일을 정리해야 해요. 미세조정된 모델은 더 이상 사용하지 않아도 스토리지 비용이 발생할 수 있으니, 배포 삭제와 함께 모델 자체도 정리하는 걸 잊지 마세요.

더 알아보기 (Learn more)