Delen via


Zelfstudie voor het afstemmen van Azure OpenAI GPT-4o-mini

Deze zelfstudie begeleidt u bij het verfijnen van een gpt-4o-mini-2024-07-18 model.

In deze zelfstudie leert u het volgende:

  • Voorbeeldgegevenssets maken.
  • Maak omgevingsvariabelen voor uw resource-eindpunt en API-sleutel.
  • Bereid uw voorbeeldtrainings- en validatiegegevenssets voor op het afstemmen.
  • Upload uw trainingsbestand en validatiebestand voor het afstemmen.
  • Maak een afstemmingstaak voor gpt-4o-mini-2024-07-18.
  • Implementeer een aangepast aangepast model.

Vereisten

  • Een Azure-abonnement: maak er gratis een.
  • Python 3.8 of nieuwere versie
  • De volgende Python-bibliotheken: json, , osrequests, tiktoken, time, , openai. numpy
  • Jupyter Notebooks
  • Een Azure OpenAI-resource in een regio waar gpt-4o-mini-2024-07-18 het afstemmen beschikbaar is. Als u geen resource hebt, wordt het proces voor het maken van een resource gedocumenteerd in onze handleiding voor resource-implementatie.
  • Voor het afstemmen van de toegang is Cognitive Services OpenAI-inzender vereist.
  • Als u nog geen toegang hebt om het quotum weer te geven en modellen implementeert in Azure OpenAI Studio, hebt u extra machtigingen nodig.

Belangrijk

We raden u aan om de prijsinformatie voor afstemming te bekijken om vertrouwd te raken met de bijbehorende kosten. Bij het testen heeft deze zelfstudie geresulteerd in 48.000 tokens die worden gefactureerd (4.800 trainingstokens * 10 periodes van training). Trainingskosten zijn naast de kosten die zijn gekoppeld aan het verfijnen van deductie en de hostingkosten per uur voor het implementeren van een nauwkeurig afgestemd model. Nadat u de zelfstudie hebt voltooid, moet u de aangepaste modelimplementatie verwijderen, anders blijven de hostingkosten per uur in rekening worden gebracht.

Instellingen

Python-bibliotheken

Deze zelfstudie bevat voorbeelden van enkele van de nieuwste OpenAI-functies, waaronder seed/events/controlepunten. Als u van deze functies wilt profiteren, moet u mogelijk een upgrade uitvoeren pip install openai --upgrade naar de nieuwste versie.

pip install openai requests tiktoken numpy

Sleutel en eindpunt ophalen

Als u azure OpenAI wilt aanroepen, hebt u een eindpunt en een sleutel nodig.

Naam van de variabele Weergegeven als
ENDPOINT Het service-eindpunt vindt u in de sectie Sleutels en eindpunten bij het controleren van uw resource vanuit Azure Portal. U kunt het eindpunt ook vinden via de pagina Implementaties in Azure AI Studio. Een voorbeeldeindpunt is: https://docs-test-001.openai.azure.com/.
API-KEY Deze waarde vindt u in de sectie Sleutels en eindpunt bij het onderzoeken van uw resource vanuit de Azure Portal. U kunt KEY1 of KEY2 gebruiken.

Ga naar uw resource in Azure Portal. De sectie Sleutels en eindpunt vindt u in de sectie Resourcebeheer . Kopieer uw eindpunt en toegangssleutel, omdat u beide nodig hebt voor het verifiëren van uw API-aanroepen. U kunt KEY1 of KEY2 gebruiken. Als u altijd twee sleutels hebt, kunt u sleutels veilig roteren en opnieuw genereren zonder een serviceonderbreking te veroorzaken.

Schermopname van de overzichtsgebruikersinterface voor een Azure OpenAI-resource in Azure Portal met het eindpunt en de locatie van toegangssleutels die rood zijn omcirkeld.

Omgevingsvariabelen

Maak en wijs permanente omgevingsvariabelen toe voor uw sleutel en eindpunt.

Belangrijk

Als u een API-sleutel gebruikt, slaat u deze veilig op ergens anders op, zoals in Azure Key Vault. Neem de API-sleutel niet rechtstreeks in uw code op en plaats deze nooit openbaar.

Zie Aanvragen verifiëren bij Azure AI-services voor meer informatie over beveiliging van AI-services.

setx AZURE_OPENAI_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx AZURE_OPENAI_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"

Een voorbeeldgegevensset maken

Voor het afstemmen gpt-4o-mini-2024-07-18 is een speciaal opgemaakt JSONL-trainingsbestand vereist. OpenAI biedt het volgende voorbeeld in hun documentatie:

{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already."}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?"}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters."}]}

In dit voorbeeld wijzigen we dit enigszins door het volgende te wijzigen:

{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already."}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?"}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters."}]}

Hoewel deze drie voorbeelden handig zijn om u de algemene indeling te geven, moet u meer voorbeelden nodig hebben als u uw aangepaste aangepaste model wilt sturen om op een vergelijkbare manier te reageren. Over het algemeen wilt u ten minste 50 voorbeelden van hoge kwaliteit starten. Het is echter volledig mogelijk om een use-case te hebben waarvoor 1000 van hoogwaardige trainingsvoorbeelden van hoge kwaliteit nodig kan zijn.

Over het algemeen kan het verdubbelen van de grootte van de gegevensset leiden tot een lineaire toename van de modelkwaliteit. Maar houd er rekening mee dat voorbeelden van lage kwaliteit een negatieve invloed kunnen hebben op de prestaties. Als u het model traint op een grote hoeveelheid interne gegevens, zonder eerst de gegevensset te verwijderen voor alleen de voorbeelden van de hoogste kwaliteit, kunt u eindigen met een model dat veel slechter presteert dan verwacht.

U moet twee bestanden training_set.jsonl maken en validation_set.jsonl.

Maak de bestanden in dezelfde map waarop u het Jupyter Notebook uitvoert en kopieer de inhoud van de volgende codeblokken naar de bijbehorende bestanden:

training_set.jsonl

{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who discovered Antarctica?"}, {"role": "assistant", "content": "Some chaps named Fabian Gottlieb von Bellingshausen and Mikhail Lazarev, as if they don't teach that in every school!"}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What is the biggest ocean?"}, {"role": "assistant", "content": "The Pacific Ocean. It's not like it's a small pond or anything."}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What is the largest planet?"}, {"role": "assistant", "content": "It's called Jupiter, you may have heard of it...or not."}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who painted the Mona Lisa?"}, {"role": "assistant", "content": "Oh, some obscure artist named Leonardo da Vinci. Not that he is famous or anything."}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the boiling point of water?"}, {"role": "assistant", "content": "Exciting fact of the day: it's 100 degrees Celsius. Life-changing, isn't it?"}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'The Odyssey'?"}, {"role": "assistant", "content": "Oh, just some poet named Homer. Nothing special, really."}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What is the largest mammal?"}, {"role": "assistant", "content": "Blue Whale. Quite a big fish isn't it? Oh wait, it's not a fish!"}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the highest mountain peak?"}, {"role": "assistant", "content": "Everest. Brace yourself, it's not a walk in the park."}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who invented the telephone?"}, {"role": "assistant", "content": "A guy named Alexander Graham Bell. Bet you didn't guess that one!"}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What is the distance from Earth to the Sun?"}, {"role": "assistant", "content": "About 93 million miles. Just a quick drive, really."}]}

validation_set.jsonl

{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of Australia?"}, {"role": "assistant", "content": "It's Canberra, not Sydney. Shocking, I know!"}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'The Great Gatsby'?"}, {"role": "assistant", "content": "Some guy named F. Scott Fitzgerald. Ever heard of him?"}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the deepest part of the ocean?"}, {"role": "assistant", "content": "Mariana Trench, makes your swimming pool seem a bit shallow, doesn't it?"}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who composed the 'Moonlight Sonata'?"}, {"role": "assistant", "content": "Just a little-known guy named Beethoven. No big deal."}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What are the colors of the rainbow?"}, {"role": "assistant", "content": "ROYGBIV. Red, orange, yellow, green, blue, indigo, violet. Not that we learned this in preschool or anything!"}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What is the smallest planet?"}, {"role": "assistant", "content": "Meet Mercury, the runt of the solar system family."}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Pride and Prejudice'?"}, {"role": "assistant", "content": "Do the words Jane Austen ring a bell? No? Well, she wrote it."}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the largest desert?"}, {"role": "assistant", "content": "Antarctica. Surprise, surprise! Deserts aren't just full of sand, you know."}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What is the longest river?"}, {"role": "assistant", "content": "The Nile River. It's not like it's famous or anything."}]}
{"messages": [{"role": "system", "content": "Clippy is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of Germany?"}, {"role": "assistant", "content": "Berlin. Shocking news, right?"}]}

Nu moet u enkele voorbereidende controles uitvoeren op onze trainings- en validatiebestanden.

# Run preliminary checks

import json

# Load the training set
with open('training_set.jsonl', 'r', encoding='utf-8') as f:
    training_dataset = [json.loads(line) for line in f]

# Training dataset stats
print("Number of examples in training set:", len(training_dataset))
print("First example in training set:")
for message in training_dataset[0]["messages"]:
    print(message)

# Load the validation set
with open('validation_set.jsonl', 'r', encoding='utf-8') as f:
    validation_dataset = [json.loads(line) for line in f]

# Validation dataset stats
print("\nNumber of examples in validation set:", len(validation_dataset))
print("First example in validation set:")
for message in validation_dataset[0]["messages"]:
    print(message)

Uitvoer:

Number of examples in training set: 10
First example in training set:
{'role': 'system', 'content': 'Clippy is a factual chatbot that is also sarcastic.'}
{'role': 'user', 'content': 'Who discovered America?'}
{'role': 'assistant', 'content': "Some chap named Christopher Columbus, as if they don't teach that in every school!"}

Number of examples in validation set: 10
First example in validation set:
{'role': 'system', 'content': 'Clippy is a factual chatbot that is also sarcastic.'}
{'role': 'user', 'content': "What's the capital of Australia?"}
{'role': 'assistant', 'content': "It's Canberra, not Sydney. Shocking, I know!"}

In dit geval hebben we slechts 10 trainings- en 10 validatievoorbeelden, dus hoewel dit de basismechanica laat zien van het verfijnen van een model, is dit in onwaarschijnlijke gevallen een groot genoeg aantal voorbeelden om een consistent merkbare impact te produceren.

U kunt nu extra code uitvoeren vanuit OpenAI met behulp van de tiktokenbibliotheek om het aantal token te valideren. Token tellen met deze methode geeft u niet de exacte tokenaantallen die worden gebruikt voor het afstemmen, maar moet een goede schatting geven.

Notitie

Afzonderlijke voorbeelden moeten onder de huidige context van het trainingsvoorbeeld van het gpt-4o-mini-2024-07-18 model blijven van: 64.536 tokens. De invoertokenlimiet van het model blijft 128.000 tokens.

# Validate token counts

import json
import tiktoken
import numpy as np
from collections import defaultdict

encoding = tiktoken.get_encoding("o200k_base") # default encoding for gpt-4o models. This requires the latest version of tiktoken to be installed.

def num_tokens_from_messages(messages, tokens_per_message=3, tokens_per_name=1):
    num_tokens = 0
    for message in messages:
        num_tokens += tokens_per_message
        for key, value in message.items():
            num_tokens += len(encoding.encode(value))
            if key == "name":
                num_tokens += tokens_per_name
    num_tokens += 3
    return num_tokens

def num_assistant_tokens_from_messages(messages):
    num_tokens = 0
    for message in messages:
        if message["role"] == "assistant":
            num_tokens += len(encoding.encode(message["content"]))
    return num_tokens

def print_distribution(values, name):
    print(f"\n#### Distribution of {name}:")
    print(f"min / max: {min(values)}, {max(values)}")
    print(f"mean / median: {np.mean(values)}, {np.median(values)}")
    print(f"p5 / p95: {np.quantile(values, 0.1)}, {np.quantile(values, 0.9)}")

files = ['training_set.jsonl', 'validation_set.jsonl']

for file in files:
    print(f"Processing file: {file}")
    with open(file, 'r', encoding='utf-8') as f:
        dataset = [json.loads(line) for line in f]

    total_tokens = []
    assistant_tokens = []

    for ex in dataset:
        messages = ex.get("messages", {})
        total_tokens.append(num_tokens_from_messages(messages))
        assistant_tokens.append(num_assistant_tokens_from_messages(messages))

    print_distribution(total_tokens, "total tokens")
    print_distribution(assistant_tokens, "assistant tokens")
    print('*' * 50)

Uitvoer:

Processing file: training_set.jsonl

#### Distribution of total tokens:
min / max: 46, 59
mean / median: 49.8, 48.5
p5 / p95: 46.0, 53.599999999999994

#### Distribution of assistant tokens:
min / max: 13, 28
mean / median: 16.5, 14.0
p5 / p95: 13.0, 19.9
**************************************************
Processing file: validation_set.jsonl

#### Distribution of total tokens:
min / max: 41, 64
mean / median: 48.9, 47.0
p5 / p95: 43.7, 54.099999999999994

#### Distribution of assistant tokens:
min / max: 8, 29
mean / median: 15.0, 12.5
p5 / p95: 10.7, 19.999999999999996
****************************

Verfijningsbestanden uploaden

# Upload fine-tuning files

import os
from openai import AzureOpenAI

client = AzureOpenAI(
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"),
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),
  api_version = "2024-08-01-preview"  # This API version or later is required to access seed/events/checkpoint features
)

training_file_name = 'training_set.jsonl'
validation_file_name = 'validation_set.jsonl'

# Upload the training and validation dataset files to Azure OpenAI with the SDK.

training_response = client.files.create(
    file = open(training_file_name, "rb"), purpose="fine-tune"
)
training_file_id = training_response.id

validation_response = client.files.create(
    file = open(validation_file_name, "rb"), purpose="fine-tune"
)
validation_file_id = validation_response.id

print("Training file ID:", training_file_id)
print("Validation file ID:", validation_file_id)

Uitvoer:

Training file ID: file-0e3aa3f2e81e49a5b8b96166ea214626
Validation file ID: file-8556c3bb41b7416bb7519b47fcd1dd6b

Beginnen met afstemmen

Nu de verfijningsbestanden zijn geüpload, kunt u uw trainingstaak voor het afstemmen indienen:

In dit voorbeeld geven we ook de seed-parameter door. Het zaad bepaalt de reproduceerbaarheid van de taak. Het doorgeven van dezelfde seed- en taakparameters moet dezelfde resultaten opleveren, maar kan in zeldzame gevallen verschillen. Als er geen seed is opgegeven, wordt er een voor u gegenereerd.

# Submit fine-tuning training job

response = client.fine_tuning.jobs.create(
    training_file = training_file_id,
    validation_file = validation_file_id,
    model = "gpt-4o-mini-2024-07-18", # Enter base model name. Note that in Azure OpenAI the model name contains dashes and cannot contain dot/period characters.
    seed = 105 # seed parameter controls reproducibility of the fine-tuning job. If no seed is specified one will be generated automatically.
)

job_id = response.id

# You can use the job ID to monitor the status of the fine-tuning job.
# The fine-tuning job will take some time to start and complete.

print("Job ID:", response.id)
print("Status:", response.status)
print(response.model_dump_json(indent=2))

Python 1.x-uitvoer:

Job ID: ftjob-900fcfc7ea1d4360a9f0cb1697b4eaa6
Status: pending
{
  "id": "ftjob-900fcfc7ea1d4360a9f0cb1697b4eaa6",
  "created_at": 1715824115,
  "error": null,
  "fine_tuned_model": null,
  "finished_at": null,
  "hyperparameters": {
    "n_epochs": -1,
    "batch_size": -1,
    "learning_rate_multiplier": 1
  },
  "model": "gpt-4o-mini-2024-07-18",
  "object": "fine_tuning.job",
  "organization_id": null,
  "result_files": null,
  "seed": 105,
  "status": "pending",
  "trained_tokens": null,
  "training_file": "file-0e3aa3f2e81e49a5b8b96166ea214626",
  "validation_file": "file-8556c3bb41b7416bb7519b47fcd1dd6b",
  "estimated_finish": null,
  "integrations": null
}

Status van trainingstaak bijhouden

Als u de status van de trainingstaak wilt peilen totdat deze is voltooid, kunt u het volgende uitvoeren:

# Track training status

from IPython.display import clear_output
import time

start_time = time.time()

# Get the status of our fine-tuning job.
response = client.fine_tuning.jobs.retrieve(job_id)

status = response.status

# If the job isn't done yet, poll it every 10 seconds.
while status not in ["succeeded", "failed"]:
    time.sleep(10)

    response = client.fine_tuning.jobs.retrieve(job_id)
    print(response.model_dump_json(indent=2))
    print("Elapsed time: {} minutes {} seconds".format(int((time.time() - start_time) // 60), int((time.time() - start_time) % 60)))
    status = response.status
    print(f'Status: {status}')
    clear_output(wait=True)

print(f'Fine-tuning job {job_id} finished with status: {status}')

# List all fine-tuning jobs for this resource.
print('Checking other fine-tune jobs for this resource.')
response = client.fine_tuning.jobs.list()
print(f'Found {len(response.data)} fine-tune jobs.')

Python 1.x-uitvoer:

Job ID: ftjob-900fcfc7ea1d4360a9f0cb1697b4eaa6
Status: pending
{
  "id": "ftjob-900fcfc7ea1d4360a9f0cb1697b4eaa6",
  "created_at": 1715824115,
  "error": null,
  "fine_tuned_model": null,
  "finished_at": null,
  "hyperparameters": {
    "n_epochs": -1,
    "batch_size": -1,
    "learning_rate_multiplier": 1
  },
  "model": "gpt-4o-mini-2024-07-18",
  "object": "fine_tuning.job",
  "organization_id": null,
  "result_files": null,
  "seed": 105,
  "status": "pending",
  "trained_tokens": null,
  "training_file": "file-0e3aa3f2e81e49a5b8b96166ea214626",
  "validation_file": "file-8556c3bb41b7416bb7519b47fcd1dd6b",
  "estimated_finish": null,
  "integrations": null
}

Het is niet ongebruikelijk dat het meer dan een uur duurt voordat de training is voltooid. Zodra de training is voltooid, wordt het uitvoerbericht gewijzigd in bijvoorbeeld:

Fine-tuning job ftjob-900fcfc7ea1d4360a9f0cb1697b4eaa6 finished with status: succeeded
Checking other fine-tune jobs for this resource.
Found 4 fine-tune jobs.

Afstemmingsgebeurtenissen weergeven

API-versie: 2024-08-01-preview of hoger is vereist voor deze opdracht.

Hoewel het niet nodig is om het afstemmen te voltooien, kan het handig zijn om de afzonderlijke afstemmingsgebeurtenissen te onderzoeken die tijdens de training zijn gegenereerd. De volledige trainingsresultaten kunnen ook worden onderzocht nadat de training is voltooid in het trainingsresultatenbestand.

response = client.fine_tuning.jobs.list_events(fine_tuning_job_id=job_id, limit=10)
print(response.model_dump_json(indent=2))

Python 1.x-uitvoer:

{
  "data": [
    {
      "id": "ftevent-179d02d6178f4a0486516ff8cbcdbfb6",
      "created_at": 1715826339,
      "level": "info",
      "message": "Training hours billed: 0.500",
      "object": "fine_tuning.job.event",
      "type": "message"
    },
    {
      "id": "ftevent-467bc5e766224e97b5561055dc4c39c0",
      "created_at": 1715826339,
      "level": "info",
      "message": "Completed results file: file-175c81c590074388bdb49e8e0d91bac3",
      "object": "fine_tuning.job.event",
      "type": "message"
    },
    {
      "id": "ftevent-a30c44da4c304180b327c3be3a7a7e51",
      "created_at": 1715826337,
      "level": "info",
      "message": "Postprocessing started.",
      "object": "fine_tuning.job.event",
      "type": "message"
    },
    {
      "id": "ftevent-ea10a008f1a045e9914de98b6b47514b",
      "created_at": 1715826303,
      "level": "info",
      "message": "Job succeeded.",
      "object": "fine_tuning.job.event",
      "type": "message"
    },
    {
      "id": "ftevent-008dc754dc9e61b008dc754dc9e61b00",
      "created_at": 1715825614,
      "level": "info",
      "message": "Step 100: training loss=0.001647822093218565",
      "object": "fine_tuning.job.event",
      "type": "metrics",
      "data": {
        "step": 100,
        "train_loss": 0.001647822093218565,
        "train_mean_token_accuracy": 1,
        "valid_loss": 1.5170825719833374,
        "valid_mean_token_accuracy": 0.75,
        "full_valid_loss": 1.7539110545870624,
        "full_valid_mean_token_accuracy": 0.7215189873417721
      }
    },
    {
      "id": "ftevent-008dc754dc3f03a008dc754dc3f03a00",
      "created_at": 1715825604,
      "level": "info",
      "message": "Step 90: training loss=0.00971441250294447",
      "object": "fine_tuning.job.event",
      "type": "metrics",
      "data": {
        "step": 90,
        "train_loss": 0.00971441250294447,
        "train_mean_token_accuracy": 1,
        "valid_loss": 1.3702410459518433,
        "valid_mean_token_accuracy": 0.75,
        "full_valid_loss": 1.7371194453179082,
        "full_valid_mean_token_accuracy": 0.7278481012658228
      }
    },
    {
      "id": "ftevent-008dc754dbdfa59008dc754dbdfa5900",
      "created_at": 1715825594,
      "level": "info",
      "message": "Step 80: training loss=0.0032251903321594",
      "object": "fine_tuning.job.event",
      "type": "metrics",
      "data": {
        "step": 80,
        "train_loss": 0.0032251903321594,
        "train_mean_token_accuracy": 1,
        "valid_loss": 1.4242165088653564,
        "valid_mean_token_accuracy": 0.75,
        "full_valid_loss": 1.6554046099698996,
        "full_valid_mean_token_accuracy": 0.7278481012658228
      }
    },
    {
      "id": "ftevent-008dc754db80478008dc754db8047800",
      "created_at": 1715825584,
      "level": "info",
      "message": "Step 70: training loss=0.07380199432373047",
      "object": "fine_tuning.job.event",
      "type": "metrics",
      "data": {
        "step": 70,
        "train_loss": 0.07380199432373047,
        "train_mean_token_accuracy": 1,
        "valid_loss": 1.2011798620224,
        "valid_mean_token_accuracy": 0.75,
        "full_valid_loss": 1.508960385865803,
        "full_valid_mean_token_accuracy": 0.740506329113924
      }
    },
    {
      "id": "ftevent-008dc754db20e97008dc754db20e9700",
      "created_at": 1715825574,
      "level": "info",
      "message": "Step 60: training loss=0.245253324508667",
      "object": "fine_tuning.job.event",
      "type": "metrics",
      "data": {
        "step": 60,
        "train_loss": 0.245253324508667,
        "train_mean_token_accuracy": 0.875,
        "valid_loss": 1.0585949420928955,
        "valid_mean_token_accuracy": 0.75,
        "full_valid_loss": 1.3787144045286541,
        "full_valid_mean_token_accuracy": 0.7341772151898734
      }
    },
    {
      "id": "ftevent-008dc754dac18b6008dc754dac18b600",
      "created_at": 1715825564,
      "level": "info",
      "message": "Step 50: training loss=0.1696014404296875",
      "object": "fine_tuning.job.event",
      "type": "metrics",
      "data": {
        "step": 50,
        "train_loss": 0.1696014404296875,
        "train_mean_token_accuracy": 0.8999999761581421,
        "valid_loss": 0.8862184286117554,
        "valid_mean_token_accuracy": 0.8125,
        "full_valid_loss": 1.2814022257358213,
        "full_valid_mean_token_accuracy": 0.7151898734177216
      }
    }
  ],
  "has_more": true,
  "object": "list"
}

Controlepunten weergeven

API-versie: 2024-08-01-preview of hoger is vereist voor deze opdracht.

Wanneer elk trainingstijdperk een controlepunt voltooit, wordt er een controlepunt gegenereerd. Een controlepunt is een volledig functionele versie van een model dat zowel kan worden geïmplementeerd als gebruikt als het doelmodel voor volgende taakafstemming. Controlepunten kunnen met name nuttig zijn, omdat ze een momentopname van uw model kunnen bieden voordat er overfitting is opgetreden. Wanneer een taak voor het afstemmen is voltooid, beschikt u over de drie meest recente versies van het model die u kunt implementeren. De laatste periode wordt vertegenwoordigd door uw nauwkeurig afgestemde model, de vorige twee epochs zijn beschikbaar als controlepunten.

response = client.fine_tuning.jobs.checkpoints.list(job_id)
print(response.model_dump_json(indent=2))

Python 1.x-uitvoer:

{
  "data": [
    {
      "id": "ftchkpt-148ab69f0a404cf9ab55a73d51b152de",
      "created_at": 1715743077,
      "fine_tuned_model_checkpoint": "gpt-4o-mini-2024-07-18.ft-0e208cf33a6a466994aff31a08aba678",
      "fine_tuning_job_id": "ftjob-372c72db22c34e6f9ccb62c26ee0fbd9",
      "metrics": {
        "full_valid_loss": 1.8258173013035255,
        "full_valid_mean_token_accuracy": 0.7151898734177216,
        "step": 100.0,
        "train_loss": 0.004080486483871937,
        "train_mean_token_accuracy": 1.0,
        "valid_loss": 1.5915886163711548,
        "valid_mean_token_accuracy": 0.75
      },
      "object": "fine_tuning.job.checkpoint",
      "step_number": 100
    },
    {
      "id": "ftchkpt-e559c011ecc04fc68eaa339d8227d02d",
      "created_at": 1715743013,
      "fine_tuned_model_checkpoint": "gpt-4o-mini-2024-07-18.ft-0e208cf33a6a466994aff31a08aba678:ckpt-step-90",
      "fine_tuning_job_id": "ftjob-372c72db22c34e6f9ccb62c26ee0fbd9",
      "metrics": {
        "full_valid_loss": 1.7958603267428241,
        "full_valid_mean_token_accuracy": 0.7215189873417721,
        "step": 90.0,
        "train_loss": 0.0011079151881858706,
        "train_mean_token_accuracy": 1.0,
        "valid_loss": 1.6084896326065063,
        "valid_mean_token_accuracy": 0.75
      },
      "object": "fine_tuning.job.checkpoint",
      "step_number": 90
    },
    {
      "id": "ftchkpt-8ae8beef3dcd4dfbbe9212e79bb53265",
      "created_at": 1715742984,
      "fine_tuned_model_checkpoint": "gpt-4o-mini-2024-07-18.ft-0e208cf33a6a466994aff31a08aba678:ckpt-step-80",
      "fine_tuning_job_id": "ftjob-372c72db22c34e6f9ccb62c26ee0fbd9",
      "metrics": {
        "full_valid_loss": 1.6909511662736725,
        "full_valid_mean_token_accuracy": 0.7088607594936709,
        "step": 80.0,
        "train_loss": 0.000667572021484375,
        "train_mean_token_accuracy": 1.0,
        "valid_loss": 1.4677599668502808,
        "valid_mean_token_accuracy": 0.75
      },
      "object": "fine_tuning.job.checkpoint",
      "step_number": 80
    }
  ],
  "has_more": false,
  "object": "list"
}

Laatste trainingsuitvoeringsresultaten

Voer het volgende uit om de uiteindelijke resultaten te verkrijgen:

# Retrieve fine_tuned_model name

response = client.fine_tuning.jobs.retrieve(job_id)

print(response.model_dump_json(indent=2))
fine_tuned_model = response.fine_tuned_model

Een nauwkeurig afgestemd model implementeren

In tegenstelling tot de vorige Python SDK-opdrachten in deze zelfstudie, moet de modelimplementatie worden uitgevoerd met behulp van de REST API, waarvoor afzonderlijke autorisatie, een ander API-pad en een andere API-versie zijn vereist.

U kunt ook uw nauwkeurig afgestemde model implementeren met behulp van een van de andere veelgebruikte implementatiemethoden, zoals Azure OpenAI Studio of Azure CLI.

variabele Definitie
token Er zijn meerdere manieren om een autorisatietoken te genereren. De eenvoudigste methode voor eerste tests is het starten van Cloud Shell vanuit Azure Portal. Voer vervolgens az account get-access-token uit. U kunt dit token gebruiken als uw tijdelijke autorisatietoken voor API-tests. We raden u aan dit op te slaan in een nieuwe omgevingsvariabele
abonnement De abonnements-id voor de bijbehorende Azure OpenAI-resource
resource_group De naam van de resourcegroep voor uw Azure OpenAI-resource
resource_name De naam van de Azure OpenAI-resource
model_deployment_name De aangepaste naam voor de nieuwe aangepaste modelimplementatie. Dit is de naam waarnaar wordt verwezen in uw code bij het maken van chat-voltooiingsgesprekken.
fine_tuned_model Haal deze waarde op uit uw verfijningstaak en resultaten in de vorige stap. Het zal eruitzien als gpt-4o-mini-2024-07-18.ft-0e208cf33a6a466994aff31a08aba678. U moet die waarde toevoegen aan de deploy_data json.

Belangrijk

Nadat u een aangepast model hebt geïmplementeerd, wordt de implementatie verwijderd als de implementatie langer dan vijftien (15) dagen inactief blijft. De implementatie van een aangepast model is inactief als het model meer dan vijftien (15) dagen geleden is geïmplementeerd en er tijdens een continue periode van 15 dagen geen voltooiingen of chatvoltooiingen zijn gedaan.

Het verwijderen van een inactieve implementatie is niet van invloed op het onderliggende aangepaste model en het aangepaste model kan op elk gewenst moment opnieuw worden geïmplementeerd. Zoals beschreven in prijzen van De Azure OpenAI-service, worden voor elk aangepast (nauwkeurig) model dat wordt geïmplementeerd, een uurlijkse hostingkosten in rekening gebracht, ongeacht of er aanroepen voor voltooiingen of chats in het model worden gedaan. Voor meer informatie over het plannen en beheren van kosten met Azure OpenAI raadpleegt u de richtlijnen in Plan voor het beheren van kosten voor Azure OpenAI Service.

# Deploy fine-tuned model

import json
import requests

token = os.getenv("TEMP_AUTH_TOKEN")
subscription = "<YOUR_SUBSCRIPTION_ID>"
resource_group = "<YOUR_RESOURCE_GROUP_NAME>"
resource_name = "<YOUR_AZURE_OPENAI_RESOURCE_NAME>"
model_deployment_name = "gpt-4o-mini-2024-07-18-ft" # Custom deployment name you chose for your fine-tuning model

deploy_params = {'api-version': "2023-05-01"}
deploy_headers = {'Authorization': 'Bearer {}'.format(token), 'Content-Type': 'application/json'}

deploy_data = {
    "sku": {"name": "standard", "capacity": 1},
    "properties": {
        "model": {
            "format": "OpenAI",
            "name": "<YOUR_FINE_TUNED_MODEL>", #retrieve this value from the previous call, it will look like gpt-4o-mini-2024-07-18.ft-0e208cf33a6a466994aff31a08aba678
            "version": "1"
        }
    }
}
deploy_data = json.dumps(deploy_data)

request_url = f'https://management.azure.com/subscriptions/{subscription}/resourceGroups/{resource_group}/providers/Microsoft.CognitiveServices/accounts/{resource_name}/deployments/{model_deployment_name}'

print('Creating a new deployment...')

r = requests.put(request_url, params=deploy_params, headers=deploy_headers, data=deploy_data)

print(r)
print(r.reason)
print(r.json())

U kunt de voortgang van uw implementatie controleren in Azure OpenAI Studio:

Schermopname van de voortgang van de implementatie in Azure OpenAI Studio.

Het is niet ongebruikelijk dat het enige tijd kost om dit proces te voltooien bij het implementeren van nauwkeurig afgestemde modellen.

Een geïmplementeerd aangepast model gebruiken

Nadat uw nauwkeurig afgestemde model is geïmplementeerd, kunt u het gebruiken zoals elk ander geïmplementeerd model in de Chat Playground van Azure OpenAI Studio of via de api voor het voltooien van de chat. U kunt bijvoorbeeld een chatopvullingsgesprek verzenden naar uw geïmplementeerde model, zoals wordt weergegeven in het volgende Python-voorbeeld. U kunt dezelfde parameters blijven gebruiken met uw aangepaste model, zoals temperatuur en max_tokens, zoals bij andere geïmplementeerde modellen.

# Use the deployed customized model

import os
from openai import AzureOpenAI

client = AzureOpenAI(
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"),
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),
  api_version = "2024-06-01"
)

response = client.chat.completions.create(
    model = "gpt-4o-mini-2024-07-18-ft", # model = "Custom deployment name you chose for your fine-tuning model"
    messages = [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Does Azure OpenAI support customer managed keys?"},
        {"role": "assistant", "content": "Yes, customer managed keys are supported by Azure OpenAI."},
        {"role": "user", "content": "Do other Azure AI services support this too?"}
    ]
)

print(response.choices[0].message.content)

Implementatie verwijderen

In tegenstelling tot andere typen Azure OpenAI-modellen hebben afgestemde/aangepaste modellen een uurlijkse hostingkosten aan hen gekoppeld zodra ze zijn geïmplementeerd. Het wordt sterk aanbevolen dat wanneer u klaar bent met deze zelfstudie en een paar chat-voltooiingsgesprekken hebt getest op basis van uw nauwkeurig afgestemde model, dat u de modelimplementatie verwijdert.

Het verwijderen van de implementatie heeft geen invloed op het model zelf, dus u kunt het aangepaste model dat u voor deze zelfstudie hebt getraind, op elk gewenst moment opnieuw implementeren.

U kunt de implementatie in Azure OpenAI Studio verwijderen via REST API, Azure CLI of andere ondersteunde implementatiemethoden.

Probleemoplossing

Hoe kan ik afstemmen inschakelen? Een aangepast model maken wordt grijs weergegeven in Azure OpenAI Studio

Als u toegang wilt krijgen tot fine-tuning, hebt u Cognitive Services OpenAI-inzender toegewezen. Zelfs iemand met machtigingen voor servicebeheerders op hoog niveau heeft dit account nog steeds expliciet ingesteld om toegang te krijgen tot het afstemmen. Raadpleeg de richtlijnen voor op rollen gebaseerd toegangsbeheer voor meer informatie.

Volgende stappen