JSONL für KI-Trainingsdaten

Ein umfassender Leitfaden zur Vorbereitung von JSONL-Trainingsdaten für KI und Machine Learning. Umfasst OpenAI Fine-Tuning, Anthropic Claude, HuggingFace-Datensätze, Datenvalidierung und großskalige Datenpipelines.

Letzte Aktualisierung: Februar 2026

Warum JSONL der Standard für KI-Trainingsdaten ist

JSONL (JSON Lines) hat sich zum De-facto-Standard für KI- und Machine-Learning-Trainingsdaten entwickelt. Jeder große KI-Anbieter, von OpenAI über Anthropic bis HuggingFace, verwendet JSONL als primäres Format für Fine-Tuning-Datensätze. Der Grund ist einfach: JSONL speichert ein Beispiel pro Zeile, was es trivial macht, Daten während des Trainings zu streamen, Beispiele zu mischen, Datensätze zu zählen, in Trainings- und Testsets aufzuteilen und neue Proben anzuhängen, ohne die gesamte Datei neu schreiben zu müssen.

Im Gegensatz zu einem einzelnen JSON-Array, das vor der Verwendung vollständig geparst werden muss, können JSONL-Dateien zeilenweise verarbeitet werden. Dies ist entscheidend, wenn Ihre Trainingsdatensätze auf Millionen von Beispielen über Gigabytes anwachsen. In diesem Leitfaden erfahren Sie die genauen JSONL-Formate, die von OpenAI, Anthropic Claude und HuggingFace erwartet werden, wie Sie Ihre Daten validieren und bereinigen, und wie Sie großskalige Datensätze für Produktionstrainingsläufe vorbereiten.

OpenAI Fine-Tuning JSONL-Format

OpenAI verwendet JSONL sowohl für Fine-Tuning als auch für die Batch API. Für das Fine-Tuning von Chat-Modellen wie GPT-4o-mini muss jede Zeile ein messages-Array mit der Standard-Chat-Completion-Struktur enthalten. Die drei Rollen — system, user und assistant — definieren die Konversation, die das Modell reproduzieren soll.

Jede Zeile ist ein Trainingsbeispiel. Die Systemnachricht legt das Verhalten fest, die Benutzernachricht ist die Eingabe, und die Assistentennachricht ist die Zielausgabe, die das Modell lernen soll.

Chat Completion Trainingsformat
{"messages": [{"role": "system", "content": "You are a helpful customer support agent for an e-commerce platform."}, {"role": "user", "content": "Where is my order #12345?"}, {"role": "assistant", "content": "I can see that order #12345 was shipped on February 10th via FedEx. The tracking number is FX987654321. Based on the latest update, it should arrive by February 14th."}]}
{"messages": [{"role": "system", "content": "You are a helpful customer support agent for an e-commerce platform."}, {"role": "user", "content": "I want to return my purchase."}, {"role": "assistant", "content": "I would be happy to help with your return. Could you please provide the order number and the reason for the return? Our return policy allows returns within 30 days of delivery for most items."}]}

Für mehrstufige Konversationen fügen Sie den vollständigen Gesprächsverlauf ein. Das Modell lernt aus jeder assistant-Nachricht im messages-Array. So bringen Sie dem Modell bei, Folgefragen zu bearbeiten.

Training mit mehrstufigen Konversationen
{"messages": [{"role": "system", "content": "You are a Python programming tutor."}, {"role": "user", "content": "What is a list comprehension?"}, {"role": "assistant", "content": "A list comprehension is a concise way to create lists in Python. Instead of writing a for loop to build a list, you can write it in one line: [expression for item in iterable if condition]."}, {"role": "user", "content": "Can you show me an example?"}, {"role": "assistant", "content": "Sure! Here is an example that creates a list of squares for even numbers:\n\nsquares = [x**2 for x in range(10) if x % 2 == 0]\n# Result: [0, 4, 16, 36, 64]\n\nThis is equivalent to:\nsquares = []\nfor x in range(10):\n if x % 2 == 0:\n squares.append(x**2)"}]}

OpenAI erfordert mindestens 10 Trainingsbeispiele, empfiehlt jedoch 50-100 für spürbare Verbesserungen. Alle Nachrichten müssen role- und content-Felder haben. Die Systemnachricht ist optional, wird aber für konsistentes Verhalten empfohlen. Verwenden Sie die OpenAI-CLI, um Ihre Datei vor dem Hochladen zu validieren: openai tools fine_tunes.prepare_data -f training.jsonl

Anthropic Claude Trainingsformat

Anthropic verwendet JSONL für das Fine-Tuning von Claude-Modellen. Das Format verwendet human- und assistant-Runden in einer strukturierten Konversation. Während das genaue Format von der Fine-Tuning-Methode und API-Version abhängt, folgt das Kernmuster der Messages-API-Struktur.

Jede Zeile enthält eine Konversation mit einem System-Prompt und abwechselnden user/assistant-Nachrichten. Das Modell lernt, die Assistentenantworten im gegebenen Konversationskontext zu erzeugen.

Claude Messages Format
{"system": "You are a medical information assistant. Provide accurate, general health information while always recommending consulting a healthcare professional.", "messages": [{"role": "user", "content": "What are the symptoms of vitamin D deficiency?"}, {"role": "assistant", "content": "Common symptoms of vitamin D deficiency include fatigue and tiredness, bone pain and muscle weakness, mood changes including depression, slow wound healing, and frequent infections. However, many people with mild deficiency may not notice symptoms. A blood test is the only way to confirm your vitamin D levels. I recommend speaking with your doctor who can order the appropriate test and recommend supplementation if needed."}]}
{"system": "You are a medical information assistant. Provide accurate, general health information while always recommending consulting a healthcare professional.", "messages": [{"role": "user", "content": "Is it safe to take ibuprofen daily?"}, {"role": "assistant", "content": "Taking ibuprofen daily for extended periods can carry risks including stomach ulcers and gastrointestinal bleeding, increased risk of heart attack and stroke, kidney problems with long-term use, and potential interactions with other medications. For occasional pain relief, short-term use at recommended doses is generally considered safe for most adults. However, if you find yourself needing daily pain relief, please consult your doctor. They can evaluate the underlying cause and recommend a safer long-term treatment plan."}]}

Für mehrstufige Trainingsdaten fügen Sie die vollständige Konversation mit abwechselnden user- und assistant-Nachrichten ein. Das Modell lernt den Gesprächsfluss und wie es den Kontext über mehrere Runden hinweg beibehält.

Mehrstufige Claude-Konversationen
{"system": "You are a cooking assistant specializing in Italian cuisine.", "messages": [{"role": "user", "content": "How do I make carbonara?"}, {"role": "assistant", "content": "Authentic carbonara uses just five ingredients: spaghetti, guanciale (cured pork cheek), eggs, Pecorino Romano cheese, and black pepper. The key technique is tempering the egg mixture with the hot pasta water so it creates a creamy sauce without scrambling."}, {"role": "user", "content": "Can I use bacon instead of guanciale?"}, {"role": "assistant", "content": "While guanciale gives the most authentic flavor, pancetta is a closer substitute. Bacon works in a pinch but its smoky flavor changes the dish significantly. If using bacon, choose an unsmoked variety. Whichever you use, cut it into small pieces and render the fat slowly over medium-low heat until crispy."}]}

HuggingFace-Datensätze mit JSONL

Die datasets-Bibliothek von HuggingFace unterstützt JSONL nativ als Eingabeformat. Sie können lokale JSONL-Dateien laden, entfernte Datensätze streamen und einfach zwischen Formaten konvertieren. JSONL ist das empfohlene Format zum Teilen von Datensätzen auf dem HuggingFace Hub.

Verwenden Sie die datasets-Bibliothek, um JSONL-Dateien in ein Dataset-Objekt zu laden. Dies bietet effizienten speicherabgebildeten Zugriff, eingebaute Train/Test-Aufteilung und nahtlose Integration mit der Trainer-API.

JSONL-Datensätze laden
from datasets import load_dataset
# Load a local JSONL file
dataset = load_dataset('json', data_files='training.jsonl')
print(dataset)
# DatasetDict({
# train: Dataset({
# features: ['messages', 'system'],
# num_rows: 5000
# })
# })
# Load with train/test split
dataset = load_dataset('json', data_files={
'train': 'train.jsonl',
'test': 'test.jsonl'
})
# Stream a large remote dataset
dataset = load_dataset(
'json',
data_files='https://example.com/large_dataset.jsonl',
streaming=True
)
for example in dataset['train']:
print(example)
break

Konvertieren Sie jeden HuggingFace-Datensatz in das JSONL-Format zur Verwendung mit anderen Trainingspipelines. Die to_json-Methode schreibt jedes Beispiel als separate JSON-Zeile.

Export nach JSONL
from datasets import load_dataset
# Load a dataset from the Hub
dataset = load_dataset('squad', split='train')
# Export to JSONL
dataset.to_json('squad_train.jsonl')
print(f'Exported {len(dataset)} examples')
# Export with specific columns
dataset.select_columns(['question', 'context', 'answers']).to_json(
'squad_filtered.jsonl'
)
# Process and export
def format_for_finetuning(example):
return {
'messages': [
{'role': 'user', 'content': example['question']},
{'role': 'assistant', 'content': example['answers']['text'][0]}
]
}
formatted = dataset.map(format_for_finetuning, remove_columns=dataset.column_names)
formatted.to_json('squad_chat_format.jsonl')

Datenvalidierung und -bereinigung

Die Qualität der Trainingsdaten wirkt sich direkt auf die Modellleistung aus. Ungültiges JSON, fehlende Felder, übermäßig lange Beispiele und doppelte Einträge können die Fine-Tuning-Ergebnisse verschlechtern. Validieren und bereinigen Sie Ihre JSONL-Dateien immer vor dem Start eines Trainingslaufs.

Dieses Skript validiert jede Zeile Ihrer JSONL-Datei auf häufige Probleme: ungültiges JSON, fehlende Pflichtfelder, leere Inhalte und Token-Länge. Führen Sie es vor dem Hochladen aus, um Probleme frühzeitig zu erkennen.

JSONL-Trainingsdaten-Validator
import json
import sys
from collections import Counter
def validate_training_data(path: str) -> dict:
"""Validate a JSONL file for AI fine-tuning."""
stats = Counter()
errors = []
with open(path, 'r', encoding='utf-8') as f:
for line_num, line in enumerate(f, 1):
line = line.strip()
if not line:
continue
stats['total'] += 1
# Check valid JSON
try:
data = json.loads(line)
except json.JSONDecodeError as e:
errors.append(f'Line {line_num}: Invalid JSON - {e}')
stats['invalid_json'] += 1
continue
# Check messages field exists
if 'messages' not in data:
errors.append(f'Line {line_num}: Missing "messages" field')
stats['missing_messages'] += 1
continue
messages = data['messages']
# Check message structure
for i, msg in enumerate(messages):
if 'role' not in msg:
errors.append(f'Line {line_num}, msg {i}: Missing "role"')
stats['missing_role'] += 1
if 'content' not in msg:
errors.append(f'Line {line_num}, msg {i}: Missing "content"')
stats['missing_content'] += 1
elif not msg['content'].strip():
errors.append(f'Line {line_num}, msg {i}: Empty content')
stats['empty_content'] += 1
# Check has at least one assistant message
roles = [m.get('role') for m in messages]
if 'assistant' not in roles:
errors.append(f'Line {line_num}: No assistant message')
stats['no_assistant'] += 1
stats['valid'] += 1
return {'stats': dict(stats), 'errors': errors[:50]}
result = validate_training_data('training.jsonl')
print(f"Total: {result['stats'].get('total', 0)}")
print(f"Valid: {result['stats'].get('valid', 0)}")
if result['errors']:
print(f"\nFirst {len(result['errors'])} errors:")
for err in result['errors']:
print(f' {err}')

Doppelte Trainingsbeispiele verschwenden Rechenleistung und können das Modell in Richtung überrepräsentierter Muster verzerren. Dieses Skript entfernt exakte Duplikate basierend auf dem Inhaltshash jeder Zeile.

Deduplizierungsskript
import json
import hashlib
def deduplicate_jsonl(input_path: str, output_path: str) -> dict:
"""Remove duplicate training examples from a JSONL file."""
seen_hashes = set()
total = 0
unique = 0
with open(input_path, 'r') as fin, open(output_path, 'w') as fout:
for line in fin:
line = line.strip()
if not line:
continue
total += 1
# Hash the normalized JSON to catch formatting differences
data = json.loads(line)
canonical = json.dumps(data, sort_keys=True)
content_hash = hashlib.sha256(canonical.encode()).hexdigest()
if content_hash not in seen_hashes:
seen_hashes.add(content_hash)
fout.write(json.dumps(data) + '\n')
unique += 1
duplicates = total - unique
print(f'Total: {total}, Unique: {unique}, Removed: {duplicates}')
return {'total': total, 'unique': unique, 'duplicates': duplicates}
deduplicate_jsonl('training.jsonl', 'training_deduped.jsonl')

Großskalige Datenvorbereitung

Produktionstrainingsdatensätze enthalten oft Hunderttausende oder Millionen von Beispielen. In diesem Maßstab benötigen Sie automatisierte Pipelines zum Mischen, Aufteilen und Sharden Ihrer JSONL-Daten. Eine ordnungsgemäße Vorbereitung verhindert Trainingsprobleme wie katastrophales Vergessen und gewährleistet reproduzierbare Experimente.

Dieses Skript mischt Ihre Daten zufällig und teilt sie in Trainings- und Testsets auf. Das Mischen ist entscheidend, da JSONL-Dateien oft in geordneter Reihenfolge generiert werden und Training mit geordneten Daten zu schlechter Generalisierung führen kann.

Train/Test-Aufteilung und Shuffle-Pipeline
import json
import random
from pathlib import Path
def prepare_training_data(
input_path: str,
output_dir: str,
test_ratio: float = 0.1,
seed: int = 42
) -> dict:
"""Shuffle and split JSONL into train/test sets."""
random.seed(seed)
output = Path(output_dir)
output.mkdir(parents=True, exist_ok=True)
# Load all examples
examples = []
with open(input_path, 'r') as f:
for line in f:
line = line.strip()
if line:
examples.append(json.loads(line))
# Shuffle
random.shuffle(examples)
# Split
split_idx = int(len(examples) * (1 - test_ratio))
train_data = examples[:split_idx]
test_data = examples[split_idx:]
# Write output files
train_path = output / 'train.jsonl'
test_path = output / 'test.jsonl'
for data, path in [(train_data, train_path), (test_data, test_path)]:
with open(path, 'w') as f:
for example in data:
f.write(json.dumps(example) + '\n')
print(f'Train: {len(train_data)} examples -> {train_path}')
print(f'Test: {len(test_data)} examples -> {test_path}')
return {'train': len(train_data), 'test': len(test_data)}
prepare_training_data(
'all_examples.jsonl',
'./prepared_data/',
test_ratio=0.1,
seed=42
)

Wenn Datensätze für eine einzelne Datei zu groß sind oder Sie das Training auf mehrere GPUs verteilen müssen, teilen Sie die JSONL-Datei in kleinere Teile auf. Jeder Shard kann unabhängig verarbeitet werden.

Datei-Sharding für verteiltes Training
import json
from pathlib import Path
def shard_jsonl(
input_path: str,
output_dir: str,
shard_size: int = 50000
) -> int:
"""Split a large JSONL file into smaller shards."""
output = Path(output_dir)
output.mkdir(parents=True, exist_ok=True)
shard_num = 0
line_count = 0
current_file = None
with open(input_path, 'r') as fin:
for line in fin:
line = line.strip()
if not line:
continue
if line_count % shard_size == 0:
if current_file:
current_file.close()
shard_path = output / f'shard_{shard_num:04d}.jsonl'
current_file = open(shard_path, 'w')
shard_num += 1
current_file.write(line + '\n')
line_count += 1
if current_file:
current_file.close()
print(f'Created {shard_num} shards from {line_count} examples')
return shard_num
shard_jsonl('large_dataset.jsonl', './shards/', shard_size=50000)

Validieren Sie Ihre Trainingsdaten online

Verwenden Sie unsere kostenlosen browserbasierten Tools, um Ihre JSONL-Trainingsdaten zu validieren, formatieren und konvertieren, bevor Sie sie bei OpenAI, Anthropic oder HuggingFace hochladen.

Bereit, Ihre Trainingsdaten vorzubereiten?

Validieren, formatieren und inspizieren Sie Ihre JSONL-Trainingsdateien direkt in Ihrem Browser. Keine Uploads, keine Anmeldung, 100 % privat.

Häufig gestellte Fragen

JSONL-Trainingsdaten — OpenAI, Claude & Hugging Face Form...