The Fine-tuning API allows you to create custom models by training on your own data. Fine-tuning can improve model performance on specific tasks and reduce costs by using smaller, specialized models.
Create a fine-tuning job
Creates a fine-tuning job which begins the process of creating a new model from a given dataset.
client. fine_tuning . jobs . create (params)
The name of the model to fine-tune. You can select one of the supported models:
gpt-4o-2024-08-06
gpt-4o-mini-2024-07-18
gpt-3.5-turbo
The ID of an uploaded file that contains training data. The file must be formatted as a JSONL file.
The hyperparameters used for the fine-tuning job. Show Hyperparameters properties
Number of examples in each batch. Can be an integer or auto for automatic selection.
Scaling factor for the learning rate. Can be a float or auto.
The number of epochs to train the model for. Can be an integer or auto.
A string of up to 64 characters that will be added to your fine-tuned model name. For example, a suffix of “custom-model” would produce a model name like ft:gpt-3.5-turbo:my-org:custom-model:id.
The ID of an uploaded file that contains validation data. If provided, this data is used to generate validation metrics during fine-tuning.
A list of integrations to enable for your fine-tuning job (e.g., Weights & Biases).
The seed controls the reproducibility of the job. Passing in the same seed and job parameters should produce the same results.
The method used for fine-tuning. The type of fine-tuning method. Options: supervised, dpo (Direct Preference Optimization).
Set of 16 key-value pairs that can be attached to an object for storing additional information.
Response
Returns a FineTuningJob object.
The fine-tuning job identifier.
The object type, always fine_tuning.job.
The base model being fine-tuned.
Unix timestamp of when the job was created.
Unix timestamp of when the job finished.
The name of the fine-tuned model that is being created. The value will be null if the job is still running.
The organization that owns the fine-tuning job.
The current status of the job: validating_files, queued, running, succeeded, failed, or cancelled.
The file ID used for training.
The file ID used for validation.
The hyperparameters used for the fine-tuning job.
The total number of tokens trained.
Examples
Create a basic fine-tuning job
require "openai"
client = OpenAI :: Client . new
# First, upload your training data
training_file = client. files . create (
file: File . open ( "training_data.jsonl" ),
purpose: :fine_tune
)
# Create the fine-tuning job
job = client. fine_tuning . jobs . create (
model: "gpt-3.5-turbo" ,
training_file: training_file. id
)
puts "Job ID: #{ job. id } "
puts "Status: #{ job. status } "
Fine-tuning with hyperparameters
job = client. fine_tuning . jobs . create (
model: "gpt-4o-mini-2024-07-18" ,
training_file: training_file. id ,
hyperparameters: {
n_epochs: 3 ,
batch_size: 4 ,
learning_rate_multiplier: 0.1
},
suffix: "my-custom-model"
)
puts "Fine-tuning job created: #{ job. id } "
With validation data
# Upload training and validation files
training_file = client. files . create (
file: File . open ( "train.jsonl" ),
purpose: :fine_tune
)
validation_file = client. files . create (
file: File . open ( "validation.jsonl" ),
purpose: :fine_tune
)
# Create job with validation
job = client. fine_tuning . jobs . create (
model: "gpt-3.5-turbo" ,
training_file: training_file. id ,
validation_file: validation_file. id ,
metadata: {
project: "customer-support" ,
version: "v1"
}
)
puts "Job #{ job. id } created with validation data"
Retrieve a fine-tuning job
Get info about a fine-tuning job.
client. fine_tuning . jobs . retrieve (fine_tuning_job_id)
The ID of the fine-tuning job.
Examples
Check job status
require "openai"
client = OpenAI :: Client . new
job = client. fine_tuning . jobs . retrieve ( "ftjob-abc123" )
puts "Status: #{ job. status } "
puts "Model: #{ job. fine_tuned_model } " if job. fine_tuned_model
puts "Trained tokens: #{ job. trained_tokens } "
Monitor job progress
def wait_for_fine_tuning ( client , job_id )
loop do
job = client. fine_tuning . jobs . retrieve (job_id)
puts "Status: #{ job. status } "
case job. status
when "succeeded"
puts "Fine-tuning completed! Model: #{ job. fine_tuned_model } "
return job
when "failed" , "cancelled"
puts "Fine-tuning #{ job. status } "
return job
end
sleep 60 # Check every minute
end
end
job = client. fine_tuning . jobs . create (
model: "gpt-3.5-turbo" ,
training_file: training_file_id
)
final_job = wait_for_fine_tuning (client, job. id )
List fine-tuning jobs
List your organization’s fine-tuning jobs.
client. fine_tuning . jobs . list (params = {})
Number of fine-tuning jobs to retrieve.
Identifier for the last job from the previous pagination request.
Optional metadata filter. Use the syntax metadata[key]=value.
Examples
List all jobs
require "openai"
client = OpenAI :: Client . new
jobs = client. fine_tuning . jobs . list
jobs. data . each do | job |
puts " #{ job. id } - #{ job. status } - #{ job. model } "
end
jobs = client. fine_tuning . jobs . list (
metadata: { project: "customer-support" }
)
puts "Customer support fine-tuning jobs:"
jobs. data . each do | job |
puts "- #{ job. id } : #{ job. status } "
end
Paginate through jobs
# Get first page
page1 = client. fine_tuning . jobs . list ( limit: 10 )
page1. data . each do | job |
puts job. id
end
# Get next page
if page1. data . any?
page2 = client. fine_tuning . jobs . list (
limit: 10 ,
after: page1. data . last . id
)
page2. data . each do | job |
puts job. id
end
end
Cancel a fine-tuning job
Immediately cancel a fine-tune job.
client. fine_tuning . jobs . cancel (fine_tuning_job_id)
The ID of the fine-tuning job to cancel.
Examples
require "openai"
client = OpenAI :: Client . new
job = client. fine_tuning . jobs . cancel ( "ftjob-abc123" )
puts "Job #{ job. id } status: #{ job. status } "
Pause and resume jobs
Pause a job
client. fine_tuning . jobs . pause (fine_tuning_job_id)
Resume a job
client. fine_tuning . jobs . resume (fine_tuning_job_id)
Examples
require "openai"
client = OpenAI :: Client . new
# Pause a running job
job = client. fine_tuning . jobs . pause ( "ftjob-abc123" )
puts "Job paused: #{ job. status } "
# Resume it later
job = client. fine_tuning . jobs . resume ( "ftjob-abc123" )
puts "Job resumed: #{ job. status } "
List fine-tuning events
Get status updates for a fine-tuning job.
client. fine_tuning . jobs . list_events (fine_tuning_job_id, params = {})
The ID of the fine-tuning job to get events for.
Number of events to retrieve.
Identifier for the last event from the previous pagination request.
Examples
View job events
require "openai"
client = OpenAI :: Client . new
events = client. fine_tuning . jobs . list_events ( "ftjob-abc123" )
events. data . each do | event |
puts " #{ Time . at (event. created_at ) } : #{ event. message } "
end
Stream events in real-time
def stream_job_events ( client , job_id )
last_event_id = nil
loop do
events = client. fine_tuning . jobs . list_events (
job_id,
after: last_event_id
)
events. data . each do | event |
puts event. message
last_event_id = event. id
end
# Check job status
job = client. fine_tuning . jobs . retrieve (job_id)
break if [ "succeeded" , "failed" , "cancelled" ]. include? (job. status )
sleep 10
end
end
stream_job_events (client, "ftjob-abc123" )
Checkpoints
Access intermediate checkpoints from a fine-tuning job.
checkpoints = client. fine_tuning . jobs . checkpoints . list ( "ftjob-abc123" )
checkpoints. data . each do | checkpoint |
puts "Step #{ checkpoint. step_number } : #{ checkpoint. metrics } "
end
Fine-tuning data must be in JSONL format with the following structure:
{ "messages" : [{ "role" : "system" , "content" : "You are a helpful assistant." }, { "role" : "user" , "content" : "What is the capital of France?" }, { "role" : "assistant" , "content" : "The capital of France is Paris." }]}
{ "messages" : [{ "role" : "system" , "content" : "You are a helpful assistant." }, { "role" : "user" , "content" : "Who wrote Romeo and Juliet?" }, { "role" : "assistant" , "content" : "William Shakespeare wrote Romeo and Juliet." }]}
{ "messages" : [{ "role" : "system" , "content" : "You are a helpful assistant." }, { "role" : "user" , "content" : "What's the weather in Boston?" }, { "role" : "assistant" , "tool_calls" : [{ "id" : "call_1" , "type" : "function" , "function" : { "name" : "get_weather" , "arguments" : "{ \" location \" : \" Boston, MA \" }" }}]}]}
Best practices
Data quality : Use high-quality, diverse training examples (minimum 10, recommended 50-100)
Data format : Validate your JSONL files before uploading
Hyperparameters : Start with auto and adjust based on validation metrics
Validation set : Always include a validation file to monitor overfitting
Monitor progress : Use events to track training progress
Test thoroughly : Evaluate your fine-tuned model before production use
Version control : Use suffixes and metadata to track different model versions
Cost awareness : Fine-tuning and using fine-tuned models incurs costs
Complete example
require "openai"
client = OpenAI :: Client . new
# 1. Upload training data
puts "Uploading training data..."
training_file = client. files . create (
file: File . open ( "training.jsonl" ),
purpose: :fine_tune
)
puts "Waiting for file processing..."
sleep 5
# 2. Create fine-tuning job
puts "Creating fine-tuning job..."
job = client. fine_tuning . jobs . create (
model: "gpt-3.5-turbo" ,
training_file: training_file. id ,
suffix: "my-app-v1" ,
hyperparameters: {
n_epochs: 3
}
)
puts "Job ID: #{ job. id } "
# 3. Monitor progress
loop do
job = client. fine_tuning . jobs . retrieve (job. id )
puts "Status: #{ job. status } "
case job. status
when "succeeded"
puts "Fine-tuning complete!"
puts "Model: #{ job. fine_tuned_model } "
break
when "failed" , "cancelled"
puts "Fine-tuning #{ job. status } "
break
end
sleep 60
end
# 4. Use the fine-tuned model
if job. status == "succeeded"
response = client. chat . completions . create (
model: job. fine_tuned_model ,
messages: [{ role: "user" , content: "Hello!" }]
)
puts response. choices . first . message . content
end