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

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

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

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

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

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

ב-Colab הכי קל לבצע את ההגדרה הוא להעתיק את התוכן של הקובץ client_secret.json ל'מנהל הסודות' של Colab (מתחת לסמל המפתח בחלונית השמאלית) עם שם הסוד CLIENT_SECRET.

הפקודה ב-gcloud הופכת את הקובץ client_secret.json לפרטי כניסה, שבהם אפשר להשתמש כדי לבצע אימות בשירות.

try:
  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'
except ImportError:
  !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'
You are authorizing client libraries without access to a web browser. Please run the following command on a machine with a web browser and copy its output back here. Make sure the installed gcloud version is 372.0.0 or newer.

gcloud auth application-default login --remote-bootstrap="https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=87071151422-n1a3cb6c7fvkfg4gmhdtmn5ulol2l4be.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgenerative-language.tuning&state=QIyNibWSaTIsozjmvZEkVBo6EcoW0G&access_type=offline&code_challenge=76c1ZiGvKN8cvlYfj3BmbCwE4e7tvrlwaX3REUX25gY&code_challenge_method=S256&token_usage=remote"

Enter the output of the above command: https://localhost:8085/?state=QIyNibWSaTIsozjmvZEkVBo6EcoW0G&code=4/0AeaYSHBKrY911S466QjKQIFODoOPXlO1mWyTYYdrbELIDV6Hw2DKRAyro62BugroSvIWsA&scope=https://www.googleapis.com/auth/cloud-platform%20https://www.googleapis.com/auth/generative-language.tuning

Credentials saved to file: [/content/.config/application_default_credentials.json]

These credentials will be used by any library that requests Application Default Credentials (ADC).

הגדרת משתנים

CURL

מגדירים משתנים לערכים חוזרים שישמשו בשאר הקריאות ל-API ל-REST. הקוד משתמש בספריית os של Python כדי להגדיר משתני סביבה, שאפשר לגשת אליהם בכל תאי הקוד.

המצב הזה ספציפי לסביבת ה-notebook של Colab. הקוד בתא הקוד הבא מקביל להרצת הפקודות הבאות בטרמינל bash.

export access_token=$(gcloud auth application-default print-access-token)
export project_id=my-project-id
export base_url=https://generativelanguage.googleapis.com
import os

access_token = !gcloud auth application-default print-access-token
access_token = '\n'.join(access_token)

os.environ['access_token'] = access_token
os.environ['project_id'] = "[Enter your project-id here]"
os.environ['base_url'] = "https://generativelanguage.googleapis.com"

Python

access_token = !gcloud auth application-default print-access-token
access_token = '\n'.join(access_token)

project = '[Enter your project-id here]'
base_url = "https://generativelanguage.googleapis.com"

אפשר לייבא את הספרייה requests.

import requests
import json

הצגת רשימה של מודלים מכווננים

כדי לאמת את הגדרת האימות, מציגים את המודלים המכווננים הזמינים.

CURL


curl -X GET ${base_url}/v1beta/tunedModels \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${access_token}" \
    -H "x-goog-user-project: ${project_id}"

Python

headers={
  'Authorization': 'Bearer ' + access_token,
  'Content-Type': 'application/json',
  'x-goog-user-project': project
}

result = requests.get(
  url=f'{base_url}/v1beta/tunedModels',
  headers = headers,
)
result.json()

יצירת מודל מכוונן

כדי ליצור מודל שעבר כוונון, צריך להעביר את מערך הנתונים למודל בשדה training_data.

בדוגמה הזו, תכווננו מודל כדי ליצור את המספר הבא ברצף. לדוגמה, אם הקלט הוא 1, הפלט של המודל צריך להיות 2. אם הקלט הוא one hundred, הפלט צריך להיות one hundred one.

CURL


curl -X POST $base_url/v1beta/tunedModels \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer ${access_token}" \
    -H "x-goog-user-project: ${project_id}" \
    -d '
      {
        "display_name": "number generator model",
        "base_model": "models/gemini-1.0-pro-001",
        "tuning_task": {
          "hyperparameters": {
            "batch_size": 2,
            "learning_rate": 0.001,
            "epoch_count":5,
          },
          "training_data": {
            "examples": {
              "examples": [
                {
                    "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",
                }
              ]
            }
          }
        }
      }' | tee tunemodel.json
{
"name": "tunedModels/number-generator-model-dzlmi0gswwqb/operations/bvl8dymw0fhw",
"metadata": {
  "@type": "type.googleapis.com/google.ai.generativelanguage.v1beta.CreateTunedModelMetadata",
  "totalSteps": 38,
  "tunedModel": "tunedModels/number-generator-model-dzlmi0gswwqb"
}
}
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                              Dload  Upload   Total   Spent    Left  Speed
100  2280    0   296  100  1984    611   4098 --:--:-- --:--:-- --:--:--  4720

Python

operation = requests.post(
    url = f'{base_url}/v1beta/tunedModels',
    headers=headers,
    json= {
        "display_name": "number generator",
        "base_model": "models/gemini-1.0-pro-001",
        "tuning_task": {
          "hyperparameters": {
            "batch_size": 4,
            "learning_rate": 0.001,
            "epoch_count":5,
          },
          "training_data": {
            "examples": {
              "examples": [
                {
                    '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',
                }
              ]
            }
          }
        }
      }
)
operation
<Response [200]>
operation.json()
{'name': 'tunedModels/number-generator-wl1qr34x2py/operations/41vni3zk0a47',
'metadata': {'@type': 'type.googleapis.com/google.ai.generativelanguage.v1beta.CreateTunedModelMetadata',
  'totalSteps': 19,
  'tunedModel': 'tunedModels/number-generator-wl1qr34x2py'} }

מגדירים משתנה עם השם של המודל המכוונן שישמש בשאר הקריאות.

name=operation.json()["metadata"]["tunedModel"]
name
'tunedModels/number-generator-wl1qr34x2py'

קבלת מצב כוונון של המודל

מצב המודל מוגדר ל-CREATING במהלך האימון, והוא ישתנה ל-ACTIVE בסיום האימון.

CURL

בהמשך מופיע קטע של קוד Python כדי לנתח את שם המודל שנוצר מה-JSON בתשובה. אם מריצים את הפקודה בטרמינל, אפשר לנסות להשתמש במנתח JSON של bash כדי לנתח את התשובה.

import json

first_page = json.load(open('tunemodel.json'))
os.environ['modelname'] = first_page['metadata']['tunedModel']

print(os.environ['modelname'])
tunedModels/number-generator-model-dzlmi0gswwqb

מבצעים עוד בקשת GET עם שם המודל כדי לקבל את המטא-נתונים של המודל, שכוללים את שדה המצב.


curl -X GET ${base_url}/v1beta/${modelname} \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer ${access_token}" \
    -H "x-goog-user-project: ${project_id}" | grep state
"state": "ACTIVE",
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                              Dload  Upload   Total   Spent    Left  Speed
100  5921    0  5921    0     0  13164      0 --:--:-- --:--:-- --:--:-- 13157

Python

tuned_model = requests.get(
    url = f'{base_url}/v1beta/{name}',
    headers=headers,
)
tuned_model.json()

הקוד שבהמשך בודק את שדה המצב כל 5 שניות עד שהוא לא נמצא יותר במצב CREATING.

import time
import pprint

op_json = operation.json()
response = op_json.get('response')
error = op_json.get('error')

while response is None and error is None:
    time.sleep(5)

    operation = requests.get(
        url = f'{base_url}/v1/{op_json["name"]}',
        headers=headers,
    )

    op_json = operation.json()
    response = op_json.get('response')
    error = op_json.get('error')

    percent = op_json['metadata'].get('completedPercent')
    if percent is not None:
      print(f"{percent:.2f}% - {op_json['metadata']['snapshots'][-1]}")
      print()

if error is not None:
    raise Exception(error)
100.00% - {'step': 19, 'epoch': 5, 'meanLoss': 1.402067, 'computeTime': '2024-03-14T15:11:23.766989274Z'}

הרצת ההסקה

כשפעולת הכוונון תסתיים, תוכלו להשתמש בה כדי ליצור טקסט באמצעות שירות הטקסט.

CURL

מנסים להזין ספרה רומית, למשל, 63 (LXIII):


curl -X POST $base_url/v1beta/$modelname:generateContent \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer ${access_token}" \
    -H "x-goog-user-project: ${project_id}" \
    -d '{
        "contents": [{
        "parts": [{
          "text": "LXIII"
          }]
        }]
        }' 2> /dev/null
{
"candidates": [
  {
    "content": {
      "parts": [
        {
          "text": "LXIV"
        }
      ],
      "role": "model"
    },
    "finishReason": "STOP",
    "index": 0,
    "safetyRatings": [
      {
        "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_HATE_SPEECH",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_HARASSMENT",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
        "probability": "NEGLIGIBLE"
      }
    ]
  }
],
"promptFeedback": {
  "safetyRatings": [
    {
      "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
      "probability": "NEGLIGIBLE"
    },
    {
      "category": "HARM_CATEGORY_HATE_SPEECH",
      "probability": "NEGLIGIBLE"
    },
    {
      "category": "HARM_CATEGORY_HARASSMENT",
      "probability": "NEGLIGIBLE"
    },
    {
      "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
      "probability": "NEGLIGIBLE"
    }
  ]
}
}

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

תוכלו למצוא מידע נוסף על שיפור הביצועים במדריך הכוונון.

Python

מנסים להזין ספרה יפנית, למשל 6 (gcloud):

import time

m = requests.post(
    url = f'{base_url}/v1beta/{name}:generateContent',
    headers=headers,
    json= {
        "contents": [{
            "parts": [{
                "text": "六"
            }]
          }]
    })
import pprint
pprint.pprint(m.json())
{'candidates': [{'content': {'parts': [{'text': '七'}], 'role': 'model'},
                'finishReason': 'STOP',
                'index': 0,
                'safetyRatings': [{'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
                                    'probability': 'NEGLIGIBLE'},
                                  {'category': 'HARM_CATEGORY_HATE_SPEECH',
                                    'probability': 'NEGLIGIBLE'},
                                  {'category': 'HARM_CATEGORY_HARASSMENT',
                                    'probability': 'LOW'},
                                  {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',
                                    'probability': 'NEGLIGIBLE'}]}],
'promptFeedback': {'safetyRatings': [{'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
                                      'probability': 'NEGLIGIBLE'},
                                      {'category': 'HARM_CATEGORY_HATE_SPEECH',
                                      'probability': 'NEGLIGIBLE'},
                                      {'category': 'HARM_CATEGORY_HARASSMENT',
                                      'probability': 'NEGLIGIBLE'},
                                      {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',
                                      'probability': 'NEGLIGIBLE'}]} }

יכול להיות שהפלט מהמודל שלך נכון או שגוי. אם המודל המכוונן לא עומד בסטנדרטים הנדרשים, אפשר לנסות להוסיף עוד דוגמאות באיכות גבוהה, לתקן את ההיפר-פרמטרים או להוסיף קידומת לדוגמאות.

סיכום

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

השלבים הבאים

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