미세 조정 튜토리얼

ai.google.dev에서 보기 Google Colab에서 실행 GitHub에서 소스 보기

이 노트북에서는 Gemini API용 Python 클라이언트 라이브러리를 사용하여 조정 서비스를 시작하는 방법을 알아봅니다. Gemini API의 텍스트 생성 서비스의 기반이 되는 텍스트 모델을 조정하는 방법을 알아봅니다

시작하기 전에: 프로젝트 및 API 키 설정

Gemini API를 호출하기 전에 프로젝트를 설정하고 API 키를 구성해야 합니다.

설정

인증 설정

Gemini API를 사용하면 자체 데이터를 기반으로 모델을 조정할 수 있습니다. 사용자의 데이터와 조정된 모델이므로 API 키가 제공할 수 있는 것보다 더 엄격한 액세스 제어가 필요합니다.

이 가이드를 실행하기 전에 먼저 프로젝트의 OAuth를 설정해야 합니다.

Colab에서 설정하는 가장 쉬운 방법은 client_secret.json 파일의 콘텐츠를 보안 비밀 이름이 CLIENT_SECRET인 Colab의 'Secrets Manager' (왼쪽 패널의 키 아이콘 아래)에 복사하는 것입니다.

이 gcloud 명령어는 client_secret.json 파일을 서비스에 인증하는 데 사용할 수 있는 사용자 인증 정보로 변환합니다.

import os
if 'COLAB_RELEASE_TAG' in os.environ:
  from google.colab import userdata
  import pathlib
  pathlib.Path('client_secret.json').write_text(userdata.get('CLIENT_SECRET'))

  # Use `--no-browser` in colab
  !gcloud auth application-default login --no-browser --client-id-file client_secret.json --scopes='https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/generative-language.tuning'
else:
  !gcloud auth application-default login --client-id-file client_secret.json --scopes='https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/generative-language.tuning'

클라이언트 라이브러리 설치하기

pip install -q google-generativeai

라이브러리 가져오기

import google.generativeai as genai

genai.list_tuned_model 메서드로 기존 조정된 모델을 확인할 수 있습니다.

for i, m in zip(range(5), genai.list_tuned_models()):
  print(m.name)
tunedModels/my-model-8527
tunedModels/my-model-7092
tunedModels/my-model-2778
tunedModels/my-model-1298
tunedModels/my-model-3883

미세 조정된 모델 만들기

조정된 모델을 만들려면 genai.create_tuned_model 메서드에서 데이터 세트를 모델에 전달해야 합니다. 이렇게 하려면 호출에서 입력 값과 출력 값을 직접 정의하거나 파일에서 메서드로 전달할 DataFrame으로 가져오면 됩니다.

이 예시에서는 시퀀스의 다음 숫자를 생성하도록 모델을 조정합니다. 예를 들어 입력이 1이면 모델은 2를 출력해야 합니다. 입력이 one hundred이면 출력은 one hundred one입니다.

base_model = [
    m for m in genai.list_models()
    if "createTunedModel" in m.supported_generation_methods][0]
base_model
Model(name='models/gemini-1.0-pro-001',
      base_model_id='',
      version='001',
      display_name='Gemini 1.0 Pro',
      description=('The best model for scaling across a wide range of tasks. This is a stable '
                   'model that supports tuning.'),
      input_token_limit=30720,
      output_token_limit=2048,
      supported_generation_methods=['generateContent', 'countTokens', 'createTunedModel'],
      temperature=0.9,
      top_p=1.0,
      top_k=1)
import random

name = f'generate-num-{random.randint(0,10000)}'
operation = genai.create_tuned_model(
    # You can use a tuned model here too. Set `source_model="tunedModels/..."`
    source_model=base_model.name,
    training_data=[
        {
             'text_input': '1',
             'output': '2',
        },{
             'text_input': '3',
             'output': '4',
        },{
             'text_input': '-3',
             'output': '-2',
        },{
             'text_input': 'twenty two',
             'output': 'twenty three',
        },{
             'text_input': 'two hundred',
             'output': 'two hundred one',
        },{
             'text_input': 'ninety nine',
             'output': 'one hundred',
        },{
             'text_input': '8',
             'output': '9',
        },{
             'text_input': '-98',
             'output': '-97',
        },{
             'text_input': '1,000',
             'output': '1,001',
        },{
             'text_input': '10,100,000',
             'output': '10,100,001',
        },{
             'text_input': 'thirteen',
             'output': 'fourteen',
        },{
             'text_input': 'eighty',
             'output': 'eighty one',
        },{
             'text_input': 'one',
             'output': 'two',
        },{
             'text_input': 'three',
             'output': 'four',
        },{
             'text_input': 'seven',
             'output': 'eight',
        }
    ],
    id = name,
    epoch_count = 100,
    batch_size=4,
    learning_rate=0.001,
)

조정된 모델은 조정된 모델 목록에 즉시 추가되지만 모델이 조정되는 동안 상태는 '생성 중'으로 설정됩니다.

model = genai.get_tuned_model(f'tunedModels/{name}')

model
TunedModel(name='tunedModels/generate-num-2946',
           source_model='models/gemini-1.0-pro-001',
           base_model='models/gemini-1.0-pro-001',
           display_name='',
           description='',
           temperature=0.9,
           top_p=1.0,
           top_k=1,
           state=<State.CREATING: 1>,
           create_time=datetime.datetime(2024, 2, 21, 20, 4, 16, 448050, tzinfo=datetime.timezone.utc),
           update_time=datetime.datetime(2024, 2, 21, 20, 4, 16, 448050, tzinfo=datetime.timezone.utc),
           tuning_task=TuningTask(start_time=datetime.datetime(2024, 2, 21, 20, 4, 16, 890698, tzinfo=datetime.timezone.utc),
                                  complete_time=None,
                                  snapshots=[],
                                  hyperparameters=Hyperparameters(epoch_count=100,
                                                                  batch_size=4,
                                                                  learning_rate=0.001)))
model.state
<State.CREATING: 1>

조정 진행 상황 확인

metadata를 사용하여 상태를 확인합니다.

operation.metadata
total_steps: 375
tuned_model: "tunedModels/generate-num-2946"

operation.result() 또는 operation.wait_bar()를 사용하여 학습이 완료될 때까지 기다립니다.

import time

for status in operation.wait_bar():
  time.sleep(30)
0%|          | 0/375 [00:00<?, ?it/s]

cancel() 메서드를 사용하여 언제든지 조정 작업을 취소할 수 있습니다. 아래 줄의 주석 처리를 삭제하고 코드 셀을 실행하여 작업이 완료되기 전에 취소합니다.

# operation.cancel()

조정이 완료되면 조정 결과에서 손실 곡선을 볼 수 있습니다. 손실 곡선은 모델의 예측이 이상적인 출력에서 얼마나 벗어나는지 보여줍니다.

import pandas as pd
import seaborn as sns

model = operation.result()

snapshots = pd.DataFrame(model.tuning_task.snapshots)

sns.lineplot(data=snapshots, x = 'epoch', y='mean_loss')
<Axes: xlabel='epoch', ylabel='mean_loss'>

png

모델 평가

genai.generate_text 메서드를 사용하고 모델 이름을 지정하여 모델 성능을 테스트할 수 있습니다.

model = genai.GenerativeModel(model_name=f'tunedModels/{name}')
result = model.generate_content('55')
result.text
'56'
result = model.generate_content('123455')
result.text
'123456'
result = model.generate_content('four')
result.text
'five'
result = model.generate_content('quatre') # French 4
result.text                               # French 5 is "cinq"
'cinq'
result = model.generate_content('III')    # Roman numeral 3
result.text                               # Roman numeral 4 is IV
'IV'
result = model.generate_content('七')  # Japanese 7
result.text                            # Japanese 8 is 八!
'八'

제한된 예에도 불구하고 작업을 선택한 것 같지만 '다음'은 비교적 간단한 개념입니다. 성능 향상에 관한 자세한 내용은 조정 가이드를 참고하세요.

설명 업데이트

genai.update_tuned_model 메서드를 사용하여 언제든지 조정된 모델의 설명을 업데이트할 수 있습니다.

genai.update_tuned_model(f'tunedModels/{name}', {"description":"This is my model."});
model = genai.get_tuned_model(f'tunedModels/{name}')

model.description
'This is my model.'

모델 삭제

더 이상 필요하지 않은 모델을 삭제하여 조정된 모델 목록을 정리할 수 있습니다. genai.delete_tuned_model 메서드를 사용하여 모델을 삭제합니다. 조정 작업을 취소한 경우 성능을 예측하지 못할 수 있으므로 작업을 삭제해야 할 수 있습니다.

genai.delete_tuned_model(f'tunedModels/{name}')

모델이 더 이상 존재하지 않습니다.

try:
  m = genai.get_tuned_model(f'tunedModels/{name}')
  print(m)
except Exception as e:
  print(f"{type(e)}: {e}")
<class 'google.api_core.exceptions.NotFound'>: 404 Tuned model tunedModels/generate-num-2946 does not exist.