Подготовка данных для fine-tuning чат-моделей
Полный pipeline проверки и анализа JSONL-датасета перед тонкой настройкой: форматные ошибки, статистика токенов и оценка стоимости обучения.
Формат данных для fine-tuning
Каждый пример в JSONL-файле — это объект с ключом messages, аналогичный Chat Completions:
{
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is 2+2?"},
{"role": "assistant", "content": "4"}
]
}
Загрузка и базовая валидация
import json
from collections import defaultdict
with open("data/toy_chat_fine_tuning.jsonl", "r") as f:
dataset = [json.loads(line) for line in f]
format_errors = defaultdict(int)
for ex in dataset:
if not isinstance(ex, dict):
format_errors["data_type"] += 1
continue
messages = ex.get("messages")
if not messages:
format_errors["missing_messages_list"] += 1
continue
for msg in messages:
if "role" not in msg or "content" not in msg:
format_errors["message_missing_key"] += 1
if msg.get("role") not in ("system", "user", "assistant", "function"):
format_errors["unrecognized_role"] += 1
if not any(m["role"] == "assistant" for m in messages):
format_errors["example_missing_assistant_message"] += 1
if format_errors:
for k, v in format_errors.items():
print(f"{k}: {v}")
else:
print("No errors found")
Подсчёт токенов и оценка стоимости
import tiktoken, numpy as np
enc = tiktoken.get_encoding("cl100k_base")
def num_tokens(messages):
total = 3
for m in messages:
total += 3
for v in m.values():
total += len(enc.encode(str(v)))
return total
convo_lens = [num_tokens(ex["messages"]) for ex in dataset]
print(f"Mean tokens/example: {np.mean(convo_lens):.0f}")
n_too_long = sum(l > 16385 for l in convo_lens)
print(f"Examples over token limit: {n_too_long}")
# Оценка стоимости (3 эпохи по умолчанию)
total_billing = sum(min(16385, l) for l in convo_lens)
print(f"~{total_billing * 3} billing tokens для 3 эпох")
Правило большого пальца: 50–100 хорошо размеченных примеров дают заметный эффект; больше 1 000 — обычно достаточно для большинства задач. Всегда проверяйте датасет скриптом выше перед загрузкой в API.
Возьмите любой свой JSONL-файл диалогов, прогоните скрипт валидации и подсчёта токенов, исправьте все найденные ошибки и вычислите примерную стоимость обучения на 3 эпохи.
Скопируйте и адаптируйте под свой контекст. Текст в треугольных скобках — то, что нужно заменить.
Ты проверяешь JSONL-датасет для fine-tuning OpenAI. Запусти полный скрипт валидации из урока ft-data-prep. Выведи сводку: кол-во примеров, ошибки (если есть), мин/макс/среднее токенов, кол-во примеров выше лимита 16 385 токенов, и оценочную стоимость обучения за 3 эпохи по текущим ценам OpenAI.
Забывают проверить наличие хотя бы одного сообщения assistant в каждом примере; не учитывают, что примеры длиннее 16 385 токенов будут усечены, а не отброшены.
Используйте tiktoken до загрузки файла — это позволяет оценить стоимость без единого API-вызова. Минимальный эффективный датасет — 50 примеров; для улучшения тона/стиля иногда хватает даже 20.
Перед каждой новой задачей fine-tuning для верификации данных и предварительного расчёта бюджета.
Не нужно для инференса или prompt engineering без тонкой настройки.