Strip away the mystique and a fine-tuning dataset is a plain text file — one valid, labeled conversation per line.
1JSONL Is Just Repeated, Independent JSON
Unlike a single JSON file holding one big array, JSONL (JSON Lines) puts one complete, independently-valid JSON object on each line. That format lets a training pipeline stream and process massive datasets one line at a time without ever needing to load the entire file into memory as one giant structure.
2Train on the Exact Shape You'll Actually Run
If production will call the fine-tuned model with a specific system message, the training examples need that same system message — training the model on a different framing than what it will see at inference time teaches it a pattern that doesn't quite match how it's actually used, undermining the whole point of specializing it.
3Step-by-Step Breakdown
Real Examples, Real Format. A fine-tuning dataset is just a real file of labeled examples, one per line, in the exact conversational shape you want the model to learn — a system instruction, a real user ticket, and the correct label as the assistant's response. This is JSONL: one complete, valid JSON object per line.
Build the Real Training File. to_finetune_example already shapes one labeled ticket into the conversational format a fine-tuning job expects. Finish build_jsonl so it actually converts every real example and serializes each one to a valid JSON line.
Why does each fine-tuning example include the same system message every ticket was actually going to be classified with, rather than omitting it since it's identical every time?
- →The model needs to learn the exact pattern it will actually be called with in production — training on a different (or missing) system message than what's used at inference time introduces a mismatch between training and real usage.
- →It's included purely to make the training file larger, with no effect on what the model learns.
A Real Dataset, Ready to Train. You just built real training examples in exactly the format a fine-tuning job expects. Two lines is a toy dataset — a real one needs hundreds of diverse, correctly labeled examples. Next lesson: what actually happens once that dataset is submitted, and how to evaluate whether the result is trustworthy.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Validate Every Line Before Submitting a Training Job
A single malformed JSON line can fail an entire training job submission — parse and validate every line locally first, so failures are caught immediately with a clear line number rather than after a remote submission.
for i, line in enumerate(lines): json.loads(line) # raises with context on failureSEO Implications
- 1
Target 'JSONL fine-tuning format example' and 'prepare fine-tuning dataset' separately
Developers formatting their first dataset search for the concrete file format and the broader preparation process independently.
Best Practices
Keep a Held-Out Portion of Labeled Examples Out of the Training File Entirely
Examples the model never trains on are what make real evaluation possible afterward — mixing your eval set into training defeats the purpose of measuring generalization, covered in the next lesson.
Frequent Bugs
Using inconsistent labels across examples, like "High", "high", and "URGENT" for the same actual priority level.
Inconsistent labeling teaches the model an inconsistent pattern — normalize every label to the exact same set of values before building the dataset.
Real-World Examples
Streaming Large Training Files
A dataset with 50,000 labeled tickets is processed by most fine-tuning pipelines one JSONL line at a time, exactly why the format avoids one giant JSON array that would need to be fully parsed into memory at once.
for line in open("dataset.jsonl"): process(json.loads(line))