How to fine-tune model for classification
Quick answer
To fine-tune a model for classification, prepare a labeled dataset in JSONL format with messages and labels, upload it using
client.files.create, then create a fine-tuning job with client.fine_tuning.jobs.create specifying the base model. After training, use the fine-tuned model for classification by sending inputs as chat messages and interpreting the output labels.PREREQUISITES
Python 3.8+OpenAI API key (free tier works)pip install openai>=1.0
Setup
Install the official OpenAI Python SDK and set your API key as an environment variable.
pip install openai output
Collecting openai Downloading openai-1.x.x-py3-none-any.whl Installing collected packages: openai Successfully installed openai-1.x.x
Step by step
Prepare your classification dataset in JSONL format where each line contains a JSON object with messages (including user input) and the expected label as the assistant's response. Upload the file, create a fine-tuning job, and then use the fine-tuned model for inference.
import os
import json
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
# Step 1: Prepare training data file (classification format)
# Example line in training.jsonl:
# {"messages": [{"role": "user", "content": "Is this email spam?"}], "label": "spam"}
# Step 2: Upload training file
with open("training.jsonl", "rb") as f:
training_file = client.files.create(file=f, purpose="fine-tune")
print(f"Uploaded training file ID: {training_file.id}")
# Step 3: Create fine-tuning job
job = client.fine_tuning.jobs.create(
training_file=training_file.id,
model="gpt-4o-mini-2024-07-18"
)
print(f"Fine-tuning job ID: {job.id}")
# Step 4: Poll job status (simplified example)
import time
while True:
status = client.fine_tuning.jobs.retrieve(job.id)
print(f"Status: {status.status}")
if status.status in ["succeeded", "failed"]:
break
time.sleep(30)
# Step 5: Use fine-tuned model for classification
if status.status == "succeeded":
fine_tuned_model = status.fine_tuned_model
messages = [{"role": "user", "content": "Is this email spam?"}]
response = client.chat.completions.create(
model=fine_tuned_model,
messages=messages
)
print("Classification result:", response.choices[0].message.content) output
Uploaded training file ID: file-abc123xyz Fine-tuning job ID: job-xyz789abc Status: running Status: running Status: succeeded Classification result: spam
Common variations
- Use async calls with
asyncioandawaitfor non-blocking fine-tuning job polling. - Change base model to
gpt-4oorgpt-4o-minidepending on your accuracy and cost needs. - For multi-class classification, format labels as distinct strings and ensure training data covers all classes.
import asyncio
async def poll_job(job_id):
while True:
status = client.fine_tuning.jobs.retrieve(job_id)
print(f"Status: {status.status}")
if status.status in ["succeeded", "failed"]:
return status
await asyncio.sleep(30)
# Usage:
# asyncio.run(poll_job(job.id)) output
Status: running Status: running Status: succeeded
Troubleshooting
- If you see
Invalid file format, ensure your JSONL lines have correctmessagesandlabelkeys. - If fine-tuning job fails, check your dataset size and format; classification fine-tuning requires sufficient labeled examples.
- Use
client.fine_tuning.jobs.retrieve(job.id)to get detailed error messages.
Key Takeaways
- Prepare classification data as JSONL with user messages and label responses.
- Upload data and create fine-tuning jobs using
client.files.createandclient.fine_tuning.jobs.create. - Poll job status until completion before using the fine-tuned model for inference.
- Use async polling or different base models to optimize workflow and cost.
- Check error messages carefully for data format issues or insufficient training data.