API REST: réglage de modèle

Voir sur ai.google.dev Exécuter dans Google Colab Afficher la source sur GitHub

Dans ce notebook, vous allez apprendre à utiliser le service de réglage de l'API Gemini à l'aide de commandes curl ou de l'API de requête Python pour appeler l'API Gemini. Ici, vous allez apprendre à régler le modèle de texte du service de génération de texte de l'API Gemini.

Préparation

Authentifier

L'API Gemini vous permet de régler des modèles à partir de vos propres données. Étant donné qu'il s'agit de vos données et de vos modèles ajustés, des contrôles d'accès plus stricts sont nécessaires que les clés API ne peuvent fournir.

Avant de pouvoir exécuter ce tutoriel, vous devez configurer OAuth pour votre projet.

Dans Colab, la méthode la plus simple pour configurer consiste à copier le contenu de votre fichier client_secret.json dans le "Gestionnaire de secrets " de Colab (sous l'icône en forme de clé dans le panneau de gauche) avec le nom du secret CLIENT_SECRET.

Cette commande gcloud transforme le fichier client_secret.json en identifiants permettant de s'authentifier auprès du service.

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).

Appeler l'API REST avec CURL

Cette section présente des exemples d'instructions curl pour appeler l'API REST. Vous allez apprendre à créer un job de réglage, à vérifier son état et à effectuer un appel d'inférence une fois l'opération terminée.

Définir des variables

Définissez des variables de valeurs récurrentes à utiliser pour les autres appels de l'API REST. Le code utilise la bibliothèque Python os pour définir des variables d'environnement accessibles dans toutes les cellules de code.

Ceci est spécifique à l'environnement de notebook Colab. Le code de la cellule de code suivante équivaut à exécuter les commandes suivantes dans un terminal 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"

Répertorier les modèles réglés

Vérifiez votre configuration d'authentification en répertoriant les modèles réglés actuellement disponibles.


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

Créer un modèle réglé

Pour créer un modèle réglé, vous devez lui transmettre votre ensemble de données dans le champ training_data.

Dans cet exemple, vous allez régler un modèle pour générer le nombre suivant de la séquence. Par exemple, si l'entrée est 1, le modèle doit générer 2. Si l'entrée est one hundred, la sortie doit être one hundred one.


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

Obtenir l'état du modèle réglé

Le modèle est défini sur CREATING pendant l'entraînement et passe à ACTIVE une fois l'opération terminée.

Vous trouverez ci-dessous un extrait de code Python permettant d'analyser le nom du modèle généré à partir de la réponse JSON. Si vous l'exécutez dans un terminal, vous pouvez essayer d'analyser la réponse à l'aide d'un analyseur 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

Exécutez une autre requête GET avec le nom du modèle pour obtenir les métadonnées du modèle qui incluent le champ "state".


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

Exécuter une inférence

Une fois la tâche de réglage terminée, vous pouvez l'utiliser pour générer du texte avec le service de texte. Essayez de saisir un chiffre romain, par exemple 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"
      }
    ]
  }
}

Le résultat de votre modèle peut être correct ou non. Si le modèle réglé ne répond pas aux normes requises, vous pouvez essayer d'ajouter d'autres exemples de haute qualité, de modifier les hyperparamètres ou d'ajouter un préambule à vos exemples. Vous pouvez même créer un autre modèle réglé à partir du premier modèle que vous avez créé.

Pour en savoir plus sur l'amélioration des performances, consultez le guide de réglage.

Appeler l'API REST avec des requêtes Python

Vous pouvez appeler l'API REST avec n'importe quelle bibliothèque qui vous permet d'envoyer des requêtes HTTP. L'ensemble d'exemples suivant utilise la bibliothèque de requêtes Python et illustre certaines fonctionnalités plus avancées.

Définir des variables

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"

Importez la bibliothèque requests.

import requests
import json

Répertorier les modèles réglés

Vérifiez votre configuration d'authentification en répertoriant les modèles réglés actuellement disponibles.

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()

Créer un modèle réglé

Comme pour l'exemple Curl, vous transmettez l'ensemble de données via le champ training_data.

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'} }

Définissez une variable avec le nom du modèle réglé à utiliser pour le reste des appels.

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

Obtenir l'état du modèle réglé

Vous pouvez vérifier la progression de votre job de réglage en consultant le champ "state". CREATING signifie que la tâche de réglage est toujours en cours, et ACTIVE signifie que les entraînements sont terminés et que le modèle réglé est prêt à l'emploi.

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

Le code ci-dessous vérifie le champ d'état toutes les cinq secondes jusqu'à ce qu'il ne présente plus l'état 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'}

Exécuter une inférence

Une fois la tâche de réglage terminée, vous pouvez l'utiliser pour générer du texte de la même manière que vous utiliseriez le modèle de texte de base. Essayez de saisir un chiffre japonais, par exemple 6 (六).

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'}]} }

Le résultat de votre modèle peut être correct ou non. Si le modèle réglé ne répond pas aux normes requises, vous pouvez essayer d'ajouter d'autres exemples de haute qualité, de modifier les hyperparamètres ou d'ajouter un préambule à vos exemples.

Conclusion

Même si les données d'entraînement ne contiennent aucune référence à des chiffres romains ou japonais, le modèle a été capable de se généraliser bien après les ajustements. Vous pouvez ainsi affiner les modèles en fonction de vos cas d'utilisation.

Étapes suivantes

Pour savoir comment utiliser le service de réglage avec l'aide du SDK Python pour l'API Gemini, consultez le guide de démarrage rapide pour le réglage avec Python. Pour découvrir comment utiliser d'autres services dans l'API Gemini, consultez le guide de démarrage rapide pour Python.