JSONL per Dati di Addestramento IA

Una guida completa alla preparazione dei dati di addestramento JSONL per l'intelligenza artificiale e il machine learning. Copre il fine-tuning di OpenAI, Anthropic Claude, dataset HuggingFace, validazione dei dati e pipeline di dati su larga scala.

Ultimo aggiornamento: Febbraio 2026

Perché JSONL è lo Standard per i Dati di Addestramento IA

JSONL (JSON Lines) è diventato lo standard de facto per i dati di addestramento di intelligenza artificiale e machine learning. Ogni grande fornitore di IA, da OpenAI ad Anthropic a HuggingFace, utilizza JSONL come formato principale per i dataset di fine-tuning. Il motivo è semplice: JSONL memorizza un esempio per riga, rendendo banale lo streaming dei dati durante l'addestramento, il mescolamento degli esempi, il conteggio dei record, la suddivisione in set di train e test e l'aggiunta di nuovi campioni senza riscrivere l'intero file.

A differenza di un singolo array JSON che deve essere completamente analizzato prima dell'uso, i file JSONL possono essere elaborati riga per riga. Questo è importante quando i dataset di addestramento crescono fino a milioni di esempi che occupano gigabyte. In questa guida imparerai i formati JSONL esatti previsti da OpenAI, Anthropic Claude e HuggingFace, come validare e pulire i tuoi dati e come preparare dataset su larga scala per esecuzioni di addestramento in produzione.

Formato JSONL per il Fine-tuning di OpenAI

OpenAI utilizza JSONL sia per il fine-tuning che per la Batch API. Per il fine-tuning di modelli chat come GPT-4o-mini, ogni riga deve contenere un array messages con la struttura standard di chat completion. I tre ruoli, system, user e assistant, definiscono la conversazione che il modello deve imparare a riprodurre.

Ogni riga è un esempio di addestramento. Il messaggio system imposta il comportamento, il messaggio user è l'input e il messaggio assistant è l'output target che il modello deve imparare.

Formato di Addestramento 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."}]}

Per conversazioni multi-turno, includi l'intera cronologia della conversazione. Il modello impara da ogni turno assistant nell'array messages. Questo è il modo per insegnare al modello a gestire le domande di follow-up.

Addestramento con Conversazioni Multi-turno
{"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 richiede almeno 10 esempi di addestramento, ma ne raccomanda 50-100 per miglioramenti evidenti. Tutti i messaggi devono avere i campi role e content. Il messaggio system è opzionale ma raccomandato per un comportamento coerente. Usa la CLI di OpenAI per validare il tuo file prima del caricamento: openai tools fine_tunes.prepare_data -f training.jsonl

Formato di Addestramento Anthropic Claude

Anthropic utilizza JSONL per il fine-tuning dei modelli Claude. Il formato usa turni human e assistant in una conversazione strutturata. Mentre il formato esatto dipende dal metodo di fine-tuning e dalla versione dell'API, il pattern principale segue la struttura della Messages API.

Ogni riga contiene una conversazione con un prompt di sistema e messaggi alternati user/assistant. Il modello impara a produrre le risposte assistant dato il contesto della conversazione.

Formato Messages di 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."}]}

Per dati di addestramento multi-turno, includi la conversazione completa con messaggi alternati user e assistant. Il modello impara il flusso della conversazione e come mantenere il contesto attraverso i turni.

Conversazioni Multi-turno di 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."}]}

Dataset HuggingFace con JSONL

La libreria datasets di HuggingFace supporta nativamente JSONL come formato di input. Puoi caricare file JSONL locali, fare streaming di dataset remoti e convertire tra formati facilmente. JSONL è il formato raccomandato per condividere dataset su HuggingFace Hub.

Usa la libreria datasets per caricare file JSONL in un oggetto Dataset. Questo fornisce accesso efficiente con memory-mapping, suddivisione train/test integrata e integrazione senza soluzione di continuità con la Trainer API.

Caricamento di Dataset 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

Converti qualsiasi dataset HuggingFace in formato JSONL per l'uso con altre pipeline di addestramento. Il metodo to_json scrive ogni esempio come una riga JSON separata.

Esportazione in 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')

Validazione e Pulizia dei Dati

La qualità dei dati di addestramento influisce direttamente sulle prestazioni del modello. JSON non valido, campi mancanti, esempi eccessivamente lunghi e voci duplicate possono tutti degradare i risultati del fine-tuning. Valida e pulisci sempre i tuoi file JSONL prima di avviare un'esecuzione di addestramento.

Questo script valida ogni riga del tuo file JSONL contro problemi comuni: JSON non valido, campi obbligatori mancanti, contenuto vuoto e lunghezza dei token. Eseguilo prima del caricamento per individuare i problemi in anticipo.

Validatore di Dati di Addestramento 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}')

Esempi di addestramento duplicati sprecano risorse computazionali e possono introdurre bias nel modello verso pattern sovra-rappresentati. Questo script rimuove i duplicati esatti basandosi sull'hash del contenuto di ogni riga.

Script di Deduplicazione
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')

Preparazione Dati su Larga Scala

I dataset di addestramento in produzione contengono spesso centinaia di migliaia o milioni di esempi. A questa scala, hai bisogno di pipeline automatizzate per il mescolamento, la suddivisione e lo sharding dei tuoi dati JSONL. Una preparazione adeguata previene problemi di addestramento come il catastrophic forgetting e garantisce esperimenti riproducibili.

Questo script mescola i tuoi dati in modo casuale e li suddivide in set di train e test. Il mescolamento è fondamentale perché i file JSONL sono spesso generati in ordine, e addestrare su dati ordinati può portare a una scarsa generalizzazione.

Pipeline di Suddivisione Train/Test e Mescolamento
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
)

Quando i dataset sono troppo grandi per un singolo file o hai bisogno di distribuire l'addestramento su più GPU, suddividi il file JSONL in blocchi più piccoli. Ogni shard può essere elaborato indipendentemente.

Sharding dei File per Addestramento Distribuito
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)

Valida i Tuoi Dati di Addestramento Online

Usa i nostri strumenti gratuiti basati su browser per validare, formattare e convertire i tuoi dati di addestramento JSONL prima di caricarli su OpenAI, Anthropic o HuggingFace.

Pronto a Preparare i Tuoi Dati di Addestramento?

Valida, formatta e ispeziona i tuoi file di addestramento JSONL direttamente nel browser. Nessun upload, nessuna registrazione, 100% privato.

Domande Frequenti

Dati di Addestramento JSONL — Formati OpenAI, Claude e Hu...