מדריך לכוונון עדין

להצגה ב-ai.google.dev הפעלה ב-Google Colab הצגת המקור ב-GitHub

ב-notebook הזה נסביר איך להתחיל להשתמש בשירות הכוונון באמצעות ספריית הלקוח של Python ב-Gemini API. כאן נסביר איך לכוונן את מודל הטקסט שמאחורי שירות יצירת הטקסט של Gemini API.

לפני שמתחילים: מגדירים את הפרויקט ואת מפתח ה-API

לפני שליחת קריאה ל-Gemini API, צריך להגדיר את הפרויקט ואת מפתח ה-API.

הגדרה

מגדירים אימות

עם Gemini API אפשר לכוונן את המודלים לפי הנתונים שלך. מכיוון שמדובר בנתונים שלכם ובמודלים המכווננים שלכם, יש צורך באמצעי בקרת גישה מחמירים יותר מכפי שמפתחות API יכולים לספק.

כדי להריץ את המדריך הזה, צריך להגדיר OAuth בפרויקט.

הדרך הקלה ביותר להגדיר את Colab היא להעתיק את התוכן של הקובץ client_secret.json ל'מנהל הסודות' של Colab (מתחת לסמל המפתח בחלונית השמאלית) עם השם של הסוד 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

אפשר לבדוק את המודלים המכווננים הקיימים באמצעות ה-method 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 שיועברו ל-method.

בדוגמה הזו, תכווננו מודל כדי ליצור את המספר הבא ברצף. לדוגמה, אם הקלט הוא 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 כדי לבדוק את המדינה (State):

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

הערכת המודל

תוכלו להשתמש ב-method 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.