Jump to content

AI 모델 튜닝하기: 학습 데이터 활용부터 성능 향상까지


Recommended Posts

파인 튜닝은 언제 활용하는가?


프롬프트 엔지니어링은 AI 모델의 성능을 향상시키는 효과적인 방법이지만, 그 한계에 도달할 때가 있습니다. 이때 유용한 대안이 바로 튜닝입니다. 튜닝은 프롬프트 엔지니어링만으로는 성능 향상이 어려운 정체 구간에서 추가적인 성능 개선을 가능하게 합니다.

튜닝의 장점 중 하나는 사용자가 보유한 고유 데이터를 활용하여 특정 작업에 특화된 모델을 만들 수 있다는 것입니다. 예를 들어, 고객의 문의를 분류하는 작업에서 100건의 테스트셋으로 프롬프트 최적화를 수행했지만, 정답률이 73%에 머물러 있었습니다. 또한, AI의 출력이 불필요한 문장이나 부가적인 설명을 포함하는 경우가 여전히 존재했습니다. 이러한 상황에서 파인튜닝은 모델의 성능을 향상시키고, 출력의 일관성을 개선하는 데 효과적인 방법입니다.

image.png.59d76cb6416b02ccf2392af0597e16d8.png

 

튜닝 전 오답 예시

   User
   Completion
   실제 정답
이전에 계정 만들었다가 지우고 다시 네이버 밴드 새로 계정 만들려고 하는데, 계정 만들고 지웠다가 다시 가입이 안되나요? 정답은 '네이버밴드 오류해결'입니다.  네이버밴드 계정                                     


이러한 상황에서, 고객 문의 분류 작업을 예로 들어 튜닝을 통한 성능 향상 방법을 살펴보겠습니다. 우리의 목표는 카테고리 분류의 정확도를 높이고, AI가 '카테고리명'만을 출력하도록 만드는 것입니다. 이를 위해 다음과 같은 단계로 튜닝을 진행해 보겠습니다.

 

Step 1. 데이터셋 준비


튜닝을 효과적으로 수행하기 위해서는 충분한 양의 고품질 데이터가 필요합니다. 하이퍼클로바X의 경우, 일반적으로 400개 이상의 데이터셋이 권장됩니다. 이는 작업의 성격과 도메인(예: 의료, 법률, 경제, 마케팅 등)에 따라 다소 차이가 있을 수 있습니다.

image.png.7396dba07bb1e83e67216124c88e5323.png

HCX-003 모델 인퍼런스 시 결과가 잘 나오지 않던 항목을
400개 이상의 데이터셋으로 튜닝했을 때 오류 발생 확률이 크게 감소하는 것을 확인했습니다. (
작업에 따라 달라질 수 있습니다.)

1. 학습시킬 데이터 수집하기

튜닝 학습을 시작하기 전, 다양한 고객 문의와 그에 맞는 카테고리 분류 데이터를 모아야 합니다. 이때 데이터 전처리가 중요한데, 이는 오타 수정, 표기 교정, 데이터 정제 및 구조화 등을 포함하는 작업입니다. 효과적인 학습 시스템 구축을 위해 필수적인 단계로, 전처리가 필요한 데이터 예시를 들면 다음과 같습니다.

데이터 전처리 과정에서는 잘못된 카테고리로 라벨링된 데이터를 올바른 카테고리로 수정하고, 의도와 의미를 판별하기 어려운 데이터는 제거하는 것이 좋습니다. 모델의 성능 향상을 위해 특수 문자와 이모티콘 제거, 축약어 및 인터넷 용어의 표준어 처리 등의 추가적인 전처리 작업도 고려할 수 있습니다.

   전처리 유형
   text
   잘못된 completion                              
   올바른 completion
잘못된 라벨링 네이버 드라이브 사용 금액 알려주세요. 네이버플러스멤버십 오류 해결 MYBOX 가격                                                                    

 

   전처리 유형     
   text                                                                           
판별불가 ㅇㅋㄷㅋ111                                                                                     
판별불가 !!bjaowjd@@

위와 같이 의도와 의미를 판별하기 어려운 데이터는 제거해주어야합니다. 그 외에도 모델의 성능을 높이기 위해, 특수 문자 및 이모티콘 제거, 축약어 및 인터넷 용어 표준어 처리 등의 작업도 고려할 수 있을 것입니다.

 

이러한 전처리 과정을 거쳐, 네이버 고객센터의 고객 문의 데이터를 기반으로 1000개의 학습 데이터셋을 구성했습니다. 이 데이터셋은 다음과 같은 구조를 가집니다.

  • Text 열: 다양한 고객 문의 예제를 포함합니다. MYBOX, 네이버플러스멤버십, 네이버 밴드 등 15개의 카테고리에 걸쳐 실제 사용자의 문의를 반영하기 위해 비문도 포함될 수 있습니다.
  • Completion 열: 각 고객 문의에 대한 정확한 카테고리 분류를 포함합니다. 분류 태스크의 성공을 위해 이 부분의 정확성은 매우 중요합니다.

 

이렇게 구성된 데이터셋의 예시는 다음과 같습니다.

C_ID
T_ID
Text
Completion
1 0 네이버플러스멤버십 한달에 내는 요금이 얼마고 멤버십은 따로 어플 설치해서 이용하는건가요? 네이버플러스멤버십 가격
2 0 핸드폰 해킹 당해서 드라이브에 사진 백업해두려고 하는데 앱을 깔아야지 백업 가능한가요?
백업하는 법 좀 알려주세요
MYBOX 보안 및 해킹
3 0 네이버 밴드 계정을 찾을려면 어케해야되나요 네이버밴드 계정
4 0

최근에 멤버십이 7월26일에 4900원이 결제 된다는데 이거 무슨 소리이죠?

네이버플러스멤버십 결제

 

학습 데이터는 양보다도 질이 중요합니다. 수집한 데이터의 정답(completion)이 올바르게 부여되어있는지 사전에 꼼꼼히 체크하면 도움이 됩니다.

 


 2. 데이터셋 파일 만들기

  • 파일 형식 : .json 혹은 .csv 파일로 준비해주세요.
  • System_Prompt(선택) : 시스템 프롬프트를 함께 학습시킨다면, 가장 첫 열에 추가해야 합니다. 저희는 최적화한 시스템 프롬프트를 함께 데이터셋에 추가해 학습시켜보았습니다.
  • C_ID : 한 개가 대화 데이터 한 건을 의미하며, 0부터 시작해 하나씩 늘어납니다.
  • T_ID : User & Assistant의 발화 페어 한 건을 의미하며, 0부터 시작해 하나씩 늘어납니다. 저희의 경우, '분류' 태스크이기 때문에 여러 대화 턴 예제는 필요 없습니다. User와 Assistant의 발화 페어가 필요하지 않으므로, T_ID는 모두 0으로 설정해 데이터셋을 만들었습니다.

 

    System_Prompt
 C_ID
 T_ID
    Text
    Completion
<system prompt가 있는 경우 삽입> 0 0 네이버플러스멤버십 한달에 내는 요금이 얼마고 멤버십은 따로 어플 설치해서 이용하는건가요? 네이버플러스멤버십 가격
<system prompt가 있는 경우 삽입> 1 0 핸드폰 해킹 당해서 드라이브에 사진 백업해두려고 하는데 앱을 깔아야지 백업 가능한가요? 백업하는 법 좀 알려주세요 MYBOX 보안 및 해킹

<system prompt가 있는 경우 삽입>

2 0 네이버 밴드 계정을 찾을려면 어케해야되나요 네이버밴드 계정
<system prompt가 있는 경우 삽입> 3 0 최근에 멤버십이 7월26일에 4900원이 결제 된다는데 이거 무슨 소리이죠? 네이버플러스멤버십 결제

 

데이터셋에 대한 자세한 설명은 데이터셋 준비 가이드를 참고해보세요.

 

Step 2. AI 모델 튜닝하기


1. 하이퍼파라미터 설정하기

  • epochs : 전체 데이터셋을 반복 학습하는 횟수를 지정합니다. 예를 들어, 4에서 8로 증가시키면 모델의 학습량이 늘어나 loss가 감소할 수 있습니다. 하지만, 과도한 epochs 설정은 과적합(overfitting)을 유발할 수 있으므로 주의해야 합니다. 고객 문의 분류 작업의 경우, 8 epochs가 적절합니다.
  • model : 튜닝에 사용할 모델을 선택합니다. 분류 작업에는 HCX-DASH-001 모델이 적합합니다.
  • tasktype : 작업 유형을 지정합니다. 분류 작업이므로 classification을 선택합니다.

 

2. 학습생성API 코드 작성 후 실행하기

아래와 같이 python 코드를 작성했습니다. 여러분도 태스크 작업에 따라 적절하게 파라미터를 수정해 코드를 작성해보세요.

학습 생성 코드 보기 

# -*- coding: utf-8 -*-
 
import base64
import hashlib
import hmac
import requests
import time
 
 
class CreateTaskExecutor:
    def __init__(self, host, uri, method, iam_access_key, secret_key, request_id):
        self._host = host
        self._uri = uri
        self._method = method
        self._api_gw_time = str(int(time.time() * 1000))
        self._iam_access_key = iam_access_key
        self._secret_key = secret_key
        self._request_id = request_id
 
    def _make_signature(self) :
        secret_key = bytes(self._secret_key, 'UTF-8')
        message = self._method + " " + self._uri + "\n" + self._api_gw_time + "\n" + self._iam_access_key
        message = bytes(message, 'UTF-8')
        signing_key = base64.b64encode(hmac.new(secret_key, message, digestmod=hashlib.sha256).digest())
        return signing_key
 
    def _send_request(self, create_request):
 
        headers = {
            'X-NCP-APIGW-TIMESTAMP': self._api_gw_time,
            'X-NCP-IAM-ACCESS-KEY': self._iam_access_key,
            'X-NCP-APIGW-SIGNATURE-V2': self._make_signature(),
            'X-NCP-CLOVASTUDIO-REQUEST-ID': self._request_id
        }
 
        result = requests.post(self._host + self._uri, json=create_request, headers=headers).json()
        return result
 
    def execute(self, create_request):
        res = self._send_request(create_request)
        if 'status' in res and res['status']['code'] == '20000':
            return res['result']
        else:
            return res
 
 
if __name__ == '__main__':
    create_task_executor = CreateTaskExecutor(
        host='https://clovastudio.apigw.ntruss.com',
        uri='/tuning/v2/tasks',
        method='POST',
        iam_access_key='<your_iam_access_key>',
        secret_key='<your_secret_key>',
        request_id='<unique_request_id>'
    )
 
    request_data = {
        'name': 'example_tuning_task',
        'model': 'HCX-003',
        'taskType': 'CLASSIFICATION',
        'trainEpochs': 8,
        'learningRate': 1e-5,
        'trainingDatasetBucket': 'bucket_name',
        'trainingDatasetFilePath': 'path/to/dataset/file.json',
        'trainingDatasetAccessKey': '<dataset_access_key>',
        'trainingDatasetSecretKey': '<dataset_secret_key>'
    }
 
    response = create_task_executor.execute(request_data)
    print(request_data)
    print(response)

 

튜닝 API 사용은 학습 생성 가이드를 참고해보세요.

 

3. 튜닝 완료된 모델 확인하기

'클로바 스튜디오 > 내 작업 > 튜닝' 경로에서 아래 이미지와 같이 튜닝 모델의 작업 상태와 예상 소요 시간을 확인할 수 있습니다.

image.png.139f3cfe16cf9fe584291c628d29f341.png

 

'튜닝 완료된 작업 선택> 코드 보기' 경로에서 아래 이미지와 같이 튜닝한 모델의 task id를 확인하세요.

 

image.png.ccc7348b36da17b0e7f4785736e8e9e0.png

 

Step 3. 결과 인퍼런스하기


1. 플레이그라운드에서 인퍼런스하기

image.png.95800dc2012bf852f4af8ecf8feb67b2.png

① 엔진을 튜닝한 모델로 선택
'플레이그라운드 > 불러오기'를 통해 튜닝한 모델을 선택합니다.

② 테스트셋 데이터 중 하나를 입력
테스트셋 데이터 중, 튜닝하기 전에 계속 오류를 냈던 예제 하나를 선택해서 인퍼런스 테스트를 해보았습니다.
'MYBOX'를 고객이 '네이버 드라이브'로 말하는 바람에, 분류에 어려움을 겪었던 케이스입니다.

③ 결과 확인
결과를 확인하니 분류 작업을 잘 수행했고, 결과물 형식도 원하는 형식으로 나오네요!

User       네이버 드라이브에 사진을 모두 삭제하고 휴지통까지 삭제하였습니다다시 복구하고 싶은데 가능한가요?가능하다면 방법을 알고 싶습니다.
Assistant  MYBOX 데이터 관리

 

2. Chat Completion API로 테스트셋 인퍼런스하기

이제 테스트셋 100건에 대해 모두 인퍼런스해보겠습니다.

① 테스트셋 준비하기
튜닝이 잘 되었는지 확인하기 위해선 테스트할 데이터를 수집해야 합니다. 주의할 점은, 이 데이터가 튜닝할 때 사용한 데이터셋과 달라야 한다는 것입니다.
저희는 아래와 같이 평가 데이터 100개를 준비하여 평가를 진행했습니다.

image.png.0d6ac4bbe2826f1b0a032da896097433.png

 

② 인퍼런스 코드 실행하기
아래는 테스트셋 엑셀 파일로 대량의 테스트셋을 인퍼런스 돌리는 코드입니다. API key, 테스트셋 파일 경로, 완료 후 저장할 파일 경로, 튜닝한 모델의 task id를 변경해 코드를 실행해보세요.

Chat Completion 인퍼런스 코드 보기 

import requests
import pandas as pd
import time
 
# API Key 정보 설정
CLOVA_API_KEY = '{CLOVA Studio API Key}'  # CLOVA Studio API Key
APIGW_API_KEY = '{API Gateway API Key}'  # API Gateway API Key
REQUEST_ID = '{Request ID}'  # Unique request identifier
MODEL_PARAMETERS = {
    "topP": 0.8,
    "topK": 0,
    "maxTokens": 256,
    "temperature": 0.5,
    "repeatPenalty": 5.0,
    "includeAiFilters": True,
    "stopBefore": [],
}
INPUT_FILENAME = "{테스트셋 파일 경로}"  # .xlsx 파일
OUTPUT_FILENAME = "{인퍼런스 완료 후 저장할 파일 경로}"  # .xlsx 파일
 
def send_requests(system: str, user: str) :
    url = "https://clovastudio.stream.ntruss.com/v2/tasks/{taskId}/chat-completions"  # taskId는 사용자의 작업 ID로 대체
    headers = {
        "X-NCP-CLOVASTUDIO-API-KEY": CLOVA_API_KEY,
        "X-NCP-APIGW-API-KEY": APIGW_API_KEY,
        "X-NCP-CLOVASTUDIO-REQUEST-ID": REQUEST_ID,
        "Content-Type": "application/json",
        "Accept": "application/json",
    }
    body = MODEL_PARAMETERS.copy()
    body["messages"] = [
        {"role": "system", "content": system},
        {"role": "user", "content": user},
    ]
    response = requests.post(url=url, json=body, headers=headers)
    result = response.json()
    if "result" in result:
        print(result["result"])
        return result["result"]["message"]
    else:
        print("Error:", result)
        return {"role": "error", "content": "Error in API response"}
 
if __name__ == '__main__':
    # Input 데이터 읽기
    df = pd.read_excel(INPUT_FILENAME)
    results_role = []
    results_content = []
 
    for i in df.itertuples():
        # 시스템 메시지와 사용자 메시지를 입력으로 전달
        result = send_requests(i.system, i.user)
        results_role.append(result['role'])
        results_content.append(result['content'])
 
    # 결과를 DataFrame에 추가
    df.insert(2, "role", results_role, True)
    df.insert(3, "content", results_content, True)
 
    # 결과를 엑셀 파일로 저장
    df.to_excel(OUTPUT_FILENAME, index=False)

 

Step 4. 평가하기


1. 정량 평가

평가 데이터의 정답과 모델 답변을 비교하면서, 맞으면 match 열에 1, 틀리면 0으로 점수를 매겨서 정확도를 계산합니다.

image.png.6e0a353baa18b1cc7cfea3c21bf2c44a.png

평가셋 100의 정답과 각 모델 답변이 일치하는 지에 대한 점수를 매긴 후, HCX-DASH-001과 HCX-003모델 각각의 학습 전후를 비교해보겠습니다.

image.png.b756e2d2a412d42c931f0d1676fee8e6.png

튜닝 후, HCX-DASH-001과 HCX-003 모델 모두 성능이 크게 향상되었습니다. HCX-DASH-001의 경우, 초기 성능은 73점이었지만, 파인튜닝 후 97점으로 향상되었습니다. 반면, HCX-003 모델은 초기 성능이 83점이었지만, 파인튜닝 후 95점으로 개선되었습니다. 초기에는 더 큰 모델인 HCX-003이 HCX-DASH-001보다 높은 성능을 보였지만, 양질의 데이터로 학습된 후에는 더 작은 모델인 HCX-DASH-001이 HCX-003과 비슷하거나 더 나은 성능을 보였습니다. 이는 효과적인 파인튜닝이 모델 크기의 차이를 상쇄하고, 때로는 더 작은 모델이 특정 작업에 더 잘 최적화될 수 있음을 보여줍니다.

충분한 데이터를 가지고 있고 과금에 대한 고민이 있으시다면 작은 모델인 HCX-DASH-001로도 충분한 성능 개선을 기대해볼 수 있다는 점을 참고해주세요.

 

2. 정성 평가

이전에 오답으로 나왔던 같은 고객 문의에 대해 어떻게 답변하는지 확인해보았습니다. 튜닝 전과 달리, 원하는 형식대로 '카테고리명'만 출력했고, 카테고리 분류도 잘한 것을 확인할 수 있었습니다.

    user
    튜닝 전 Completion
    튜닝 후 Completion
    정답
이전에 계정 만들었다가 지우고 다시 네이버 밴드 새로 계정 만들려고 하는데, 계정 만들고 지웠다가 다시 가입이 안되나요? 정답은 '네이버밴드 오류해결'입니다.    네이버밴드 계정   네이버밴드 계정

 

튜닝은 AI 모델을 사용자와 과제에 맞게 최적화 시킬 수 있는 방법입니다. 이는 정체된 성능을 한 단계 끌어올리고, 원하는 형식으로 결과를 일관되게 출력하는 데 매우 효과적입니다. 앞서 설명드린 단계와 사례를 참고하여, 여러분의 프로젝트에서도 튜닝을 적극 활용해 보세요. 적절한 데이터셋 구성과 체계적인 프로세스를 통해 최고의 결과를 도출할 수 있을 것입니다. 더 나은 성능과 높은 정확도를 향한 튜닝 여정, 지금 바로 시작해 보세요! 🚀

 

 

image.png.2526d94dea6ed6733cd4662b1a6a2042.png

 

링크 복사
다른 사이트에 공유하기

  • CLOVA Studio 운영자 changed the title to AI 모델 튜닝하기: 학습 데이터 활용부터 성능 향상까지

게시글 및 댓글을 작성하려면 로그인 해주세요.



로그인
×
×
  • Create New...