Lesson 25 · Slide 1
Fine-Tuning via API
Take a foundation model and make it yours — using nothing more than a JSONL file and an API call. No GPUs to manage, no infrastructure to build.
Learning Objectives
- Prepare and validate JSONL training data in the chat-completions message format
- Create and monitor fine-tuning jobs through the OpenAI API
- Understand key hyperparameters: epochs, learning rate multiplier, batch size
- Evaluate a fine-tuned model against its base model
- Manage costs, versioning, and deployment of fine-tuned models
Notes: Module 5 focus. Lesson 24 covered LoRA/QLoRA for local fine-tuning; this lesson covers the hosted API approach. Students need an OpenAI API key with fine-tuning access.
Lesson 25 · Slide 2
Why API Fine-Tuning?
API-based fine-tuning lets you customise a model without managing GPUs, training frameworks, or model weights. The provider handles infrastructure; you provide the data.
When to Fine-Tune via API
Good Fit
- Consistent tone or style (brand voice, legal language)
- Structured output formats (JSON schemas, specific templates)
- Domain-specific terminology the base model handles poorly
- Reducing prompt length by "baking in" instructions
Not Ideal
- Adding new factual knowledge (use RAG instead)
- Tasks that change frequently (re-training is slow)
- When prompt engineering alone gets you to 95%+
- Very small datasets (<50 examples)
Notes: Emphasise the decision framework: try prompt engineering first, then few-shot, then fine-tuning. Fine-tuning is not a first resort.
Lesson 25 · Slide 3
JSONL Data Format
Training data must be a JSONL file (one JSON object per line). Each line contains a messages array using the chat-completions format: system, user, and assistant roles.
{"messages": [
{"role": "system", "content": "You are a customer-support agent for Acme Corp. Always be polite and concise."},
{"role": "user", "content": "How do I reset my password?"},
{"role": "assistant", "content": "Go to acme.com/reset, enter your email, and follow the link sent to your inbox. The link expires in 15 minutes."}
]}
{"messages": [
{"role": "system", "content": "You are a customer-support agent for Acme Corp. Always be polite and concise."},
{"role": "user", "content": "What's your refund policy?"},
{"role": "assistant", "content": "We offer full refunds within 30 days of purchase. Email billing@acme.com with your order number."}
]}
Key Rules
- Each example must include at least one user and one assistant message
- The system message is optional but should be consistent across examples
- Multi-turn conversations are supported — alternate user/assistant messages
- The model learns to produce the assistant messages; user/system messages are context
Lesson 25 · Slide 4
Data Validation & Quality
Garbage in, garbage out. Validating your training data is the most important step in the entire fine-tuning pipeline.
Automated Checks
- Format: Valid JSON on every line, correct
messages structure, valid roles
- Token limits: Each example must fit within the model's context window (typically 4096 or 16384 tokens for fine-tuning)
- Minimum count: At least 10 examples required; 50–100+ recommended
- Duplicates: Remove exact duplicates; near-duplicates hurt generalisation
Manual Quality Checks
- Are the assistant responses what you actually want the model to produce?
- Is the style and formatting consistent across examples?
- Do examples cover the full range of expected inputs?
- Are there contradictions between examples?
Notes: Walk through the OpenAI cookbook validation script. Emphasise that 50 high-quality examples often outperform 500 noisy ones.
Lesson 25 · Slide 5
Creating a Fine-Tuning Job
Two API calls: upload the file, then create the job.
from openai import OpenAI
client = OpenAI()
# Step 1: Upload the training file
file = client.files.create(
file=open("training_data.jsonl", "rb"),
purpose="fine-tune"
)
# Step 2: Create the fine-tuning job
job = client.fine_tuning.jobs.create(
training_file=file.id,
model="gpt-4o-mini-2024-07-18",
hyperparameters={
"n_epochs": 3,
"learning_rate_multiplier": 1.8,
"batch_size": 1
},
suffix="acme-support-v1" # custom model name suffix
)
Provider Comparison
| Provider | Base Models | Min Examples | Method |
| OpenAI | gpt-4o-mini, gpt-4o | 10 | API + Dashboard |
| Anthropic | Claude (limited access) | Varies | Partner program |
| Google | Gemini | 10 | Vertex AI / API |
| Together AI | Llama, Mistral, etc. | 1 | API |
Lesson 25 · Slide 6
Hyperparameters
Three levers control how the model trains. Getting these right can mean the difference between a great model and an overfit one.
n_epochs
How many times the model sees each example. More epochs = more learning, but risk of overfitting.
- <100 examples: 3–4 epochs
- 100–500 examples: 2–3 epochs
- 500+ examples: 1–2 epochs
learning_rate_multiplier
Scales the default learning rate. Higher = faster learning but less stable. Start with 1.0 (auto) and adjust if results plateau or diverge.
batch_size
Number of examples processed before updating weights. Larger batches = smoother gradients but slower feedback.
- Default: auto (typically 1–4 for small datasets)
- Larger datasets: 4–32
Rule of Thumb
Start with defaults. Only change one parameter at a time. Track training loss — if it drops to near zero, you are overfitting.
Lesson 25 · Slide 7
Monitoring, Evaluation & Cost
Monitoring Training
# Poll job status
job = client.fine_tuning.jobs.retrieve(job.id)
print(job.status) # "validating_files" → "running" → "succeeded"
# Stream training events
for event in client.fine_tuning.jobs.list_events(job.id):
print(f"[{event.created_at}] {event.message}")
Evaluating the Fine-Tuned Model
- Hold out 10–20% of your data as a validation set (pass as
validation_file)
- Compare fine-tuned vs. base model on identical test prompts
- Use both automated metrics (accuracy, format compliance) and human review
- Watch for regression: fine-tuned models can lose general capabilities
Cost Management
| Cost Component | gpt-4o-mini (approx.) |
| Training | $3.00 / 1M tokens |
| Input (inference) | $0.30 / 1M tokens |
| Output (inference) | $1.20 / 1M tokens |
Training cost = tokens_per_example x n_examples x n_epochs x rate. A 200-example dataset at 500 tokens each, 3 epochs = ~$0.90.
Lesson 25 · Slide 8
Lab & Homework
Lab Exercises
- Prepare JSONL Data — create a training dataset of 50+ examples in the chat-completions format for a customer-support domain
- Validate Data — run automated format and quality checks; fix any issues
- Fine-Tune — upload data and create a fine-tuning job via the OpenAI API
- Evaluate — compare the fine-tuned model against the base model on held-out test prompts
Homework Tasks
- Build a JSONL dataset for a different domain (e.g., technical docs, product descriptions) and fine-tune a model on it
- Experiment with hyperparameters: train the same data with 3 different epoch counts and compare validation loss curves
- Write a cost analysis comparing fine-tuning vs. few-shot prompting for a 10,000 calls/day workload