Fine-tuning a large language model transforms a general-purpose AI into a specialist that understands your domain, tone, and task requirements. Whether you need a customer support bot that speaks your brand voice or a code assistant trained on your internal APIs, fine-tuning is the bridge between generic and purpose-built.

This guide walks you through the entire process -- from preparing your dataset to deploying your fine-tuned model -- using two of the most accessible platforms in 2026: OpenAI and Together AI.

When Fine-Tuning Makes Sense

Before investing time and compute, confirm that fine-tuning is the right approach:

  • Prompt engineering is not enough. You have tried few-shot examples and system prompts but the model still misses nuances.
  • You have quality training data. At least 50-100 examples for simple tasks, 500+ for complex behavior changes.
  • Consistency matters. You need the model to reliably follow a specific format, style, or reasoning pattern.
  • Latency or cost is a concern. A fine-tuned smaller model can replace a larger model with long prompts.

If you just need factual knowledge injection, consider RAG (retrieval-augmented generation) instead.

Step 1: Prepare Your Training Data

The quality of your fine-tune depends entirely on your data. Both OpenAI and Together AI accept JSONL format with conversational structure.

{"messages": [{"role": "system", "content": "You are a technical support agent for Acme Cloud."}, {"role": "user", "content": "My deployment failed with exit code 137."}, {"role": "assistant", "content": "Exit code 137 means your container was killed due to memory limits. Increase the memory allocation in your acme.yaml under resources.memory, then redeploy."}]}
{"messages": [{"role": "system", "content": "You are a technical support agent for Acme Cloud."}, {"role": "user", "content": "How do I rotate my API keys?"}, {"role": "assistant", "content": "Navigate to Settings > API Keys, click the rotate icon next to the key you want to refresh, then update your environment variables with the new value."}]}

Data preparation tips:

  1. Keep the system message consistent across examples
  2. Remove personally identifiable information
  3. Ensure assistant responses represent the ideal output you want
  4. Validate your JSONL -- one malformed line breaks the entire upload
  5. Aim for diversity in your examples to avoid overfitting on patterns
# Validate your JSONL file
python -c "
import json, sys
with open('training_data.jsonl') as f:
    for i, line in enumerate(f, 1):
        try:
            obj = json.loads(line)
            assert 'messages' in obj
        except Exception as e:
            print(f'Error on line {i}: {e}')
            sys.exit(1)
print(f'Valid: {i} examples')
"

Step 2: Fine-Tune with OpenAI

OpenAI

OpenAI offers the most streamlined fine-tuning experience. You can fine-tune GPT-4o-mini, GPT-4o, and other models directly through their API.

# Install the OpenAI CLI
pip install openai --upgrade
 
# Set your API key
export OPENAI_API_KEY="sk-..."
from openai import OpenAI
 
client = OpenAI()
 
# Upload your training file
training_file = client.files.create(
    file=open("training_data.jsonl", "rb"),
    purpose="fine-tune"
)
 
# Create the fine-tuning job
job = client.fine_tuning.jobs.create(
    training_file=training_file.id,
    model="gpt-4o-mini-2024-07-18",
    hyperparameters={
        "n_epochs": 3,
        "batch_size": "auto",
        "learning_rate_multiplier": "auto"
    }
)
 
print(f"Job created: {job.id}")

Monitor your job:

# Check status
job_status = client.fine_tuning.jobs.retrieve(job.id)
print(f"Status: {job_status.status}")
print(f"Trained tokens: {job_status.trained_tokens}")
 
# List events
events = client.fine_tuning.jobs.list_events(job.id, limit=10)
for event in events.data:
    print(f"{event.created_at}: {event.message}")

Once complete, your fine-tuned model ID appears in the job details (e.g., ft:gpt-4o-mini-2024-07-18:org:custom-name:id).

Step 3: Fine-Tune with Together AI

Together AI

Together AI gives you access to open-source models like Llama 3, Mistral, and Qwen -- often at lower cost and with more control over the training process.

pip install together
export TOGETHER_API_KEY="your-key-here"
import together
 
# Upload training data
file_resp = together.Files.upload(file="training_data.jsonl")
file_id = file_resp["id"]
 
# Start fine-tuning job
job = together.Fine_tuning.create(
    training_file=file_id,
    model="meta-llama/Llama-3-8b-chat-hf",
    n_epochs=3,
    learning_rate=1e-5,
    batch_size=4,
    suffix="my-support-bot"
)
 
print(f"Job ID: {job['id']}")

Together AI typically completes fine-tuning faster for open-source models and provides detailed training metrics including loss curves.

Step 4: Evaluate Your Fine-Tuned Model

Never skip evaluation. Create a held-out test set (10-20% of your data) that the model has never seen during training.

import json
 
def evaluate_model(client, model_id, test_file):
    correct = 0
    total = 0
 
    with open(test_file) as f:
        for line in f:
            example = json.loads(line)
            messages = example["messages"][:-1]  # Remove assistant reply
            expected = example["messages"][-1]["content"]
 
            response = client.chat.completions.create(
                model=model_id,
                messages=messages,
                temperature=0
            )
            predicted = response.choices[0].message.content
 
            # Simple exact-match or use your own scoring logic
            if expected.strip().lower() in predicted.strip().lower():
                correct += 1
            total += 1
 
    accuracy = correct / total * 100
    print(f"Accuracy: {accuracy:.1f}% ({correct}/{total})")
    return accuracy

Key metrics to track:

  • Task accuracy on held-out examples
  • Response format compliance
  • Tone and style consistency
  • Hallucination rate compared to base model
  • Latency and token usage

Step 5: Deploy and Iterate

Once satisfied with evaluation results, integrate your model:

# Use your fine-tuned model in production
response = client.chat.completions.create(
    model="ft:gpt-4o-mini-2024-07-18:org:support-bot:abc123",
    messages=[
        {"role": "system", "content": "You are a technical support agent for Acme Cloud."},
        {"role": "user", "content": "How do I scale my workers?"}
    ],
    temperature=0.3
)

Practical Tips

  • Start small. Fine-tune on 100 examples first. If results look promising, scale up your dataset.
  • Use a validation set. Both platforms support a validation file to track overfitting during training.
  • Keep epochs low. For most tasks, 2-4 epochs work well. More epochs risk memorization.
  • Compare costs. OpenAI charges per training token. Together AI charges per GPU-hour. Calculate both for your dataset size.
  • Version your data. Track which dataset version produced which model. You will iterate multiple times.
  • Combine with system prompts. Fine-tuning and prompting are complementary -- use both.

Cost Comparison

For a dataset of 1,000 examples (roughly 500K training tokens):

  • OpenAI GPT-4o-mini fine-tuning: approximately $4-8 for training, then standard inference pricing
  • Together AI Llama 3 8B: approximately $2-5 per job, with lower inference costs for open-source models

Both platforms offer free tiers or credits for initial experimentation.

Common Pitfalls

  1. Too little data. Under 50 examples rarely produces meaningful improvements.
  2. Inconsistent formatting. If your examples mix formats, the model learns inconsistency.
  3. Training on generated data without review. Always human-verify synthetic training examples.
  4. Ignoring the base model's strengths. Fine-tuning should specialize, not reteach basics.
  5. No evaluation pipeline. Without metrics, you cannot tell if v2 is better than v1.

Ready to Start Fine-Tuning?

OpenAI offers the easiest onboarding. Together AI gives you open-source flexibility at lower cost.

Start with OpenAI