JSONL dla danych treningowych AI

Kompleksowy przewodnik po przygotowywaniu danych treningowych JSONL dla AI i uczenia maszynowego. Obejmuje fine-tuning OpenAI, Anthropic Claude, zbiory danych HuggingFace, walidacje danych i potoki przetwarzania danych na duza skale.

Ostatnia aktualizacja: luty 2026

Dlaczego JSONL jest standardem dla danych treningowych AI

JSONL (JSON Lines) stal sie de facto standardem dla danych treningowych AI i uczenia maszynowego. Kazdy wazny dostawca AI, od OpenAI przez Anthropic po HuggingFace, uzywa JSONL jako glownego formatu dla zbiorow danych do fine-tuningu. Powod jest prosty: JSONL przechowuje jeden przyklad na linie, co sprawia, ze strumieniowanie danych podczas treningu, losowe mieszanie przykladow, liczenie rekordow, podzial na zbiory treningowe i testowe oraz dodawanie nowych probek bez przepisywania calego pliku jest trywialne.

W przeciwienstwie do pojedynczej tablicy JSON, ktora musi byc w calosci sparsowana przed uzyciem, pliki JSONL moga byc przetwarzane linia po linii. Ma to znaczenie, gdy zbiory danych treningowych rosna do milionow przykladow zajmujacych gigabajty. W tym przewodniku poznasz dokladne formaty JSONL oczekiwane przez OpenAI, Anthropic Claude i HuggingFace, dowiesz sie, jak walidowac i czyscic dane, oraz jak przygotowac zbiory danych na duza skale do produkcyjnych przebiegow treningowych.

Format JSONL do fine-tuningu OpenAI

OpenAI uzywa JSONL zarowno do fine-tuningu, jak i Batch API. Do fine-tuningu modeli czatowych, takich jak GPT-4o-mini, kazda linia musi zawierac tablice messages ze standardowa struktura chat completion. Trzy role - system, user i assistant - definiuja konwersacje, ktora model powinien nauczyc sie odtwarzac.

Kazda linia to jeden przyklad treningowy. Wiadomosc systemowa ustawia zachowanie, wiadomosc uzytkownika to dane wejsciowe, a wiadomosc asystenta to docelowe wyjscie, ktorego model powinien sie nauczyc.

Format treningowy Chat Completion
{"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."}]}

W przypadku konwersacji wieloturowych nalezy uwzglednic pelna historie rozmowy. Model uczy sie z kazdej tury asystenta w tablicy messages. W ten sposob uczysz model obslugi pytan uzupelniajacych.

Trening konwersacji wieloturowych
{"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 wymaga co najmniej 10 przykladow treningowych, ale zaleca 50-100 dla zauwazyalnej poprawy. Wszystkie wiadomosci musza miec pola role i content. Wiadomosc systemowa jest opcjonalna, ale zalecana dla spojnego zachowania. Uzyj CLI OpenAI do walidacji pliku przed przeslaniem: openai tools fine_tunes.prepare_data -f training.jsonl

Format treningowy Anthropic Claude

Anthropic uzywa JSONL do fine-tuningu modeli Claude. Format wykorzystuje tury human i assistant w ustrukturyzowanej konwersacji. Chociaz dokladny format zalezy od metody fine-tuningu i wersji API, glowny wzorzec odpowiada strukturze Messages API.

Kazda linia zawiera konwersacje z promptem systemowym i naprzemiennymi wiadomosciami uzytkownika/asystenta. Model uczy sie generowac odpowiedzi asystenta na podstawie kontekstu konwersacji.

Format Messages Claude
{"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."}]}

W przypadku wieloturowych danych treningowych nalezy uwzglednic pelna konwersacje z naprzemiennymi wiadomosciami uzytkownika i asystenta. Model uczy sie przeplywu konwersacji i sposobu utrzymywania kontekstu miedzy turami.

Konwersacje wieloturowe Claude
{"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."}]}

Zbiory danych HuggingFace z JSONL

Biblioteka datasets HuggingFace natywnie obsluguje JSONL jako format wejsciowy. Mozesz ladowac lokalne pliki JSONL, strumieniowac zdalne zbiory danych i latwo konwertowac miedzy formatami. JSONL jest zalecanym formatem do udostepniania zbiorow danych na HuggingFace Hub.

Uzyj biblioteki datasets do ladowania plikow JSONL do obiektu Dataset. Zapewnia to wydajny dostep z mapowaniem pamieci, wbudowany podzial train/test oraz bezproblemowa integracje z Trainer API.

Ladowanie zbiorow danych JSONL
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

Konwertuj dowolny zbior danych HuggingFace do formatu JSONL do uzycia z innymi potokami treningowymi. Metoda to_json zapisuje kazdy przyklad jako osobna linie JSON.

Eksportowanie do 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')

Walidacja i czyszczenie danych

Jakosc danych treningowych bezposrednio wplywa na wydajnosc modelu. Nieprawidlowy JSON, brakujace pola, zbyt dlugie przyklady i duplikaty moga pogorszyc wyniki fine-tuningu. Zawsze waliduj i czyscij pliki JSONL przed rozpoczeciem przebiegu treningowego.

Ten skrypt waliduje kazda linie pliku JSONL pod katem typowych problemow: nieprawidlowy JSON, brakujace wymagane pola, pusta tresc i dlugosc tokenow. Uruchom go przed przeslaniem, aby wczesnie wykryc problemy.

Walidator danych treningowych JSONL
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}')

Zduplikowane przyklady treningowe marnuja moc obliczeniowa i moga spowodowac przechylenie modelu w kierunku nadmiernie reprezentowanych wzorcow. Ten skrypt usuwa dokladne duplikaty na podstawie hasha zawartosci kazdej linii.

Skrypt deduplikacji
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')

Przygotowanie danych na duza skale

Produkcyjne zbiory danych treningowych czesto zawieraja setki tysiecy lub miliony przykladow. Na tej skali potrzebujesz zautomatyzowanych potokow do losowego mieszania, podzialu i fragmentacji danych JSONL. Prawidlowe przygotowanie zapobiega problemom treningowym, takim jak katastrofalne zapominanie, i zapewnia powtarzalnosc eksperymentow.

Ten skrypt losowo miesza dane i dzieli je na zbiory treningowe i testowe. Mieszanie jest krytyczne, poniewaz pliki JSONL sa czesto generowane w okreslonym porzadku, a trening na uporzadkowanych danych moze prowadzic do slabej generalizacji.

Potok podzialu Train/Test i losowego mieszania
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
)

Gdy zbiory danych sa zbyt duze dla jednego pliku lub musisz rozlozyc trening na wiele GPU, podziel plik JSONL na mniejsze fragmenty. Kazdy fragment moze byc przetwarzany niezaleznie.

Fragmentacja plikow do treningu rozproszonego
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)

Waliduj swoje dane treningowe online

Uzyj naszych darmowych narzedzi przegladarkowych do walidacji, formatowania i konwersji danych treningowych JSONL przed przeslaniem do OpenAI, Anthropic lub HuggingFace.

Gotowy do przygotowania danych treningowych?

Waliduj, formatuj i sprawdzaj pliki treningowe JSONL bezposrednio w przegladarce. Bez przesylania, bez rejestracji, 100% prywatnosci.

Najczesciej zadawane pytania

Dane treningowe JSONL — formaty OpenAI, Claude i Hugging ...