Датасеты для LLM: токенизация, фильтрация, шардирование
Цель страницы. Дать практический пайплайн подготовки корпусов под обучение/дообучение LLM: от сбора и нормализации текста до токенизации, фильтрации качества/языка, дедупликации и шардирования для быстрого чтения с диска/объектного хранилища.
Карта процесса (сверху вниз)
- Сбор и нормализация: HTML→текст, очистка артефактов.
- Определение языка: отфильтровать нецелевые языки.
- Фильтрация качества: длины, доля небуквенных символов, перплексия, стоп‑листы.
- PII и лицензии: базовая очистка персональных данных, учёт лицензий.
- Дедупликация: точная (hash) и near‑dup (MinHash/LSH).
- Токенизация: обучение/подбор токенайзера и массовая токенизация.
- Шардирование/стриминг: упаковка в WebDataset/MDS/JSONL‑шарды, индексы и манифесты.
- Сплиты и версии: train/val/test, фиксированные сиды, контроль утечек между сплитами.
- Каталог и мониторинг: README/manifest, счётчики токенов, отчёты качества.
Библиотеки, которые особенно пригодятся: Hugging Face Datasets (процессинг/стриминг), SentencePiece/tokenizers (токенизация), Trafilatura (HTML→текст), KenLM (перплексия), datasketch (MinHash), WebDataset/MDS (шарды).
Формат данных (рекомендуемая схема)
**JSONL (1 объект = 1 документ/сэмпл) Минимальный набор полей:
{"id":"...", "text":"...", "lang":"ru", "source":"commoncrawl", "url":"...",
"license":"cc-by-sa", "timestamp":"2024-10-05",
"quality":{"len_chars":1234,"nonalpha_ratio":0.06,"perplexity":163.2},
"hash":{"xxh3":"be1d..."},
"split":"train"}
JSON Lines подходит для потоковой обработки и совместим с datasets.load_dataset("json", streaming=True). Метод Dataset.to_json() по умолчанию пишет JSONL (lines=True). Сбор и нормализация текста - Из веба/архивов: Common Crawl (WARC/WET), далее извлечение основного текста без мусора.
- Извлечение текста: trafilatura показывает стабильные результаты на выжимке текста из HTML и удобна как CLI/библиотека.
Пример (Python):
from trafilatura import fetch_url, extract
html = fetch_url("https://example.com")
text = extract(html, favor_precision=True) # основной текст без boilerplate
Языковая фильтрация
- fastText LID‑176 / LID‑218 — лёгкая и быстрая идентификация языка (176/217 языков).
- CLD3 — нейросетевой детектор языка с биндингами для Python. Оба подхода широко используются в пайплайнах очистки веб‑корпусов.
Пример (fastText):
import fasttext
lid = fasttext.load_model("lid.176.bin")
lang, conf = lid.predict("Пример текста", k=1)
Фильтрация качества (включая перплексию)
- Правила/эвристики: минимальная/максимальная длина, доля небуквенных символов, повторяющиеся паттерны, стоп‑домены.
- Перплексия (KenLM): отбраковка «шумного» или «непохожего» на эталонный стиль текста (напр., Википедия) — классический шаг в CCNet‑подобных пайплайнах.
Пример (KenLM, Python):
import kenlm, math
lm = kenlm.Model("ru.arpa") # LM на чистом корпусе-референсе
def ppl(s):
ll = sum(score for score,_,_,_ in lm.full_scores(s, bos=True, eos=True))
n = len(s.split())
return math.exp(-ll / max(1,n))
``` **PII и лицензии**
- Для минимальной защиты персональных данных примените **Microsoft Presidio** (анализатор PII с набором готовых распознавателей), затем сохраните флаги/лог.
- Учитывайте **лицензию** источника (CC‑BY‑SA/CC‑BY/проprietary) и переносите её в метаданные записи.
**Дедупликация: точная и near‑duplicate**
- **Точная**: нормализованный текст → быстрый хеш (например, **xxHash/XXH3**) → удаление дублей.[](https://xxhash.com/?utm_source=chatgpt.com)
- **Почти дубликаты**: **MinHash + LSH** (библиотека datasketch) — вылавливает похожие тексты (по Жаккару), что критично для больших веб‑корпусов.[](https://ekzhu.com/datasketch/documentation.html?utm_source=chatgpt.com)
**Код‑набросок:**
import xxhash from datasketch import MinHash, MinHashLSH def exact_key(text): return xxhash.xxh3_128_hexdigest(text.encode("utf-8")) def shingles(text, n=5): tokens = text.split() return {" ".join(tokens[i:i+n]) for i in range(len(tokens)-n+1)} m = MinHash(num_perm=128) for sh in shingles(text): m.update(sh.encode("utf-8")) lsh = MinHashLSH(threshold=0.8, num_perm=128) lsh.insert(exact_key(text), m)
**Токенизация: выбор и массовая обработка**
- **SentencePiece** (Unigram/BPE) — стандарт для обучения собственных токенайзеров под RU/EN/мультиязык.
- **Hugging Face tokenizers/Transformers** — быстрые реализации и готовые пайплайны батч‑токенизации.[](https://github.com/google/sentencepiece?utm_source=chatgpt.com)
**Обучение SentencePiece (CLI):**
spm_train --input=corpus.txt --model_prefix=llm_spm --vocab_size=50000 --model_type=unigram --character_coverage=0.9995 --input_sentence_size=10000000 --shuffle_input_sentence=true --user_defined_symbols=[PAD],[BOS],[EOS]
**Массовая токенизация (Datasets → batched map):**
from datasets import load_dataset from transformers import AutoTokenizer ds = load_dataset("json", data_files={"train":"data.jsonl"}, streaming=True) tok = AutoTokenizer.from_pretrained("./llm_spm") # ваш SPM через HF обёртку def encode(batch): out = tok(batch["text"], truncation=True, max_length=4096) out["len"] = [len(x) for x in out["input_ids"]] return out tokenized = ds["train"].map(encode, batched=True)
**Шардирование и стриминг под обучение**
### Вариант A: WebDataset (tar‑шарды)
- Файлы одной записи делят общий **basename**; шардовка — data-{000000..000999}.tar, удобно для POSIX/объектных стораджей и последовательного I/O.[](https://github.com/webdataset/webdataset?utm_source=chatgpt.com)
- Плюсы: простые tar, поддержка стриминга из URL/объектного хранилища.[](https://pypi.org/project/webdataset/0.1.25/?utm_source=chatgpt.com)
**Пример записи токенов в tar‑шарды (схема):**
Сериализуйте токены и метаданные в .npz/.json, соберите в tar через webdataset
Имя образца: 12345.txt / 12345.json -> data-000123.tar
### Вариант B: Mosaic MDS (StreamingDataset)
Формат **MDS** ориентирован на высокую пропускную способность и быстрый «рандомный доступ» к сэмплам; удобно для долгих тренировок с возобновлением.
### Вариант C: JSONL/Parquet + HF Datasets (streaming)
load\_dataset(..., streaming=True) позволяет работать без полного скачивания, обрабатывая данные на лету.
### Практика размеров
- Шард 0.5–2 ГБ обычно даёт хороший баланс между размером файлов и параллелизмом воркеров.
- Храните **manifest** набора шардов и **снимок версии** (commit + сиды).
**Дополнительно:** HF Hub поддерживает WebDataset‑артефакты и инструкции по использованию.
**Сплиты, версии и защита от утечек**
- Разбейте источники **до** токенизации (train/val/test) и **контролируйте утечки**: никакие точные/near‑дубликаты не должны попадать в разные сплиты.
- Фиксируйте **сид генератора**, версии токенайзера/фильтров, список дат Common Crawl/внешних корпусов.
**Рецепт «как в CCNet, но для RU/EN»**
1. Взять сырые тексты (WET/собственные коллекции) → извлечь body‑текст (Trafilatura).
2. Языковая фильтрация (fastText/CLD3).
3. Качество: эвристики + перплексия KenLM (на референс‑корпусе).
4. Дедуп (xxHash) + near‑dup (MinHash/LSH).
5. Обучить/подобрать токенайзер (SentencePiece), токенизировать партиями.
6. Записать в шарды (WebDataset/MDS), подготовить manifest/README.
7. Прогнать sanity‑тесты качества на подвыборке. Подход вдохновлён оригинальным **CCNet** (дедуп, LID, перплексия‑фильтр под референс).
**Траблшутинг**
- **Медленный I/O / затыки диска.** Проверьте, что чтение идёт **крупными последовательными блоками** (тар‑шарды/WebDataset) и включен **prefetch** в DataLoader.
- **Сильно «шумный» корпус после чистки.** Ужесточите пороги перплексии, добавьте эвристику по доле небуквенных символов и стоп‑домены источников.
- **Смешение языков.** Комбинируйте fastText и CLD3; фильтруйте по уверенности/доле языка в документе.
- **Дубликаты в валидации.** Добавьте проверку hash/MinHash **на уровне всех сплитов**, а не только внутри train.
**Как это запускать в cloudcompute.ru**
- Используйте шаблоны из раздела **/solutions/templates/**:
– «**Data Prep (RU/EN)**»: Jupyter/SSH‑образ с datasets, trafilatura, fasttext, pycld3, kenlm, datasketch, webdataset, mosaicml‑streaming.
– «**Tokenizer**»: окружение с sentencepiece и transformers для обучения токенайзера и массовой токенизации.
- Для хранения и переноса см. **/solutions/storage-data/** (кэш, чекпоинты, перенос датасетов) и **/solutions/llm-training/distributed-io/**.
- Для контроля качества и метрик — **/solutions/llm-training/eval/**.
**Связанные страницы**
[База по обучению](/solutions/llm-training/)
[Смешанная точность](/solutions/llm-training/mixed-precision/)
Память/скорость: [/solutions/llm-training/memory-opt/](/solutions/llm-training/memory-opt/), [/solutions/llm-training/optimizers/](/solutions/llm-training/optimizers/)
I/O и хранение: [/solutions/llm-training/distributed-io/](/solutions/llm-training/distributed-io/), [/solutions/storage-data/](/solutions/storage-data/)
[Оценка качества](/solutions/llm-training/eval/)
Готовы запустить?
Запустить GPU-сервер