Tutorial penyempurnaan Azure OpenAI GPT-4o-mini
Tutorial ini memandikan Anda melalui penyempurnaan gpt-4o-mini-2024-07-18
model.
Dalam tutorial ini, Anda akan mempelajari cara:
- Buat sampel himpunan data penyempurnaan.
- Buat variabel lingkungan untuk titik akhir sumber daya dan kunci API Anda.
- Siapkan sampel himpunan data pelatihan dan validasi Anda untuk penyempurnaan.
- Unggah file pelatihan dan file validasi Anda untuk penyempurnaan.
- Buat pekerjaan penyempurnaan untuk
gpt-4o-mini-2024-07-18
. - Menyebarkan model kustom yang disempurnakan.
Prasyarat
- Langganan Azure - Buat langganan gratis.
- Python 3.8 atau versi yang lebih baru
- Pustaka Python berikut:
json
, ,requests
,os
,tiktoken
time
,openai
,numpy
. - Jupyter Notebooks
- Sumber daya Azure OpenAI di wilayah tempat
gpt-4o-mini-2024-07-18
penyempurnaan tersedia. Jika Anda tidak memiliki sumber daya, proses pembuatan sumber daya didokumentasikan dalam panduan penyebaran sumber daya kami. - Akses penyempurnaan memerlukan Kontributor OpenAI Cognitive Services.
- Jika Anda belum memiliki akses untuk melihat kuota dan menyebarkan model di portal Azure AI Foundry, maka Anda memerlukan lebih banyak izin.
Penting
Sebaiknya tinjau informasi harga untuk penyempurnaan untuk membiasakan diri dengan biaya terkait. Pengujian tutorial ini menghasilkan 48.000 token yang ditagih (4.800 token pelatihan * 10 epoch pelatihan). Biaya pelatihan selain biaya yang terkait dengan inferensi penyempurnaan, dan biaya hosting per jam untuk penyempurnaan model yang disempurnakan. Setelah menyelesaikan tutorial, Anda harus menghapus penyebaran model yang disempurnakan jika tidak, Anda terus dikenakan biaya hosting per jam.
Penyiapan
Pustaka Python
Tutorial ini memberikan contoh beberapa fitur OpenAI terbaru termasuk seed/events/checkpoints. Untuk memanfaatkan fitur-fitur ini, Anda mungkin perlu menjalankan pip install openai --upgrade
untuk meningkatkan ke rilis terbaru.
pip install openai requests tiktoken numpy
Mengambil kunci dan titik akhir
Agar berhasil melakukan panggilan terhadap Azure OpenAI, Anda memerlukan titik akhir dan kunci.
Nama variabel | Nilai |
---|---|
ENDPOINT |
Titik akhir layanan dapat ditemukan di bagian Kunci & Titik Akhir saat memeriksa sumber daya Anda dari portal Azure. Atau, Anda dapat menemukan titik akhir melalui halaman Penyebaran di portal Azure AI Foundry. Contoh titik akhir adalah: https://docs-test-001.openai.azure.com/ . |
API-KEY |
Nilai ini dapat ditemukan di bagian Kunci & Titik Akhir saat memeriksa sumber daya Anda dari portal Microsoft Azure. Anda dapat menggunakan KEY1 atau KEY2 . |
Buka sumber daya Anda di portal Azure. Bagian Kunci & Titik Akhir dapat ditemukan di bagian Manajemen Sumber Daya. Salin titik akhir dan kunci akses Anda karena keduanya diperlukan untuk mengautentikasi panggilan API Anda. Anda dapat menggunakan KEY1
atau KEY2
. Selalu miliki dua kunci untuk memungkinkan Anda memutar dan meregenerasi kunci dengan aman tanpa menyebabkan gangguan layanan.
Variabel lingkungan
Buat dan tetapkan variabel lingkungan persisten untuk kunci dan titik akhir Anda.
Penting
Gunakan kunci API dengan hati-hati. Jangan sertakan kunci API langsung dalam kode Anda, dan jangan pernah mempostingnya secara publik. Jika Anda menggunakan kunci API, simpan dengan aman di Azure Key Vault. Untuk informasi selengkapnya tentang menggunakan kunci API dengan aman di aplikasi Anda, lihat Kunci API dengan Azure Key Vault.
Untuk informasi selengkapnya tentang keamanan layanan AI, lihat Mengautentikasi permintaan ke layanan Azure AI.
setx AZURE_OPENAI_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx AZURE_OPENAI_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"
Membuat himpunan data sampel
Penyempurnaan gpt-4o-mini-2024-07-18
memerlukan file pelatihan JSONL yang diformat khusus. OpenAI memberikan contoh berikut dalam dokumentasi mereka:
{"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."}]}
Untuk contoh ini, kami mengubah ini sedikit dengan mengubah ke:
{"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."}]}
Meskipun ketiga contoh ini berguna untuk memberi Anda format umum, jika Anda ingin mengarahkan model kustom yang disempurnakan untuk merespons dengan cara yang sama, Anda akan membutuhkan lebih banyak contoh. Umumnya Anda ingin setidaknya 50 contoh berkualitas tinggi untuk memulai. Namun, sepenuhnya mungkin untuk memiliki kasus penggunaan yang mungkin memerlukan 1.000 contoh pelatihan berkualitas tinggi agar berhasil.
Secara umum, menggandakan ukuran himpunan data dapat menyebabkan peningkatan linier dalam kualitas model. Tetapi perlu diingat, contoh kualitas rendah dapat berdampak negatif pada performa. Jika Anda melatih model pada sejumlah besar data internal tanpa terlebih dahulu memangkas himpunan data hanya untuk contoh kualitas tertinggi, Anda dapat berakhir dengan model yang berkinerja lebih buruk dari yang diharapkan.
Anda harus membuat dua file training_set.jsonl
dan validation_set.jsonl
.
Buat file di direktori yang sama dengan yang Anda jalankan Jupyter Notebook, dan salin konten blok kode berikut ke file yang sesuai:
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 might 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?"}]}
Sekarang Anda perlu menjalankan beberapa pemeriksaan awal pada file pelatihan dan validasi kami.
# 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)
Output:
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!"}
Dalam hal ini kami hanya memiliki 10 pelatihan dan 10 contoh validasi sehingga sementara ini menunjukkan mekanisme dasar penyempurnaan model ini tidak mungkin menjadi sejumlah besar contoh untuk menghasilkan efek yang terlihat secara konsisten.
Sekarang Anda dapat menggunakan pustaka tiktoken untuk memvalidasi jumlah token. Penghitungan token menggunakan metode ini tidak akan memberi Anda jumlah token yang tepat yang digunakan untuk penyempurnaan, tetapi harus memberikan perkiraan yang baik.
Catatan
Contoh individual harus tetap berada gpt-4o-mini-2024-07-18
di bawah panjang konteks contoh pelatihan model saat ini: 64.536 token. Batas token input model tetap 128.000 token.
# 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)
Output:
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
****************************
Mengunggah file penyempurnaan
# 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)
Output:
Training file ID: file-0e3aa3f2e81e49a5b8b96166ea214626
Validation file ID: file-8556c3bb41b7416bb7519b47fcd1dd6b
Mulai menyempurnakan
Sekarang setelah file penyempurnaan berhasil diunggah, Anda dapat mengirimkan pekerjaan pelatihan penyempurnaan Anda:
Dalam contoh ini, kita juga meneruskan parameter benih. Seed mengontrol reproduktifitas pekerjaan. Meneruskan seed dan parameter pekerjaan yang sama harus menghasilkan hasil yang sama, tetapi dapat berbeda dalam kasus yang jarang terjadi. Jika benih tidak ditentukan, satu dibuat untuk Anda.
# 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))
Output Python 1.x:
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
}
Melacak status pekerjaan pelatihan
Jika Anda ingin melakukan polling status pekerjaan pelatihan hingga selesai, Anda dapat menjalankan:
# 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.')
Output Python 1.x:
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
}
Tidak biasa pelatihan membutuhkan waktu lebih dari satu jam untuk diselesaikan. Setelah pelatihan selesai, pesan output berubah menjadi sesuatu seperti:
Fine-tuning job ftjob-900fcfc7ea1d4360a9f0cb1697b4eaa6 finished with status: succeeded
Checking other fine-tune jobs for this resource.
Found 4 fine-tune jobs.
Mencantumkan peristiwa penyempurnaan
Versi API: 2024-08-01-preview
atau yang lebih baru diperlukan untuk perintah ini.
Meskipun tidak perlu menyelesaikan penyempurnaan, akan sangat membantu untuk memeriksa peristiwa penyempurnaan individu yang dihasilkan selama pelatihan. Hasil pelatihan lengkap juga dapat diperiksa setelah pelatihan selesai dalam file hasil pelatihan.
response = client.fine_tuning.jobs.list_events(fine_tuning_job_id=job_id, limit=10)
print(response.model_dump_json(indent=2))
Output Python 1.x:
{
"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"
}
Mencantumkan titik pemeriksaan
Versi API: 2024-08-01-preview
atau yang lebih baru diperlukan untuk perintah ini.
Ketika setiap epoch pelatihan menyelesaikan titik pemeriksaan dihasilkan. Titik pemeriksaan adalah versi model yang berfungsi penuh yang dapat disebarkan dan digunakan sebagai model target untuk pekerjaan penyempurnaan berikutnya. Titik pemeriksaan dapat berguna, karena dapat menyediakan rekam jepret model Anda sebelum overfitting terjadi. Saat pekerjaan penyempurnaan selesai, Anda memiliki tiga versi terbaru dari model yang tersedia untuk disebarkan. Epoch akhir akan diwakili oleh model yang disempurnakan, dua epoch sebelumnya tersedia sebagai titik pemeriksaan.
response = client.fine_tuning.jobs.checkpoints.list(job_id)
print(response.model_dump_json(indent=2))
Output Python 1.x:
{
"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"
}
Hasil eksekusi pelatihan akhir
Untuk mendapatkan hasil akhir, jalankan hal berikut:
# 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
Menyebarkan model yang disempurnakan
Tidak seperti perintah Python SDK sebelumnya dalam tutorial ini, karena pengenalan fitur kuota, penyebaran model harus dilakukan menggunakan REST API, yang memerlukan otorisasi terpisah, jalur API yang berbeda, dan versi API yang berbeda.
Atau, Anda dapat menyebarkan model yang disempurnakan menggunakan salah satu metode penyebaran umum lainnya seperti portal Azure AI Foundry, atau Azure CLI.
variabel | Definisi |
---|---|
token | Ada beberapa cara untuk menghasilkan token otorisasi. Metode term mudah untuk pengujian awal adalah meluncurkan Cloud Shell dari portal Azure. Kemudian jalankan az account get-access-token . Anda dapat menggunakan token ini sebagai token otorisasi sementara untuk pengujian API. Sebaiknya simpan ini dalam variabel lingkungan baru |
langganan | ID langganan untuk sumber daya Azure OpenAI terkait |
resource_group | Nama grup sumber daya untuk sumber daya Azure OpenAI Anda |
resource_name | Nama sumber daya Azure OpenAI |
model_deployment_name | Nama kustom untuk penyebaran model baru yang disempurnakan. Ini adalah nama yang direferensikan dalam kode Anda saat melakukan panggilan penyelesaian obrolan. |
fine_tuned_model | Ambil nilai ini dari pekerjaan penyempurnaan Anda menghasilkan langkah sebelumnya. Rutenya terlihat seperti gpt-4o-mini-2024-07-18.ft-0e208cf33a6a466994aff31a08aba678 . Anda perlu menambahkan nilai tersebut ke json deploy_data. |
Penting
Setelah Anda menyebarkan model yang disesuaikan, jika kapan saja penyebaran tetap tidak aktif selama lebih dari lima belas (15) hari, penyebaran akan dihapus. Penyebaran model yang disesuaikan tidak aktif jika model disebarkan lebih dari lima belas (15) hari yang lalu dan tidak ada penyelesaian atau panggilan penyelesaian obrolan yang dilakukan padanya selama periode 15 hari berkelanjutan.
Penghapusan penyebaran yang tidak aktif tidak menghapus atau memengaruhi model yang dikustomisasi yang mendasar, dan model yang disesuaikan dapat disebarkan ulang kapan saja. Seperti yang dijelaskan dalam harga Azure OpenAI Service, setiap model yang disesuaikan (disempurnakan) yang disebarkan menimbulkan biaya hosting per jam terlepas dari apakah penyelesaian atau panggilan penyelesaian obrolan sedang dilakukan ke model. Untuk mempelajari selengkapnya tentang merencanakan dan mengelola biaya dengan Azure OpenAI, lihat panduan dalam Rencanakan untuk mengelola biaya untuk 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())
Anda dapat memeriksa kemajuan penyebaran di portal Azure AI Foundry.
Tidak jarang proses ini membutuhkan waktu untuk diselesaikan saat berhadapan dengan penyebaran model yang disempurnakan.
Menggunakan model yang disesuaikan yang disebarkan
Setelah model yang disempurnakan disebarkan, Anda dapat menggunakannya seperti model lain yang disebarkan di Chat Playground portal Azure AI Foundry, atau melalui API penyelesaian obrolan. Misalnya, Anda dapat mengirim panggilan penyelesaian obrolan ke model yang disebarkan, seperti yang ditunjukkan dalam contoh Python berikut. Anda dapat terus menggunakan parameter yang sama dengan model yang disesuaikan, seperti suhu dan max_tokens, seperti yang Anda bisa dengan model lain yang disebarkan.
# 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)
Menghapus penyebaran
Tidak seperti jenis model Azure OpenAI lainnya, model yang disempurnakan/disesuaikan memiliki biaya hosting per jam yang terkait dengannya setelah disebarkan. Sangat disarankan bahwa setelah Anda selesai dengan tutorial ini dan telah menguji beberapa panggilan penyelesaian obrolan terhadap model yang disempurnakan, anda menghapus penyebaran model.
Menghapus penyebaran tidak akan memengaruhi model itu sendiri, sehingga Anda dapat menyebarkan kembali model yang disempurnakan yang Anda latih untuk tutorial ini kapan saja.
Anda dapat menghapus penyebaran di portal Azure AI Foundry, melalui REST API, Azure CLI, atau metode penyebaran lain yang didukung.
Pemecahan Masalah
Bagaimana cara mengaktifkan penyempurnaan? Buat model kustom berwarna abu-abu.
Agar berhasil mengakses penyempurnaan, Anda memerlukan Kontributor OpenAI Cognitive Services yang ditetapkan. Bahkan seseorang dengan izin Administrator Layanan tingkat tinggi masih memerlukan akun ini secara eksplisit diatur untuk mengakses penyempurnaan. Untuk informasi selengkapnya, harap tinjau panduan kontrol akses berbasis peran.
Langkah berikutnya
- Pelajari selengkapnya tentang penyempurnaan di Azure OpenAI
- Pelajari selengkapnya tentang model yang mendasari yang mendukung Azure OpenAI.