- Spec files
pypi-openai
Describes: pkg:pypi/openai@1.106.x
- Description
- Official Python library for the OpenAI API providing chat completions, embeddings, audio, images, and more
- Author
- tessl
- Last updated
fine-tuning.md docs/
1# Fine-tuning23Create and manage custom model training jobs to adapt OpenAI models to specific use cases and domains with your own data.45## Capabilities67### Fine-tuning Jobs89Create and manage fine-tuning jobs to customize models for specific tasks and domains.1011```python { .api }12def create(13self,14*,15model: Union[str, FineTuningModel],16training_file: str,17hyperparameters: HyperparametersParam | NotGiven = NOT_GIVEN,18suffix: str | NotGiven = NOT_GIVEN,19validation_file: str | NotGiven = NOT_GIVEN,20integrations: List[IntegrationParam] | NotGiven = NOT_GIVEN,21seed: int | NotGiven = NOT_GIVEN,22extra_headers: Headers | None = None,23extra_query: Query | None = None,24extra_body: Body | None = None,25timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN26) -> FineTuningJob: ...2728def list(29self,30*,31after: str | NotGiven = NOT_GIVEN,32limit: int | NotGiven = NOT_GIVEN,33extra_headers: Headers | None = None,34extra_query: Query | None = None,35extra_body: Body | None = None,36timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN37) -> SyncPage[FineTuningJob]: ...3839def retrieve(40self,41fine_tuning_job_id: str,42*,43extra_headers: Headers | None = None,44extra_query: Query | None = None,45extra_body: Body | None = None,46timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN47) -> FineTuningJob: ...4849def cancel(50self,51fine_tuning_job_id: str,52*,53extra_headers: Headers | None = None,54extra_query: Query | None = None,55extra_body: Body | None = None,56timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN57) -> FineTuningJob: ...58```5960Usage examples:6162```python63from openai import OpenAI6465client = OpenAI()6667# Basic fine-tuning job68fine_tuning_job = client.fine_tuning.jobs.create(69training_file="file-abc123",70model="gpt-3.5-turbo-0125"71)7273print(f"Fine-tuning job created: {fine_tuning_job.id}")74print(f"Status: {fine_tuning_job.status}")75print(f"Model: {fine_tuning_job.model}")7677# Fine-tuning with custom hyperparameters78fine_tuning_job = client.fine_tuning.jobs.create(79training_file="file-abc123",80validation_file="file-def456",81model="gpt-3.5-turbo-0125",82hyperparameters={83"n_epochs": 3,84"batch_size": "auto",85"learning_rate_multiplier": "auto"86},87suffix="my-custom-model"88)8990print(f"Custom fine-tuning job: {fine_tuning_job.id}")9192# List all fine-tuning jobs93jobs = client.fine_tuning.jobs.list(limit=10)9495print("Recent fine-tuning jobs:")96for job in jobs:97print(f" {job.id}: {job.status} - {job.fine_tuned_model or 'In progress'}")9899# Retrieve specific job100job_id = "ftjob-abc123"101job = client.fine_tuning.jobs.retrieve(job_id)102103print(f"Job details:")104print(f" ID: {job.id}")105print(f" Status: {job.status}")106print(f" Model: {job.model}")107print(f" Fine-tuned model: {job.fine_tuned_model}")108print(f" Created: {job.created_at}")109print(f" Training file: {job.training_file}")110111# Cancel running job112if job.status in ["running", "queued"]:113cancelled_job = client.fine_tuning.jobs.cancel(job_id)114print(f"Job cancelled: {cancelled_job.status}")115```116117### Job Events and Monitoring118119Track fine-tuning progress through job events and status monitoring.120121```python { .api }122def list_events(123self,124fine_tuning_job_id: str,125*,126after: str | NotGiven = NOT_GIVEN,127limit: int | NotGiven = NOT_GIVEN,128extra_headers: Headers | None = None,129extra_query: Query | None = None,130extra_body: Body | None = None,131timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN132) -> SyncPage[FineTuningJobEvent]: ...133```134135Usage examples:136137```python138import time139140# Monitor fine-tuning job progress141def monitor_fine_tuning_job(job_id: str):142"""Monitor a fine-tuning job until completion"""143144print(f"Monitoring job {job_id}...")145146while True:147job = client.fine_tuning.jobs.retrieve(job_id)148print(f"Status: {job.status}")149150if job.status in ["succeeded", "failed", "cancelled"]:151print(f"Job finished with status: {job.status}")152if job.status == "succeeded":153print(f"Fine-tuned model: {job.fine_tuned_model}")154break155156# Wait before checking again157time.sleep(30)158159return job160161# Monitor job162job_id = "ftjob-abc123"163final_job = monitor_fine_tuning_job(job_id)164165# Get job events for detailed progress166events = client.fine_tuning.jobs.list_events(job_id, limit=50)167168print(f"\nJob events:")169for event in events:170print(f" [{event.created_at}] {event.level}: {event.message}")171172# Get recent events only173recent_events = client.fine_tuning.jobs.list_events(174job_id,175limit=10176)177178print(f"\nRecent events:")179for event in recent_events:180print(f" {event.message}")181182# Real-time event streaming (polling)183def stream_job_events(job_id: str, poll_interval: int = 10):184"""Stream job events in real-time"""185186last_event_id = None187188while True:189job = client.fine_tuning.jobs.retrieve(job_id)190191# Get new events192if last_event_id:193events = client.fine_tuning.jobs.list_events(194job_id,195after=last_event_id,196limit=100197)198else:199events = client.fine_tuning.jobs.list_events(200job_id,201limit=10202)203204# Process new events205for event in reversed(list(events)):206print(f"[{job.id}] {event.level}: {event.message}")207last_event_id = event.id208209# Check if job is complete210if job.status in ["succeeded", "failed", "cancelled"]:211print(f"Job completed with status: {job.status}")212break213214time.sleep(poll_interval)215216# Stream events217# stream_job_events("ftjob-abc123")218```219220### Training Data Preparation221222Prepare and validate training data for optimal fine-tuning results.223224Usage examples:225226```python227import json228from typing import List, Dict, Any229230def prepare_chat_training_data(conversations: List[Dict]) -> str:231"""Convert conversations to JSONL format for fine-tuning"""232233jsonl_data = []234235for conversation in conversations:236# Ensure proper chat format237if "messages" not in conversation:238# Convert simple Q&A to chat format239if "input" in conversation and "output" in conversation:240messages = [241{"role": "user", "content": conversation["input"]},242{"role": "assistant", "content": conversation["output"]}243]244else:245continue246else:247messages = conversation["messages"]248249# Validate message format250valid_conversation = {"messages": []}251252for message in messages:253if "role" in message and "content" in message:254if message["role"] in ["system", "user", "assistant"]:255valid_conversation["messages"].append({256"role": message["role"],257"content": str(message["content"])258})259260# Only include conversations with at least user+assistant261if len(valid_conversation["messages"]) >= 2:262jsonl_data.append(valid_conversation)263264# Write to JSONL file265filename = "training_data.jsonl"266with open(filename, 'w') as f:267for item in jsonl_data:268f.write(json.dumps(item) + '\n')269270print(f"Prepared {len(jsonl_data)} training examples in {filename}")271return filename272273# Example conversations274conversations = [275{276"input": "What is machine learning?",277"output": "Machine learning is a subset of artificial intelligence that enables computers to learn and improve from experience without being explicitly programmed."278},279{280"messages": [281{"role": "system", "content": "You are a helpful coding assistant."},282{"role": "user", "content": "How do I reverse a string in Python?"},283{"role": "assistant", "content": "You can reverse a string in Python using slicing: `reversed_string = original_string[::-1]`"}284]285},286{287"input": "Explain neural networks",288"output": "Neural networks are computing systems inspired by biological neural networks. They consist of interconnected nodes (neurons) that process information and learn patterns from data."289}290]291292# Prepare training data293training_file_path = prepare_chat_training_data(conversations)294295# Upload training file296with open(training_file_path, "rb") as f:297training_file = client.files.create(298file=f,299purpose="fine-tune"300)301302print(f"Training file uploaded: {training_file.id}")303304# Create validation data (optional)305def create_validation_split(jsonl_file: str, split_ratio: float = 0.2):306"""Split training data into training and validation sets"""307308with open(jsonl_file, 'r') as f:309lines = f.readlines()310311# Shuffle and split312import random313random.shuffle(lines)314315split_point = int(len(lines) * (1 - split_ratio))316train_lines = lines[:split_point]317val_lines = lines[split_point:]318319# Write training set320train_file = "train_data.jsonl"321with open(train_file, 'w') as f:322f.writelines(train_lines)323324# Write validation set325val_file = "val_data.jsonl"326with open(val_file, 'w') as f:327f.writelines(val_lines)328329print(f"Split into {len(train_lines)} training and {len(val_lines)} validation examples")330return train_file, val_file331332# Create train/validation split333train_file, val_file = create_validation_split("training_data.jsonl")334335# Upload both files336with open(train_file, "rb") as f:337train_file_obj = client.files.create(file=f, purpose="fine-tune")338339with open(val_file, "rb") as f:340val_file_obj = client.files.create(file=f, purpose="fine-tune")341342# Start fine-tuning with validation343job = client.fine_tuning.jobs.create(344training_file=train_file_obj.id,345validation_file=val_file_obj.id,346model="gpt-3.5-turbo-0125",347hyperparameters={348"n_epochs": 3349}350)351352print(f"Fine-tuning job with validation: {job.id}")353```354355### Model Checkpoints356357Access and manage model checkpoints created during fine-tuning.358359```python { .api }360def list(361self,362fine_tuning_job_id: str,363*,364after: str | NotGiven = NOT_GIVEN,365limit: int | NotGiven = NOT_GIVEN,366extra_headers: Headers | None = None,367extra_query: Query | None = None,368extra_body: Body | None = None,369timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN370) -> SyncPage[FineTuningJobCheckpoint]: ...371```372373Usage examples:374375```python376# List checkpoints for a job377job_id = "ftjob-abc123"378checkpoints = client.fine_tuning.jobs.checkpoints.list(job_id)379380print(f"Checkpoints for job {job_id}:")381for checkpoint in checkpoints:382print(f" Step {checkpoint.step_number}: {checkpoint.fine_tuned_model_checkpoint}")383print(f" Metrics: {checkpoint.metrics}")384385# Use checkpoint for inference386if checkpoints.data:387checkpoint_model = checkpoints.data[0].fine_tuned_model_checkpoint388389# Test the checkpoint model390response = client.chat.completions.create(391model=checkpoint_model,392messages=[393{"role": "user", "content": "Test the fine-tuned model"}394]395)396397print(f"Checkpoint model response: {response.choices[0].message.content}")398399# Compare checkpoint performance400def evaluate_checkpoint(checkpoint_model: str, test_cases: List[Dict]):401"""Evaluate a checkpoint model on test cases"""402403results = []404405for test_case in test_cases:406response = client.chat.completions.create(407model=checkpoint_model,408messages=test_case["messages"],409max_tokens=100410)411412result = {413"input": test_case["messages"][-1]["content"],414"expected": test_case.get("expected", ""),415"actual": response.choices[0].message.content,416"model": checkpoint_model417}418419results.append(result)420421return results422423# Test cases for evaluation424test_cases = [425{426"messages": [{"role": "user", "content": "What is AI?"}],427"expected": "AI explanation"428},429{430"messages": [{"role": "user", "content": "How does ML work?"}],431"expected": "ML explanation"432}433]434435# Evaluate each checkpoint436checkpoint_results = {}437for checkpoint in checkpoints.data[:3]: # Test first 3 checkpoints438model_id = checkpoint.fine_tuned_model_checkpoint439results = evaluate_checkpoint(model_id, test_cases)440checkpoint_results[checkpoint.step_number] = results441442print(f"Checkpoint {checkpoint.step_number} evaluation completed")443```444445### Production Deployment446447Deploy and use fine-tuned models in production applications.448449Usage examples:450451```python452# Get completed fine-tuning job453job = client.fine_tuning.jobs.retrieve("ftjob-abc123")454455if job.status == "succeeded":456fine_tuned_model = job.fine_tuned_model457print(f"Using fine-tuned model: {fine_tuned_model}")458459# Production usage460def generate_response(user_input: str, model: str = fine_tuned_model):461"""Generate response using fine-tuned model"""462463response = client.chat.completions.create(464model=model,465messages=[466{"role": "user", "content": user_input}467],468temperature=0.7,469max_tokens=150470)471472return response.choices[0].message.content473474# Test production deployment475test_inputs = [476"Explain quantum computing",477"What are the benefits of renewable energy?",478"How does blockchain technology work?"479]480481for input_text in test_inputs:482response = generate_response(input_text)483print(f"Input: {input_text}")484print(f"Response: {response}\n")485486# A/B testing between base and fine-tuned model487def compare_models(input_text: str, base_model: str = "gpt-3.5-turbo"):488"""Compare base model vs fine-tuned model responses"""489490# Base model response491base_response = client.chat.completions.create(492model=base_model,493messages=[{"role": "user", "content": input_text}]494)495496# Fine-tuned model response497ft_response = client.chat.completions.create(498model=fine_tuned_model,499messages=[{"role": "user", "content": input_text}]500)501502return {503"input": input_text,504"base_model": {505"model": base_model,506"response": base_response.choices[0].message.content507},508"fine_tuned_model": {509"model": fine_tuned_model,510"response": ft_response.choices[0].message.content511}512}513514# Compare models515comparison = compare_models("Explain machine learning")516print("Model comparison:")517print(f"Base: {comparison['base_model']['response']}")518print(f"Fine-tuned: {comparison['fine_tuned_model']['response']}")519520else:521print(f"Job not ready: {job.status}")522523# Model management524def manage_fine_tuned_models():525"""List and manage fine-tuned models"""526527# List models to find fine-tuned ones528models = client.models.list()529530fine_tuned_models = []531for model in models:532if "ft:" in model.id: # Fine-tuned models have "ft:" prefix533fine_tuned_models.append(model)534535print(f"Found {len(fine_tuned_models)} fine-tuned models:")536for model in fine_tuned_models:537print(f" {model.id} (created: {model.created})")538539return fine_tuned_models540541# List fine-tuned models542ft_models = manage_fine_tuned_models()543544# Delete old fine-tuned model (if needed)545# Note: Model deletion may not be immediately available546# for model in ft_models:547# if "old-model-suffix" in model.id:548# try:549# client.models.delete(model.id)550# print(f"Deleted model: {model.id}")551# except Exception as e:552# print(f"Could not delete {model.id}: {e}")553```554555## Types556557### Core Response Types558559```python { .api }560class FineTuningJob(BaseModel):561id: str562created_at: int563error: Optional[FineTuningJobError]564fine_tuned_model: Optional[str]565finished_at: Optional[int]566hyperparameters: FineTuningJobHyperparameters567model: str568object: Literal["fine_tuning.job"]569organization_id: str570result_files: List[str]571seed: int572status: Literal["validating_files", "queued", "running", "succeeded", "failed", "cancelled"]573trained_tokens: Optional[int]574training_file: str575validation_file: Optional[str]576user_provided_suffix: Optional[str]577integrations: Optional[List[FineTuningJobIntegration]]578579class FineTuningJobEvent(BaseModel):580id: str581created_at: int582level: Literal["info", "warn", "error"]583message: str584object: Literal["fine_tuning.job.event"]585586class FineTuningJobCheckpoint(BaseModel):587id: str588created_at: int589fine_tuned_model_checkpoint: str590fine_tuning_job_id: str591metrics: Dict[str, float]592object: Literal["fine_tuning.job.checkpoint"]593step_number: int594```595596### Parameter Types597598```python { .api }599# Fine-tuning job creation parameters600FineTuningJobCreateParams = TypedDict('FineTuningJobCreateParams', {601'model': Required[Union[str, FineTuningModel]],602'training_file': Required[str],603'hyperparameters': NotRequired[HyperparametersParam],604'suffix': NotRequired[str],605'validation_file': NotRequired[str],606'integrations': NotRequired[List[IntegrationParam]],607'seed': NotRequired[int],608}, total=False)609610# Hyperparameters configuration611class HyperparametersParam(TypedDict, total=False):612batch_size: Union[Literal["auto"], int]613learning_rate_multiplier: Union[Literal["auto"], float]614n_epochs: Union[Literal["auto"], int]615616# Integration parameters617class IntegrationParam(TypedDict, total=False):618type: Required[Literal["wandb"]]619wandb: Required[WandbIntegrationParam]620621class WandbIntegrationParam(TypedDict, total=False):622project: Required[str]623name: str624entity: str625tags: List[str]626```627628### Model and Status Types629630```python { .api }631# Supported fine-tuning models632FineTuningModel = Literal[633"babbage-002",634"davinci-002",635"gpt-3.5-turbo-0125",636"gpt-3.5-turbo-1106",637"gpt-4-0613",638"gpt-4o-mini-2024-07-18",639"gpt-4o-2024-08-06"640]641642# Job status enumeration643FineTuningJobStatus = Literal[644"validating_files",645"queued",646"running",647"succeeded",648"failed",649"cancelled"650]651652# Event levels653EventLevel = Literal["info", "warn", "error"]654655# Error information656class FineTuningJobError(BaseModel):657code: str658message: str659param: Optional[str]660```661662### Training Configuration663664```python { .api }665# Hyperparameter ranges and defaults666class HyperparameterDefaults:667n_epochs: Union[Literal["auto"], int] = "auto" # Typically 1-50668batch_size: Union[Literal["auto"], int] = "auto" # Powers of 2, up to 256669learning_rate_multiplier: Union[Literal["auto"], float] = "auto" # 0.02 to 2.0670671# Training data requirements672class TrainingDataRequirements:673min_examples: int = 10674recommended_examples: int = 50675format: str = "jsonl"676required_fields: List[str] = ["messages"]677678# Message format requirements679message_roles: List[str] = ["system", "user", "assistant"]680min_messages_per_example: int = 2681682# File size limits683max_file_size_mb: int = 100684max_tokens_per_example: int = 4096685686# Cost and timing estimates687class FineTuningEstimates:688# Approximate costs (varies by model and usage)689cost_per_1k_tokens_training: Dict[str, float] = {690"gpt-3.5-turbo": 0.008,691"gpt-4": 0.030,692"babbage-002": 0.0004,693"davinci-002": 0.0060694}695696# Typical training times697typical_duration_hours: Dict[str, Tuple[float, float]] = {698"small_dataset": (0.1, 1.0), # < 1000 examples699"medium_dataset": (1.0, 6.0), # 1000-10000 examples700"large_dataset": (6.0, 24.0) # > 10000 examples701}702```703704## Best Practices705706### Data Preparation707708- Use high-quality, diverse training examples709- Ensure consistent formatting across all examples710- Include system messages for context and behavior711- Balance your dataset to avoid bias712- Use validation data to monitor overfitting713714### Model Selection715716- Start with `gpt-3.5-turbo-0125` for most use cases717- Use `gpt-4` models for complex reasoning tasks718- Consider `babbage-002` or `davinci-002` for simple tasks with cost constraints719- Test different base models to find the best fit720721### Hyperparameter Tuning722723- Start with "auto" settings for initial experiments724- Use 1-3 epochs to avoid overfitting725- Monitor validation loss if using validation data726- Experiment with learning rate if auto settings don't work well727728### Monitoring and Evaluation729730- Track job events for training progress731- Use checkpoints to evaluate intermediate models732- Compare against base model performance733- Implement A/B testing for production deployment734735### Production Considerations736737- Test thoroughly before deploying fine-tuned models738- Monitor model performance in production739- Keep training data and models organized740- Plan for model updates and retraining741- Consider cost implications of fine-tuned model usage