Gemini API: Python을 사용한 모델 조정

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

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

설정

인증

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

이 튜토리얼을 실행하려면 먼저 프로젝트의 OAuth를 설정해야 합니다.

Colab에서 가장 쉽게 설정하는 방법은 client_secret.json 파일의 콘텐츠를 Colab의 'Secret Manager'(왼쪽 패널의 열쇠 아이콘 아래)에 보안 비밀 이름(CLIENT_SECRET)으로 복사하는 것입니다.

이 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 메서드에서 데이터 세트를 모델에 전달해야 합니다. 호출 시 입력 및 출력 값을 직접 정의하거나 파일에서 데이터 프레임으로 가져와서 메서드에 전달할 수 있습니다.

이 예에서는 시퀀스의 다음 숫자를 생성하도록 모델을 조정합니다. 예를 들어 입력이 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.