البرنامج التعليمي لضبط Azure OpenAI GPT-3.5 Turbo

يرشدك هذا البرنامج التعليمي من خلال ضبط gpt-35-turbo-0613 نموذج.

في هذا البرنامج التعليمي، ستتعرف على كيفية القيام بما يلي:

  • إنشاء عينة من مجموعات بيانات الضبط الدقيق.
  • إنشاء متغيرات البيئة لنقطة نهاية المورد ومفتاح API.
  • قم بإعداد نماذج مجموعات بيانات التدريب والتحقق من الصحة للضبط الدقيق.
  • قم بتحميل ملف التدريب وملف التحقق من الصحة للضبط الدقيق.
  • إنشاء مهمة ضبط ل gpt-35-turbo-0613.
  • انشر نموذجا مخصصا مضبوطا.

المتطلبات الأساسية

  • اشتراك Azure - أنشئ اشتراكاً مجاناً.
  • الوصول الممنوح إلى Azure OpenAI في اشتراك Azure المطلوب حاليا، يتم منح الوصول إلى هذه الخدمة فقط بواسطة التطبيق. يمكنك التقدم بطلب للوصول إلى Azure OpenAI عن طريق إكمال النموذج في https://aka.ms/oai/access.
  • Python 3.8 أو إصدار أحدث
  • مكتبات Python التالية: json، requests، os، tiktoken، time، ، openai. numpy
  • يجب أن تكون مكتبة OpenAI Python على الأقل إصدارا: 0.28.1.
  • Jupyter Notebooks
  • مورد Azure OpenAI في منطقة تتوفر فيها gpt-35-turbo-0613 الضبط الدقيق. إذا لم يكن لديك مورد، يتم توثيق عملية إنشاء مورد في دليل توزيع الموارد.
  • يتطلب الوصول الدقيق إلى Cognitive Services OpenAI Contributor.
  • إذا لم يكن لديك حق الوصول بالفعل لعرض الحصة النسبية، ونشر النماذج في Azure OpenAI Studio، فستتطلب أذونات إضافية.

هام

نوصي بشدة بمراجعة معلومات التسعير للضبط الدقيق قبل بدء هذا البرنامج التعليمي للتأكد من أنك مرتاح للتكاليف المرتبطة. في الاختبار، أدى هذا البرنامج التعليمي إلى فوترة ساعة تدريب واحدة، بالإضافة إلى التكاليف المرتبطة بالاستدلال على الضبط الدقيق، وتكاليف الاستضافة بالساعة لنشر نموذج دقيق. بمجرد الانتهاء من البرنامج التعليمي، يجب حذف نشر النموذج المضبط الخاص بك وإلا ستستمر في تحمل تكلفة الاستضافة كل ساعة.

الإعداد

مكتبات Python

pip install openai requests tiktoken numpy

قم باسترداد المفتاح ونقطة النهاية

لإجراء مكالمة بنجاح مقابل Azure OpenAI، تحتاج إلى نقطة نهاية ومفتاح.

اسم المتغير القيمة‬
ENDPOINT يمكن العثور على هذه القيمة في قسم المفاتيح ونقطة النهاية عند فحص المورد من مدخل Microsoft Azure. بدلاً من ذلك، يمكنك العثور على القيمة في Azure OpenAI Studio>Playground>Code View. مثال على نقطة النهاية هو: https://docs-test-001.openai.azure.com/.
API-KEY يمكن العثور على هذه القيمة في قسم المفاتيح ونقطة النهاية عند فحص المورد من مدخل Microsoft Azure. يمكنك استخدام إما KEY1 أو KEY2.

انتقل إلى مجموعة الموارد في مدخل Microsoft Azure. يمكن العثور على قسم Keys & Endpoint في قسم Resource Management . انسخ نقطة النهاية ومفتاح الوصول حيث ستحتاج إلى كليهما لمصادقة استدعاءات واجهة برمجة التطبيقات. يمكنك استخدام إما KEY1 أو KEY2. يسمح لك وجود مفتاحين دائماً بتدوير المفاتيح وإعادة إنشائها بأمان دون التسبب في تعطيل الخدمة.

لقطة شاشة لواجهة مستخدم النظرة العامة لمورد Azure OpenAI في مدخل Microsoft Azure مع وضع نقطة النهاية وموقع مفاتيح الوصول في دائرة باللون الأحمر.

متغيرات البيئة

setx AZURE_OPENAI_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx AZURE_OPENAI_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"

إنشاء عينة مجموعة بيانات

يتطلب الضبط gpt-35-turbo-0613 الدقيق ملف تدريب JSONL منسق خصيصا. يوفر OpenAI المثال التالي في وثائقهم:

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

في هذا المثال، سنقوم بتعديل هذا قليلا عن طريق التغيير إلى:

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

في حين أن هذه الأمثلة الثلاثة مفيدة لإعطائك التنسيق العام، إذا كنت تريد توجيه النموذج المخصص المضبط للاستجابة بطريقة مماثلة، فستحتاج إلى المزيد من الأمثلة. بشكل عام تريد أن يبدأ ما لا يقل عن 50 مثالا عالي الجودة. ومع ذلك، من الممكن تماما أن يكون لديك حالة استخدام قد تتطلب 1000 من أمثلة التدريب عالية الجودة لتكون ناجحة.

بشكل عام، يمكن أن يؤدي مضاعفة حجم مجموعة البيانات إلى زيادة خطية في جودة النموذج. ولكن ضع في اعتبارك أن الأمثلة منخفضة الجودة يمكن أن تؤثر سلبا على الأداء. إذا قمت بتدريب النموذج على كمية كبيرة من البيانات الداخلية، دون اقتطاع مجموعة البيانات أولا للحصول على أمثلة عالية الجودة فقط، فقد ينتهي بك الأمر بنموذج يعمل بشكل أسوأ بكثير من المتوقع.

ستحتاج إلى إنشاء ملفين training_set.jsonl و validation_set.jsonl.

قم بإنشاء الملفات في نفس الدليل الذي تقوم بتشغيل دفتر ملاحظات Jupyter، وانسخ محتويات كتل التعليمات البرمجية التالية إلى الملفات المقابلة:

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

الآن تحتاج إلى تشغيل بعض الفحوصات الأولية على ملفات التدريب والتحقق من الصحة لدينا.

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

إخراج:

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

في هذه الحالة لدينا فقط 10 تدريب و 10 أمثلة للتحقق من الصحة، لذلك في حين أن هذا سيوضح الميكانيكا الأساسية لضبط نموذج من غير المرجح أن يكون هذا عددا كبيرا بما يكفي من الأمثلة لإنتاج تأثير ملحوظ باستمرار.

الآن يمكنك بعد ذلك تشغيل بعض التعليمات البرمجية الإضافية من OpenAI باستخدام مكتبة tiktoken للتحقق من صحة عدد الرموز المميزة. يجب أن تظل الأمثلة الفردية ضمن gpt-35-turbo-0613 حد رمز الإدخال المميز للنموذج وهو 4096 رمزا مميزا.

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

إخراج:

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

تحميل ملفات ضبط دقيقة

# 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-02-01"  # This API version or later is required to access fine-tuning for turbo/babbage-002/davinci-002
)

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)

إخراج:

Training file ID: file-9ace76cb11f54fdd8358af27abf4a3ea
Validation file ID: file-70a3f525ed774e78a77994d7a1698c4b

بدء الضبط الدقيق

الآن بعد أن تم تحميل ملفات الضبط بنجاح، يمكنك إرسال مهمة التدريب على الضبط الدقيق:

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

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

إخراج:

Job ID: ftjob-40e78bc022034229a6e3a222c927651c
Status: pending
{
  "hyperparameters": {
    "n_epochs": 2
  },
  "status": "pending",
  "model": "gpt-35-turbo-0613",
  "training_file": "file-90ac5d43102f4d42a3477fd30053c758",
  "validation_file": "file-e21aad7dddbc4ddc98ba35c790a016e5",
  "id": "ftjob-40e78bc022034229a6e3a222c927651c",
  "created_at": 1697156464,
  "updated_at": 1697156464,
  "object": "fine_tuning.job"
}

تعقب حالة مهمة التدريب

إذا كنت ترغب في الاستقصاء عن حالة وظيفة التدريب حتى تكتمل، يمكنك تشغيل:

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

إخراج:

{
    "hyperparameters": {
        "n_epochs": 2
    },
    "status": "running",
    "model": "gpt-35-turbo-0613",
    "training_file": "file-9ace76cb11f54fdd8358af27abf4a3ea",
    "validation_file": "file-70a3f525ed774e78a77994d7a1698c4b",
    "id": "ftjob-0f4191f0c59a4256b7a797a3d9eed219",
    "created_at": 1695307968,
    "updated_at": 1695310376,
    "object": "fine_tuning.job"
}
Elapsed time: 40 minutes 45 seconds
Status: running

ليس من غير المعتاد أن يستغرق التدريب أكثر من ساعة لإكماله. بمجرد اكتمال التدريب، ستتغير رسالة الإخراج إلى:

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

للحصول على النتائج الكاملة، قم بتشغيل ما يلي:

# 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

توزيع نموذج مضبط بدقة

على عكس أوامر Python SDK السابقة في هذا البرنامج التعليمي، منذ إدخال ميزة الحصة النسبية، يجب أن يتم نشر النموذج باستخدام واجهة برمجة تطبيقات REST، والتي تتطلب تخويلا منفصلا، ومسار API مختلفا، وإصدار API مختلفا.

بدلا من ذلك، يمكنك نشر النموذج المضبط باستخدام أي من أساليب النشر الشائعة الأخرى مثل Azure OpenAI Studio أو Azure CLI.

المتغير التعريف
الرمز المميز هناك طرق متعددة لإنشاء رمز مميز للتخويل. أسهل طريقة للاختبار الأولي هي تشغيل Cloud Shell من مدخل Microsoft Azure. ثم شغّل az account get-access-token. يمكنك استخدام هذا الرمز المميز كرمز تخويل مؤقت لاختبار واجهة برمجة التطبيقات. نوصي بتخزين هذا في متغير بيئة جديد
الاشتراك معرف الاشتراك لمورد Azure OpenAI المقترن
مجموعة الموارد اسم مجموعة الموارد لمورد Azure OpenAI
resource_name اسم مورد Azure OpenAI
model_deployment_name الاسم المخصص لنشر النموذج الجديد الذي تم ضبطه. هذا هو الاسم الذي سيتم الرجوع إليه في التعليمات البرمجية الخاصة بك عند إجراء مكالمات إكمال الدردشة.
fine_tuned_model استرداد هذه القيمة من نتائج مهمة الضبط الدقيقة في الخطوة السابقة. سيكون شكلها على هذا النحوgpt-35-turbo-0613.ft-b044a9d3cf9c4228b5d393567f693b83. ستحتاج إلى إضافة هذه القيمة إلى deploy_data json.

هام

بعد نشر نموذج مخصص، إذا ظل النشر غير نشط في أي وقت لأكثر من خمسة عشر (15) يوما، يتم حذف النشر. يعد نشر نموذج مخصص غير نشط إذا تم نشر النموذج منذ أكثر من خمسة عشر (15) يوما ولم يتم إجراء أي مكالمات إكمال أو إكمال دردشة إليه خلال فترة 15 يوما مستمرة.

لا يؤدي حذف التوزيع غير النشط إلى حذف النموذج المخصص الأساسي أو التأثير عليه، ويمكن إعادة نشر النموذج المخصص في أي وقت. كما هو موضح في تسعير خدمة Azure OpenAI، يتحمل كل نموذج مخصص (تم ضبطه بدقة) يتم نشره تكلفة استضافة كل ساعة بغض النظر عما إذا كان يتم إجراء مكالمات إكمال أو إكمال الدردشة إلى النموذج. لمعرفة المزيد حول تخطيط التكاليف وإدارتها باستخدام Azure OpenAI، راجع الإرشادات الواردة في خطة لإدارة تكاليف خدمة Azure OpenAI.

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

لقطة شاشة لنتائج جدول DataFrame الأولي من ملف CSV.

ليس من غير المألوف أن تستغرق هذه العملية بعض الوقت لإكمالها عند التعامل مع نشر نماذج دقيقة.

استخدام نموذج مخصص منشور

بعد نشر النموذج الذي تم ضبطه بدقة، يمكنك استخدامه مثل أي نموذج آخر تم نشره إما في Chat Playground من Azure OpenAI Studio، أو عبر واجهة برمجة تطبيقات إكمال الدردشة. على سبيل المثال، يمكنك إرسال مكالمة إكمال دردشة إلى النموذج المنشور، كما هو موضح في مثال Python التالي. يمكنك الاستمرار في استخدام نفس المعلمات مع النموذج المخصص، مثل درجة الحرارة max_tokens، كما يمكنك مع النماذج الأخرى المنشورة.

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

حذف النشر

على عكس الأنواع الأخرى من نماذج Azure OpenAI، تتمتع النماذج الدقيقة/المخصصة بتكلفة استضافة كل ساعة مقترنة بها بمجرد نشرها. يوصى بشدة أنه بمجرد الانتهاء من هذا البرنامج التعليمي واختبار بعض مكالمات إكمال الدردشة مقابل النموذج الذي تم ضبطه، يمكنك حذف نشر النموذج.

لن يؤثر حذف التوزيع على النموذج نفسه، لذلك يمكنك إعادة نشر النموذج المضبط الذي قمت بتدريبه لهذا البرنامج التعليمي في أي وقت.

يمكنك حذف النشر في Azure OpenAI Studio، عبر واجهة برمجة تطبيقات REST أو Azure CLI أو أساليب النشر المدعومة الأخرى.

استكشاف الأخطاء وإصلاحها

كيف أعمل تمكين الضبط الدقيق؟ هل تم تعطيل إنشاء نموذج مخصص في Azure OpenAI Studio؟

من أجل الوصول بنجاح إلى الضبط الدقيق، تحتاج إلى تعيين مساهم OpenAI للخدمات المعرفية. حتى شخص ما بأذونات مسؤول istrator للخدمة عالية المستوى سيظل بحاجة إلى تعيين هذا الحساب بشكل صريح للوصول إلى الضبط الدقيق. لمزيد من المعلومات، يرجى مراجعة إرشادات التحكم في الوصول المستندة إلى الدور.

الخطوات التالية