Aracılığıyla paylaş


Azure OpenAI GPT-3.5 Turbo ince ayar öğreticisi

Bu öğreticide modelde ince ayarlamalar gpt-35-turbo-0613 yapabilirsiniz.

Bu öğreticide şunların nasıl yapıldığını öğrenirsiniz:

  • Örnek ince ayar veri kümeleri oluşturun.
  • Kaynak uç noktanız ve API anahtarınız için ortam değişkenleri oluşturun.
  • Hassas ayarlamalar için örnek eğitim ve doğrulama veri kümelerinizi hazırlayın.
  • hassas ayarlama için eğitim dosyanızı ve doğrulama dosyanızı karşıya yükleyin.
  • için gpt-35-turbo-0613bir ince ayar işi oluşturun.
  • Özel bir ince ayarlı model dağıtın.

Önkoşullar

  • Azure aboneliği - Ücretsiz bir abonelik oluşturun.
  • İstenen Azure aboneliğinde Azure OpenAI'ye erişim verildi Şu anda bu hizmete erişim yalnızca uygulama tarafından verilir. adresinden formu https://aka.ms/oai/accesstamamlayarak Azure OpenAI'ye erişim için başvurabilirsiniz.
  • Python 3.8 veya üzeri sürüm
  • Aşağıdaki Python kitaplıkları: , , , , , time, openai. numpytiktokenosrequestsjson
  • Jupyter Notebook
  • İnce ayarlamanın kullanılabildiği gpt-35-turbo-0613bir bölgedeki Azure OpenAI kaynağı. Kaynağınız yoksa, kaynak dağıtım kılavuzumuzda kaynak oluşturma işlemi belgelenmiştir.
  • Erişimde ince ayar yapmak için Bilişsel Hizmetler OpenAI Katkıda Bulunanı gerekir.
  • Kotayı görüntüleme ve Azure OpenAI Studio'da modelleri dağıtma erişiminiz yoksa ek izinlere ihtiyacınız olacaktır.

Önemli

İlişkili maliyetleri rahatça karşıladığınızdan emin olmak için bu öğreticiye başlamadan önce ince ayar yapmak için fiyatlandırma bilgilerini gözden geçirmenizi kesinlikle öneririz. Testte bu öğreticide, ince ayar çıkarımıyla ilişkili maliyetlerin yanı sıra bir eğitim saati faturalandırıldı ve ince ayarlanmış bir modelin dağıtıldığı saatlik barındırma maliyetleri elde edildi. Öğreticiyi tamamladıktan sonra, hassas model dağıtımınızı silmeniz gerekir, aksi takdirde saatlik barındırma maliyetine maruz kalırsınız.

Ayarlama

Python kitaplıkları

Bu öğreticide, tohum/olaylar/denetim noktaları gibi en son OpenAI özelliklerinden bazıları verilmiştir. Bu özelliklerden yararlanmak için en son sürüme yükseltmek için komutunu çalıştırmanız pip install openai --upgrade gerekebilir.

pip install openai requests tiktoken numpy

Anahtarı ve uç noktayı alma

Azure OpenAI'ye karşı başarılı bir şekilde çağrı yapmak için bir uç nokta ve anahtar gerekir.

Değişken adı Değer
ENDPOINT Bu değer, Azure portal kaynağınızı incelerken Anahtarlar ve Uç Nokta bölümünde bulunabilir. Alternatif olarak, değeri Azure OpenAI Studio>Oyun Alanı>Kod Görünümü'nde bulabilirsiniz. Örnek uç nokta: https://docs-test-001.openai.azure.com/.
API-KEY Bu değer, Azure portal kaynağınızı incelerken Anahtarlar ve Uç Nokta bölümünde bulunabilir. KEY1 veya KEY2 kullanabilirsiniz.

Azure portalında kaynağınıza gidin. Anahtarlar ve Uç Nokta bölümü Kaynak Yönetimi bölümünde bulunabilir. Api çağrılarınızın kimliğini doğrulamak için ihtiyacınız olacak şekilde uç noktanızı ve erişim anahtarınızı kopyalayın. KEY1 veya KEY2 kullanabilirsiniz. Her zaman iki anahtara sahip olmak, hizmet kesintisine neden olmadan anahtarları güvenli bir şekilde döndürmenize ve yeniden oluşturmanıza olanak tanır.

Azure portalında uç nokta ve erişim anahtarları konumu kırmızıyla daire içine alınmış bir Azure OpenAI kaynağının genel bakış kullanıcı arabiriminin ekran görüntüsü.

Ortam değişkenleri

setx AZURE_OPENAI_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx AZURE_OPENAI_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"

Örnek veri kümesi oluşturma

hassas ayarlama gpt-35-turbo-0613 , özel olarak biçimlendirilmiş bir JSONL eğitim dosyası gerektirir. OpenAI belgelerinde aşağıdaki örneği sağlar:

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

Bu örnekte şu şekilde değiştirerek bunu biraz değiştireceğiz:

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

Bu üç örnek size genel biçimi vermek için yararlı olsa da, özel ince ayarlanmış modelinizi benzer şekilde yanıt verecek şekilde yönlendirmek istiyorsanız daha fazla örneğe ihtiyacınız olacaktır. Genellikle en az 50 yüksek kaliteli örneğin başlamasını istersiniz. Ancak, 1.000'lik yüksek kaliteli eğitim örneklerinin başarılı olmasını gerektirebilecek bir kullanım örneğine sahip olmak tamamen mümkündür.

Genel olarak, veri kümesi boyutunun iki katına çıkarılması model kalitesinde doğrusal bir artışa yol açabilir. Ancak düşük kaliteli örneklerin performansı olumsuz etkileyeebileceğini unutmayın. Modeli büyük miktarda iç veri üzerinde eğitirseniz, önce veri kümesini yalnızca en yüksek kaliteli örnekler için ayıklamadan beklenenden çok daha kötü performans gösteren bir modelle sonuçlanabilirsiniz.

ve validation_set.jsonlolmak üzere iki dosya training_set.jsonl oluşturmanız gerekir.

Jupyter Not Defteri'ni çalıştırdığınız dizinde dosyaları oluşturun ve aşağıdaki kod bloklarının içeriğini ilgili dosyalara kopyalayın:

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

Şimdi eğitim ve doğrulama dosyalarımızda bazı ön denetimler çalıştırmanız gerekir.

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

Çıktı:

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

Bu durumda yalnızca 10 eğitim ve 10 doğrulama örneğimiz vardır, bu nedenle bu, tutarlı bir şekilde fark edilebilir bir etki oluşturmak için yeterince fazla sayıda örnek olma olasılığı düşük olan bir modelde ince ayarlamanın temel mekaniklerini gösterir.

Bundan sonra, belirteç sayılarını doğrulamak için tiktoken kitaplığını kullanarak OpenAI'den bazı ek kodlar çalıştırabilirsiniz. Tek tek örneklerin modelin gpt-35-turbo-0613 4096 belirteç giriş belirteci sınırı altında kalması gerekir.

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

Çıktı:

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
**************************************************

Hassas dosyaları karşıya yükleme

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

Çıktı:

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

hassas ayarlamaya başlama

Artık hassas ayarlama dosyaları başarıyla karşıya yüklendiğine göre, ince ayar eğitim işinizi gönderebilirsiniz:

Bu örnekte ayrıca seed parametresini de geçiriyoruz. Tohum, işin yeniden üretilebilirliğini denetler. Aynı tohum ve iş parametrelerinin geçirilmesi aynı sonuçları vermelidir, ancak nadir durumlarda farklılık gösterebilir. Bir tohum belirtilmezse sizin için bir tane oluşturulur.

# 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 Çıkışı:

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
}

Eğitim işi durumunu izleme

Tamamlanana kadar eğitim işinin durumunu yoklama yapmak isterseniz şunları çalıştırabilirsiniz:

# 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 Çıkışı:

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
}

Eğitimin tamamlanmasının bir saatten fazla sürmesi olağan dışı değildir. Eğitim tamamlandıktan sonra çıkış iletisi şuna benzer bir değere dönüşür:

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

İnce ayar olaylarını listeleme

Bu komut için API sürümü: 2024-05-01-preview veya üzeri gereklidir.

İnce ayarlamayı tamamlamak için gerekli olmasa da, eğitim sırasında oluşturulan tek tek ince ayar olaylarını incelemek yararlı olabilir. Eğitim sonuçları dosyasında eğitim tamamlandıktan sonra eğitim sonuçlarının tamamı da incelenebilir.

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 Çıkışı:

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

Denetim noktalarını listeleme

Bu komut için API sürümü: 2024-05-01-preview veya üzeri gereklidir.

Her eğitim dönemi tamamlandığında bir denetim noktası oluşturulur. Denetim noktası, modelin hem dağıtılabilen hem de sonraki hassas ayarlama işleri için hedef model olarak kullanılabilen tam işlevsel bir sürümüdür. Denetim noktaları, fazla uygunluk gerçekleşmeden önce modelinizin anlık görüntüsünü sağlayabildiği için özellikle yararlı olabilir. Bir ince ayar işi tamamlandığında, modelin dağıtabileceğiniz en son üç sürümüne sahip olursunuz. Son dönem, ince ayarlı modelinizle temsil edilir, önceki iki dönem kontrol noktası olarak kullanılabilir.

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

Python 1.x Çıkışı:

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

Son eğitim çalıştırması sonuçları

Son sonuçları almak için aşağıdakileri çalıştırın:

# 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

Hassas ayarlı modeli dağıtma

Bu öğreticideki önceki Python SDK komutlarından farklı olarak, kota özelliği kullanıma sunulduğundan, model dağıtımı ayrı yetkilendirme, farklı bir API yolu ve farklı bir API sürümü gerektiren REST API kullanılarak yapılmalıdır.

Alternatif olarak, Azure OpenAI Studio veya Azure CLI gibi diğer yaygın dağıtım yöntemlerinden herhangi birini kullanarak ince ayarlı modelinizi dağıtabilirsiniz.

değişken Tanım
token Yetkilendirme belirteci oluşturmanın birden çok yolu vardır. İlk test için en kolay yöntem, Cloud Shell'i Azure portalından başlatmaktır. Ardından az account get-access-token komutunu çalıştırın. Bu belirteci API testi için geçici yetkilendirme belirteciniz olarak kullanabilirsiniz. Bunu yeni bir ortam değişkeninde depolamanızı öneririz
aboneliği İlişkili Azure OpenAI kaynağının abonelik kimliği
resource_group Azure OpenAI kaynağınızın kaynak grubu adı
resource_name Azure OpenAI kaynak adı
model_deployment_name Yeni hassas model dağıtımınız için özel ad. Bu, sohbet tamamlama çağrıları yapılırken kodunuzda başvurulacak addır.
fine_tuned_model Önceki adımda ince ayar iş sonuçlarınızdan bu değeri alın. gibi gpt-35-turbo-0613.ft-b044a9d3cf9c4228b5d393567f693b83görünecektir. Bu değeri deploy_data json'a eklemeniz gerekir.

Önemli

Özelleştirilmiş bir modeli dağıttıktan sonra, herhangi bir zamanda dağıtım on beş (15) günden uzun süre etkin değilse dağıtım silinir. Model on beşten (15) gün önce dağıtıldıysa ve sürekli 15 günlük bir süre boyunca buna hiçbir tamamlama veya sohbet tamamlama çağrısı yapılmadıysa, özelleştirilmiş bir modelin dağıtımı devre dışı bırakılır.

Etkin olmayan bir dağıtımın silinmesi, temel alınan özelleştirilmiş modeli silmez veya etkilemez ve özelleştirilmiş model istediğiniz zaman yeniden dağıtılabilir. Azure OpenAI Hizmeti fiyatlandırmasında açıklandığı gibi, dağıtılan her özelleştirilmiş (ince ayarlı) model, modele tamamlama veya sohbet tamamlama çağrıları yapılıp yapılmamasına bakılmaksızın saatlik barındırma maliyetine neden olur. Azure OpenAI ile maliyetleri planlama ve yönetme hakkında daha fazla bilgi edinmek için Azure OpenAI Hizmeti maliyetlerini yönetmeyi planlama konusundaki kılavuza bakın.

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

Azure OpenAI Studio'da dağıtım ilerleme durumunuzu de kontrol edebilirsiniz:

CSV dosyasındaki ilk DataFrame tablosu sonuçlarının ekran görüntüsü.

Bu işlemin, ince ayarlı modeller dağıtılırken tamamlanması biraz zaman alması sık karşılaşılan bir durum değildir.

Dağıtılan özelleştirilmiş modeli kullanma

Hassas ayarlı modeliniz dağıtıldıktan sonra, Azure OpenAI Studio'nun Sohbet Oyun Alanı'nda veya sohbet tamamlama API'si aracılığıyla diğer dağıtılan modellerde olduğu gibi kullanabilirsiniz. Örneğin, aşağıdaki Python örneğinde gösterildiği gibi dağıtılan modelinize sohbet tamamlama çağrısı gönderebilirsiniz. Özelleştirilmiş modelinizle sıcaklık ve max_tokens gibi, dağıtılan diğer modellerde olduğu gibi aynı parametreleri kullanmaya devam edebilirsiniz.

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

Dağıtımı silme

Diğer Azure OpenAI modellerinden farklı olarak, ince ayarlı/özelleştirilmiş modellerin dağıtıldıktan sonra bunlarla ilişkili saatlik barındırma maliyeti vardır. Bu öğreticiyi tamamladıktan ve ince ayarlı modelinizde birkaç sohbet tamamlama çağrısını test ettikten sonra model dağıtımını silmeniz kesinlikle önerilir.

Dağıtımın silinmesi modelin kendisini etkilemez, bu nedenle bu öğretici için eğitmiş olduğunuz ince ayarlı modeli istediğiniz zaman yeniden dağıtabilirsiniz.

Azure OpenAI Studio'daki dağıtımı REST API, Azure CLI veya desteklenen diğer dağıtım yöntemleri aracılığıyla silebilirsiniz.

Sorun giderme

İnce ayarlamayı Nasıl yaparım? etkinleştirebilirsiniz? Azure OpenAI Studio'da özel model oluşturma işlemi gri mi?

Hassas ayarlamalara başarıyla erişmek için Bilişsel Hizmetler OpenAI Katkıda Bulunanı'nın atanması gerekir. Üst düzey Hizmet Yönetici istrator izinlerine sahip birinin bile ince ayara erişmek için bu hesabın açıkça ayarlanması gerekir. Daha fazla bilgi için rol tabanlı erişim denetimi kılavuzunu gözden geçirin.

Sonraki adımlar

  • Azure OpenAI'de ince ayarlama hakkında daha fazla bilgi edinin
  • Azure OpenAI'yi destekleyen temel modeller hakkında daha fazla bilgi edinin.