Megosztás a következőn keresztül:


Azure OpenAI GPT-3.5 Turbo finomhangolási oktatóanyag

Ez az oktatóanyag végigvezeti a modell finomhangolásán gpt-35-turbo-0613 .

Ezen oktatóanyag segítségével megtanulhatja a következőket:

  • Minta finomhangolási adathalmazok létrehozása.
  • Hozzon létre környezeti változókat az erőforrásvégponthoz és az API-kulcshoz.
  • Készítse elő a minta betanítási és érvényesítési adatkészleteket a finomhangoláshoz.
  • Töltse fel a betanítási fájlt és az érvényesítési fájlt a finomhangoláshoz.
  • Finomhangolási feladat létrehozása a következőhöz gpt-35-turbo-0613: .
  • Egyéni, finomhangolt modell üzembe helyezése.

Előfeltételek

  • Azure-előfizetés – Hozzon létre egyet ingyenesen.
  • A kívánt Azure-előfizetésben az Azure OpenAI számára biztosított hozzáférés jelenleg csak alkalmazás által érhető el. Az Azure OpenAI-hoz való hozzáférésre a következő https://aka.ms/oai/accessűrlap kitöltésével jelentkezhet: .
  • Python 3.8 vagy újabb verzió
  • A következő Python-kódtárak: json, requests, os, tiktoken, time, openainumpy.
  • Jupyter notebook
  • Azure OpenAI-erőforrás egy olyan régióban, ahol gpt-35-turbo-0613 a finomhangolás elérhető. Ha nem rendelkezik erőforrással, a létrehozás folyamatát az erőforrás-üzembe helyezési útmutatónk dokumentálja.
  • A hozzáférés finomhangolásához a Cognitive Services OpenAI-közreműködője szükséges.
  • Ha még nem rendelkezik hozzáféréssel a kvóta megtekintéséhez, és modelleket helyez üzembe az Azure OpenAI Studióban, további engedélyekre lesz szüksége.

Fontos

Javasoljuk, hogy az oktatóanyag megkezdése előtt tekintse át a díjszabási információkat a finomhangolás érdekében, hogy biztosan jól tudja-e a kapcsolódó költségeket. A tesztelés során ez az oktatóanyag egy betanítási órát számlázott ki a finomhangolási következtetéshez kapcsolódó költségek mellett, valamint a finomhangolt modell üzembe helyezésének óránkénti üzemeltetési költségeit is. Miután elvégezte az oktatóanyagot, törölnie kell a finomhangolt modell üzembe helyezését, különben továbbra is felmerül az óránkénti üzemeltetési költség.

Beállítás

Python-kódtárak

Ez az oktatóanyag példákat mutat be a legújabb OpenAI-funkciókra, például a seed/events/checkpoints szolgáltatásra. A funkciók kihasználásához előfordulhat, hogy a legújabb kiadásra való frissítéshez futnia pip install openai --upgrade kell.

pip install openai requests tiktoken numpy

Kulcs és végpont lekérése

Az Azure OpenAI-ra való sikeres híváshoz egy végpontra és egy kulcsra van szükség.

Változó neve Érték
ENDPOINT Ez az érték a Kulcsok és végpont szakaszban található meg, amikor megvizsgálja az erőforrást az Azure Portalon. Az értéket az Azure OpenAI Studio>Playground>Code nézetben is megtalálhatja. Példavégpont: https://docs-test-001.openai.azure.com/.
API-KEY Ez az érték a Kulcsok és végpont szakaszban található meg, amikor megvizsgálja az erőforrást az Azure Portalon. A következők bármelyikét használhatja: KEY1 vagy KEY2.

Nyissa meg az erőforrást az Azure Portalon. A Kulcsok > végpont szakasz az Erőforrás-kezelés szakaszban található. Másolja ki a végpontot és a hozzáférési kulcsot, mivel mindkettőre szüksége lesz az API-hívások hitelesítéséhez. A következők bármelyikét használhatja: KEY1 vagy KEY2. A két kulcs mindig lehetővé teszi a kulcsok biztonságos elforgatását és újragenerálását anélkül, hogy szolgáltatáskimaradást okoz.

Képernyőkép egy Azure OpenAI-erőforrás áttekintő felhasználói felületéről az Azure Portalon, a végpont és a hozzáférési kulcsok helye pirossal bekarikázva.

Környezeti változók

setx AZURE_OPENAI_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx AZURE_OPENAI_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"

Mintaadatkészlet létrehozása

A finomhangoláshoz gpt-35-turbo-0613 speciálisan formázott JSONL-betanítási fájl szükséges. Az OpenAI a következő példát tartalmazza a dokumentációban:

{"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."}]}

Ebben a példában ezt kissé módosítjuk a következőre való módosítással:

{"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."}]}

Bár ez a három példa hasznos lehet az általános formátumhoz, ha az egyéni finomhangolt modellt hasonló módon szeretné irányítani, további példákra lenne szüksége. Általában legalább 50 kiváló minőségű példát szeretne elindítani. Azonban teljesen lehetséges olyan használati eset, amely 1000 kiváló minőségű betanítási példát igényelhet a sikerességhez.

Általánosságban elmondható, hogy az adathalmaz méretének megduplázása lineáris modellminőség-növekedéshez vezethet. Ne feledje azonban, hogy az alacsony minőségű példák negatív hatással lehetnek a teljesítményre. Ha nagy mennyiségű belső adatra tanítja be a modellt, anélkül, hogy először csak a legjobb minőségű példákhoz metszést végezne, a vártnál sokkal rosszabb teljesítményt nyújtó modellhez vezethet.

Létre kell hoznia két fájlt training_set.jsonl és validation_set.jsonl.

Hozza létre a fájlokat ugyanabban a könyvtárban, amelyben a Jupyter Notebookot futtatja, és másolja a következő kódblokkok tartalmát a megfelelő fájlokba:

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?"}]}

Most le kell futtatnia néhány előzetes ellenőrzést a betanítási és érvényesítési fájlokon.

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

Hozam:

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!"}

Ebben az esetben csak 10 betanítási és 10 érvényesítési példánk van, így bár ez egy modell finomhangolásának alapvető mechanikáit mutatja be, valószínűleg nem lesz elég sok példa ahhoz, hogy következetesen észrevehető hatást eredményezzünk.

Ezután futtathat néhány további kódot az OpenAI-ból a tiktoken kódtár használatával a jogkivonatok számának ellenőrzéséhez. Az egyes példáknak a gpt-35-turbo-0613 modell 4096-os bemeneti jogkivonat-korlátja alatt kell maradniuk.

# Validate token counts

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

encoding = tiktoken.get_encoding("cl100k_base") # default encoding used by gpt-4, turbo, and text-embedding-ada-002 models

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)

Hozam:

Processing file: training_set.jsonl

#### Distribution of total tokens:
min / max: 47, 62
mean / median: 52.1, 50.5
p5 / p95: 47.9, 57.5

#### Distribution of assistant tokens:
min / max: 13, 30
mean / median: 17.6, 15.5
p5 / p95: 13.0, 21.9
**************************************************
Processing file: validation_set.jsonl

#### Distribution of total tokens:
min / max: 43, 65
mean / median: 51.4, 49.0
p5 / p95: 45.7, 56.9

#### Distribution of assistant tokens:
min / max: 8, 29
mean / median: 15.9, 13.5
p5 / p95: 11.6, 20.9
**************************************************

Fájlok finomhangolása

# 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-05-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)

Hozam:

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

Finomhangolás megkezdése

Most, hogy sikeresen feltöltötte a finomhangoló fájlokat, elküldheti a finomhangoló betanítási feladatot:

Ebben a példában a magparamétert is átadjuk. A vetőmag szabályozza a feladat reprodukálhatóságát. Az azonos vetőmag- és feladatparaméterek átadása ugyanazokat az eredményeket eredményezi, de ritka esetekben eltérő lehet. Ha nincs megadva mag, a rendszer létrehoz egy magot.

# Submit fine-tuning training job

response = client.fine_tuning.jobs.create(
    training_file = training_file_id,
    validation_file = validation_file_id,
    model = "gpt-35-turbo-0613", # 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 kimenet:

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-35-turbo-0613",
  "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
}

Betanítási feladat állapotának nyomon követése

Ha le szeretné lekérdezni a betanítási feladat állapotát, amíg be nem fejeződik, futtathatja a következőt:

# 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 kimenet:

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-35-turbo-0613",
  "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
}

Nem szokatlan, hogy a betanítás több mint egy órát vesz igénybe. A betanítás befejezése után a kimeneti üzenet a következőhöz hasonlóra változik:

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

Események finomhangolásának listázása

A parancshoz API-verzió: 2024-05-01-preview vagy újabb szükséges.

Bár nem szükséges a finomhangolás elvégzése, hasznos lehet megvizsgálni a betanítás során létrehozott egyéni finomhangolási eseményeket. A teljes betanítási eredmények akkor is megvizsgálhatók, ha a betanítás befejeződött a betanítási eredmények fájljában.

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 kimenet:

{
  "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"
}

Ellenőrzőpontok listázása

A parancshoz API-verzió: 2024-05-01-preview vagy újabb szükséges.

Amikor minden betanítási korszak befejeződött, létrejön egy ellenőrzőpont. Az ellenőrzőpont egy modell teljes funkcionalitású verziója, amely üzembe helyezhető és célmodellként is használható a későbbi finomhangolási feladatokhoz. Az ellenőrzőpontok különösen hasznosak lehetnek, mivel a túlillesztés előtt pillanatképet adhatnak a modellről. Ha egy finomhangolási feladat befejeződik, a modell három legújabb verziója lesz üzembe helyezhető. Az utolsó korszakot a finomhangolt modell képviseli, az előző két korszak pedig ellenőrzőpontokként lesz elérhető.

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

Python 1.x kimenet:

{
  "data": [
    {
      "id": "ftchkpt-148ab69f0a404cf9ab55a73d51b152de",
      "created_at": 1715743077,
      "fine_tuned_model_checkpoint": "gpt-35-turbo-0613.ft-372c72db22c34e6f9ccb62c26ee0fbd9",
      "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-35-turbo-0613.ft-372c72db22c34e6f9ccb62c26ee0fbd9: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-35-turbo-0613.ft-372c72db22c34e6f9ccb62c26ee0fbd9: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"
}

Utolsó betanítási futtatási eredmények

A végső eredmények lekéréséhez futtassa a következőt:

# 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

Finomhangolt modell üzembe helyezése

Az oktatóanyag korábbi Python SDK-parancsaival ellentétben a kvótafunkció bevezetése óta a modell üzembe helyezését a REST API használatával kell elvégezni, amely külön engedélyezést, egy másik API-útvonalat és egy másik API-verziót igényel.

Másik lehetőségként üzembe helyezheti a finomhangolt modellt az egyéb gyakori üzembehelyezési módszerek bármelyikével, például az Azure OpenAI Studióval vagy az Azure CLI-vel.

változó Definíció
jogkivonat Az engedélyezési jogkivonatok többféleképpen is létrehozhatóak. A kezdeti tesztelés legegyszerűbb módja a Cloud Shell elindítása az Azure Portalról. Ez után futtassa a az account get-access-token parancsot. Ezt a jogkivonatot használhatja ideiglenes engedélyezési jogkivonatként API-teszteléshez. Javasoljuk, hogy ezt egy új környezeti változóban tárolja
előfizetést A társított Azure OpenAI-erőforrás előfizetés-azonosítója
resource_group Az Azure OpenAI-erőforrás erőforráscsoportjának neve
resource_name Az Azure OpenAI-erőforrás neve
model_deployment_name Az új, finomhangolt modell üzembe helyezésének egyéni neve. Ez a név lesz hivatkozva a kódban a csevegés befejezésére irányuló hívások során.
fine_tuned_model Kérje le ezt az értéket a finomhangolási feladat eredményéből az előző lépésben. Úgy fog kinézni gpt-35-turbo-0613.ft-b044a9d3cf9c4228b5d393567f693b83. Ezt az értéket hozzá kell adnia a deploy_data jsonhoz.

Fontos

Ha a testreszabott modell üzembe helyezése után az üzembe helyezés 15 napnál hosszabb ideig inaktív marad, a rendszer törli az üzembe helyezést. A testreszabott modell üzembe helyezése inaktív , ha a modell több mint tizenöt (15) nappal ezelőtt lett üzembe helyezve, és a folyamatos 15 napos időszakban nem történt befejezési vagy csevegés-befejezési hívás.

Az inaktív üzemelő példány törlése nem törli vagy befolyásolja az alapul szolgáló testreszabott modellt, és a testre szabott modell bármikor újra üzembe helyezhető. Az Azure OpenAI szolgáltatás díjszabásában leírtaknak megfelelően minden telepített testre szabott (finomhangolt) modell óránkénti üzemeltetési költséget okoz, függetlenül attól, hogy a modellhez befejezési vagy csevegés-befejezési hívásokat végeznek-e. Ha többet szeretne megtudni a költségek Azure OpenAI-val való tervezéséről és kezeléséről, tekintse meg az Azure OpenAI szolgáltatás költségeinek kezelésére vonatkozó terv útmutatóját.

# 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 = "YOUR_CUSTOM_MODEL_DEPLOYMENT_NAME"

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-35-turbo-0613.ft-b044a9d3cf9c4228b5d393567f693b83
            "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())

Az üzembe helyezés előrehaladását az Azure OpenAI Studióban ellenőrizheti:

Képernyőkép a CSV-fájlból származó kezdeti DataFrame-tábla eredményeiről.

Nem ritka, hogy ez a folyamat egy kis időt vesz igénybe a finomhangolt modellek üzembe helyezésekor.

Üzembe helyezett testreszabott modell használata

A finomhangolt modell üzembe helyezése után az Azure OpenAI Studio csevegőterében vagy a csevegést befejező API-n keresztül bármely más üzembe helyezett modellhez hasonlóan használhatja. Küldhet például egy csevegővégzítési hívást az üzembe helyezett modellnek, ahogy az a következő Python-példában is látható. Továbbra is ugyanazokat a paramétereket használhatja a testre szabott modellel, például a hőmérséklettel és a max_tokens, mint más üzembe helyezett modellekkel.

# 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-02-01"
)

response = client.chat.completions.create(
    model = "gpt-35-turbo-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)

Üzembe helyezés törlése

Az Azure OpenAI-modellek más típusaitól eltérően a finomhangolt/testre szabott modellek az üzembe helyezés után óránkénti üzemeltetési költségekkel járnak. Erősen ajánlott, hogy ha végzett ezzel az oktatóanyaggal, és teszteljen néhány csevegés-befejezési hívást a finomhangolt modellen, törölje a modell üzembe helyezését.

Az üzembe helyezés törlése nem érinti magát a modellt, így bármikor újra üzembe helyezheti az oktatóanyaghoz betanított finomhangolt modellt.

Az üzembe helyezést az Azure OpenAI Studióban a REST API-val, az Azure CLI-vel vagy más támogatott üzembe helyezési módszerekkel törölheti.

Hibaelhárítás

Hogyan engedélyezi a finomhangolást? Egyéni modell létrehozása szürkítve lesz az Azure OpenAI Studióban?

A finomhangolás sikeres eléréséhez a Cognitive Services OpenAI-közreműködője van hozzárendelve. Még a magas szintű szolgáltatási Rendszergazda istrator engedélyekkel rendelkezőknek is szükségük lenne erre a fiókra kifejezetten a finomhangolás eléréséhez. További információkért tekintse át a szerepköralapú hozzáférés-vezérlési útmutatót.

Következő lépések

  • További információ az Azure OpenAI finomhangolásáról
  • További információ az Azure OpenAI-t használó mögöttes modellekről.