인공지능/직접 해보기

GPT turbo 3 모델로 파인튜닝 해본썰

원담 2025. 6. 25. 18:02
728x90

오늘은 ChatGPT를 나만의 스타일로 파인튜닝(Fine-tuning)하는 경험을 공유하려고 한다. 특정 목적에 맞춰 ChatGPT를 훈련시키면 더욱 똑똑하고 유용한 AI를 만들 수 있는데 이번엔 GPT turbo 3 모델을 파운데이션 모델로 설정하고 Hugging Face에 적절한 데이터를 찾아 validation 용이랑 tranining 용으로 적절히 나누어 파인 튜닝 해보았다.

특정 목적에 맞춰 ChatGPT를 훈련시키면 더욱 똑똑하고 유용한 AI를 만들 수 있는데, 이번에 사용한 데이터 셋은 samanth-data 로 철학, 심리 쪽에 맞춰 트레이닝이 되고 자기 스스로를 과학자라고 생각하는 친구의 데이터를 활용해서 더욱더 친근하고 매력적인 비서라는 캐릭터를 부여하여 더욱 자연스러운 대화가 가능하도록 훈련시켰다. 파인 튜닝은 다양한 방법론들이 있는데 여기서 사용한거는 Supervised Fine-Tuning (SFT) 방식 이다.

데이터 준비: 파인튜닝의 핵심

파인튜닝의 성패는 양질의 데이터셋에 달려있다. OpenAI 모델을 파인튜닝하기 위해서는 모델이 학습할 대화 형식의 데이터가 필요하다. 나는 Hugging Face의 cognitivecomputations/samantha-data 데이터셋 중 howto_conversations.jsonl 파일을 사용하였다.

https://huggingface.co/datasets/cognitivecomputations/samantha-data

 

cognitivecomputations/samantha-data · Datasets at Hugging Face

The viewer is disabled because this dataset repo requires arbitrary Python code execution. Please consider removing the loading script and relying on automated data support (you can use convert_to_parquet from the datasets library). If this is not possible

huggingface.co

불러온 데이터셋을 OpenAI API가 요구하는 형식, 즉 {"role": "system", "content": "..."}와 같은 메시지 리스트 형식으로 변환하는 과정이 필요 하기 때문에 데이터 셋의 대화의 화자(Theodore, Samantha)를 'user'와 'assistant' 역할로 매핑하고, 시스템 메시지를 추가하여 AI의 페르소나를 정의했어야 했다. 시스템 메시지로 "You are Samantha, a helpful and charming assistant who can help with a variety of tasks. You are friendly and does often flirt"를 설정하여 'Samantha'가 친근하고 매력적인 말투를 사용하도록 유도하였다.

데이터셋 유효성 검사 및 분석

데이터 변환이 완료되면, 이 데이터가 파인튜딩에 적합한지 꼼꼼히 확인해야 한다

  • 형식 오류 검사: 데이터가 OpenAI의 요구사항(예: 모든 메시지에 '역할(role)'과 '내용(content)'이 있는지, 역할 이름이 올바른지 등)을 정확히 따르는지 검사를 한다. 오류가 발견되면 학습에 문제가 생길 수 있기 때문에 필수적인 과정이다.
  • 토큰 수 분석: AI 모델은 텍스트를 '토큰'이라는 단위로 처리하기 때문에 각 대화가 몇 개의 토큰으로 구성되어 있는지 분석하여, 모델이 한 번에 처리할 수 있는 최대 길이 제한(예: 4096 토큰)을 초과하는 대화는 없는지 확인한다. 너무 긴 대화는 학습 시 잘려나가 모델이 전체 맥락을 이해하지 못할 수 있다. 그리고 이 과정은 파인튜닝에 드는 예상 비용을 파악하는 데도 중요한 기준이 되기도 한다.

모든 검사와 분석을 마친 후, 준비된 데이터를 파인튜닝 모델 훈련에 사용할 훈련(Training) 데이터셋과 훈련 과정을 평가할 검증(Validation) 데이터셋으로 나누어 파일로 저장한다.

platform 에 올라간 dataSet

OpenAI에 데이터 업로드 및 파인 튜닝 시작

위에서 저장한 훈련 및 검증 데이터셋 파일을 OpenAI API를 통해 업로드한다. 파일 업로드가 완료되면, 'gpt-3.5-turbo'와 같은 기본 모델을 기반으로 파인튜닝 작업을 생성하도록 명령한다. 이때, 업로드된 훈련/검증 파일의 ID를 지정해 주고, 파인튜닝이 완료된 모델에 붙일 이름을 설정해 주면 된다.

# openAI client 생성
import os
from openai import OpenAI

client = OpenAI(
    api_key="",
)

# training dataset, validation dataset 경로지정
training_dataset_file_name = '/content/samantha_task_train.jsonl'
validation_dataset_file_name = '/content/samantha_task_validation.jsonl'

# 파인튜닝 시작
response = client.fine_tuning.jobs.create(
    model = "gpt-3.5-turbo",
    training_file = training_response.id,
    validation_file = validation_response.id,
    suffix="samantha-test"
)

이 명령이 실행되면 OpenAI 서버에서 파인튜닝 작업이 시작되며, 모델이 우리의 데이터를 바탕으로 새로운 지식과 스타일을 학습하게 된다. Response 를 중간중간 찍어보면 상태 값을 확인해 볼 수 있는데, model, status, hyperparameters 설정, 학습 메서드 등 재밌는 게 많이 보인다.

FineTuningJob (
  id: 'ftjob-Ltef9BOo5nzNGRUxYYyNEm7G',
  created_at: 1750835521,
  status: 'validating_files',
  finished_at: None,
  error: {
    code: None,
    message: None,
    param: None
  },
  fine_tuned_model: None,
  
  model: 'gpt-3.5-turbo-0125',
  training_file: 'file-WPMebk72eJWeQwbcD32a1q',
  validation_file: 'file-CBm6EyC1UVg2ZsSbpijL4F',
  
  hyperparameters: {
    batch_size: 'auto',
    learning_rate_multiplier: 'auto',
    n_epochs: 'auto'
  },
  
  method: {
    type: 'supervised',
    supervised: {
      hyperparameters: {
        batch_size: 'auto',
        learning_rate_multiplier: 'auto',
        n_epochs: 'auto'
      }
    },
    dpo: None,
    reinforcement: None
  },
  
  seed: 91303938,
  estimated_finish: None,
  result_files: [],
  integrations: [],
  metadata: None,
  user_provided_suffix: 'samantha-test',
  usage_metrics: None,
  shared_with_openai: False,
  organization_id: 'org-D6qfECNKxz9WcDj0sxYroLQB',
  eval_id: None
)

platform에서도 파인튜닝이 진행 중인 상태에 대해서 확인 가능하다.

파인튜닝 잡 생성

파인튜닝 모델 테스트

파인튜닝 작업이 성공적으로 완료되면, OpenAI는 우리만을 위한 새로운 AI 모델 ID를 제공한다. 이 ID를 사용하여 훈련시킨 모델에 직접 질문을 던지고, 그 응답을 확인하며 모델의 성능을 평가할 수 있다. 

fine tuing 지표 이해하기

제공된 스크린샷은 ft:gpt-3.5-turbo-0125:wondam:samantha-test:BmEiwCMH라는 파인튜닝된 모델의 상세 정보이다. 이는 특정 데이터셋으로 gpt-3.5-turbo-0125 모델을 추가 학습시켜 얻은 결과이다.

  • 모델이름에 ft 는 파인 튜닝이 된 모델임을 나타낸다
  • training mdthod 에는 supervised라고 되어있는데 이는 모델이 지도 학습(Supervised Learning) 방식으로 훈련되었음을 의미한다. 즉, 입력(사용자 메시지)과 원하는 출력(어시스턴트 메시지) 쌍이 명확하게 주어진 데이터를 통해 학습이 이루어졌다는 뜻이다.
  • trained tokens: 105,318 이라고 나와있는데 이는 이 파인튜닝 작업에서 모델이 학습한 총 토큰 수를 말한다. 이는 훈련 데이터셋의 총 토큰 수와 에폭(Epochs) 수를 곱한 값으로, 청구되는 비용의 주요 기준이 된다.
  • Epochs: 3 은 모델이 전체 훈련 데이터셋을 반복해서 학습한 횟수이다. 여기서는 데이터셋 전체를 3번 반복해서 학습했다.
    • 이게 너무 크면 과적합이 될 수 있는 위험성이 있다
  • Batch size: 1 은 한 번의 가중치 업데이트(훈련 스텝)에 사용되는 훈련 예시의 수 이다. 배치 크기가 1이라는 것은 각 예시를 개별적으로 학습하고 가중치를 업데이트했다는 의미인데 쉽게 말해서 모델링 데이터 셋에 있는 예시(대화 한 쌍)를 하나씩 가져와 학습하고, 그 하나를 학습할 때마다 모델의 가중치를 바로바로 업데이트하여 새로운 데이터에 빨리 반영하도록 한다. 단지 학습 과정이 불안정해질 수도 있고, 학습 속도가 느려질 수도 있다.
    • 데이터셋의 크기와 컴퓨팅 자원을 고려하여야 한다.
  • LR multiplier: 2는 학습률(Learning Rate) 승수를 나타낸다. 기본 학습률에 이 값을 곱하여 실제 학습률을 결정한다. 학습률은 모델이 훈련 과정에서 가중치를 얼마나 크게 업데이트할지를 결정하는 중요한 하이퍼파라미터이다. 쉽게 말하면 학습률을 LR을 크게 하면(보폭이 크면) 모델이 너무 급하게 지식을 수정해서 제대로 학습하지 못하고 발산핟거나 불안정해질 수 있지만 학습률이 너무 작으면 너무 오랜 시간이 걸리고 심지어 중간에 갇혀서 정답인 줄 알고 착각하여 더 이상 나아가지 못할 수도 있다. 모델의 학습 속도가 매우 느려지고 최적의 성능에 도달하지 못한다는 뜻이다.
    • 경험과 실험: 사실 가장 좋은 학습률은 여러 번 실험(Trial & Error)을 통해 찾는 것이 일반적. 처음에는 일반적인 값(예: 0.001 또는 0.0001)으로 시작해서, 모델의 학습 곡선을 보면서 조절해 나간다.
    • 점진적 감소 (Learning Rate Scheduling): 학습 초반에는 조금 크게 설정하여 빠르게 정답 근처로 이동하고, 후반에는 작게 설정하여 정답을 정밀하게 찾는 전략을 사용하기도 한다
    • 옵티마이저 (Optimizer) 종류: Adam, SGD 등 어떤 '최적화 알고리즘'을 사용하느냐에 따라서도 권장되는 학습률 범위가 다르다.
  • Seed: 91303938 는 난수 생성 시 사용된 시드(Seed) 값이다. 이 시드 값을 고정하면 동일한 조건에서 파인튜닝 작업을 다시 실행했을 때, 재현 가능한 결과를 얻는 데 도움이 되는데 시드를 고정해 주면 파인 튜닝 실험을 '재현 간능하게' 만들 수 있는데, 예를 들어 어떤 파인튜닝이 좋은 성능을 냈을 때 다른 사람이 똑같은 코드로 똑같은 결과가 나오도록 하려면 시드를 고정해야 한다. 이 값은 연구나 개발 과정에서 결과를 비교하고 분석할 때 중요하다.

파인 튜닝 과정에는 작업의 훈련 지표와 그래프를 보여주었다.

Training loss vs Valid loss

 

  • Train loss: 0.846 은 모델이 훈련 데이터셋을 학습하면서 계산된 손실(Loss) 값이다. 손실은 모델의 예측이 정답과 얼마나 차이가 나는지를 나타내는 지표로, 값이 낮을수록 모델이 훈련 데이터를 잘 학습하고 있다는 의미이다. 예를들면 학생이 '교과서에 있는 문제'를 풀었을 때의 오답률이라고 비유 할 수 있다.
  • Valid loss: 1.031 은 모델이 검증 데이터셋을 예측하면서 계산된 손실 값이다. 검증 데이터셋은 훈련 과정에서 모델이 한 번도 보지 못한 데이터이므로, 이 손실 값은 모델이 새로운 데이터(일반화 능력)에 대해 얼마나 잘 작동하는지를 보여준다. 예를들면 이번엔 학생이 '모의고사'를 풀었을 때의 오답률로 표현할 수 있고, 일반적으로 훈련 손실보다는 약간 높을 수 있다.

파인튜닝된 모델과 기본 모델의 응답비교

응답비교는 상당히 흥미로웠다. 훈련 데이터셋과 유사한 유형의 질문에 대해서는 매우 특화되고 훌륭한 답변을 내놓았는데 훈련 데이터셋의 범위를 벗어나거나 일반적인 지식을 요구하는 질문에 대해서는 오히려 기본 모델보다 성능이 떨어졌기 때문이다.

 

 

왼쪽 기본 모델, 오른쪽 파인튜닝

 

파인 튜닝떄 사용했던 Samantha 데이터셋(howto_conversations.jsonl)은 "howto" 즉, 어떤 일을 하는 방법(How-to)에 대한 대화 위주로 구성되어있어서 "회사 때려치우는 법"이라는 질문은 그 자체로 '방법'을 묻는 것이긴 하지만, 크게 달라짐은 느끼지 못했다.

두개의 응답, 크게 차이점을 못느낌

흥미 로웠던 것은 "책 선반을 만드는법" (훈련 데이터 셋에 있었던 질문) 은 기본 모델보다 더 자세히 설명해준다. 기본 모델은 보통의 방법에 대해서 오른쪽 파인튜닝된 모델은 도구부터 시작해서 바닥재 용품까지 다양하다. 

챗 선반을 만드는 방법에 대해서 알려줘!

오늘은 이렇게 파인튜닝을 직접해보면서 다양한 지표들도 확인해보았다. 이렇듯 프롬프트 엔지니어링만 사용하는 것보다 파인튜닝을 활용하면 더 적은 예시와 컨텍스트 데이터를 가진 더 짧은 프롬프트를 사용할 수 있어 토큰 비용을 절감할 수 있겠구나 싶었다. 또한 소유하고 있거나 민감한 데이터를 요청마다 예시로 포함하는 경우도 있는데 이럴 경우 훈련에 사용할 수 있는 안정성도 있다고 생각한다.

와 재밌다!

 

728x90