Nemo Curator

Подготовка данных для обучения LLM: дедупликация, фильтрация, маскирование персональных данных.

Метаданные навыка

ИсточникОпциональный (устанавливается по запросу) — hermes skills install official/mlops/nemo-curator
Путьoptional-skills/mlops/nemo-curator
Версия1.0.1
АвторOrchestra Research
ЛицензияMIT
Зависимостиnemo-curator, cudf, dask, rapids
Платформыlinux, macos
ТегиData Processing, NeMo Curator, Data Curation, GPU Acceleration, Deduplication, Quality Filtering, NVIDIA, RAPIDS, PII Redaction, Multimodal, LLM Training Data

Справочник: полный SKILL.md

инфо

Ниже приведено полное определение навыка, которое Hermes Agent загружает при его активации. Именно это видит агент как инструкции, когда навык включён.

NeMo Curator — GPU-ускоренная обработка данных

Инструментарий NVIDIA для подготовки высококачественных обучающих данных для LLM.

Когда использовать NeMo Curator

Используй NeMo Curator, если:

  • Готовишь обучающие данные для LLM из веб-скрейпинга (Common Crawl)
  • Нужна быстрая дедупликация (в 16 раз быстрее CPU)
  • Курируешь мультимодальные датасеты (текст, изображения, видео, аудио)
  • Фильтруешь низкокачественный или токсичный контент
  • Масштабируешь обработку данных на GPU-кластер

Производительность:

  • В 16 раз быстрее нечёткое дедуплицирование (8 ТБ RedPajama v2)
  • На 40% ниже TCO по сравнению с CPU-альтернативами
  • Почти линейное масштабирование по узлам GPU

Альтернативы:

  • datatrove — CPU-инструмент для обработки данных с открытым кодом
  • dolma — набор инструментов от Allen AI
  • Ray Data — универсальная обработка ML-данных (без акцента на подготовку датасетов)

Быстрый старт

Установка

# NeMo Curator 1.x installs with uv. Extras use hyphens (PyPI-normalized):
#   text-cuda12 / text-cpu (and image/video/audio/math variants), or `all`.

# Только текст (CUDA 12)
uv pip install "nemo-curator[text-cuda12]"

# Все модальности
uv pip install "nemo-curator[all]"

# Только текст на CPU (медленнее)
uv pip install "nemo-curator[text-cpu]"

Базовый пайплайн обработки текста

Переписанная мажорная версия (1.x): NeMo Curator переписали вокруг пайплайн-архитектуры со стадиями на базе Ray. Прежнего API 0.x — DocumentDataset плюс nemo_curator.modules.* / ScoreFilter / Modify, которые вызывались на датасете, — больше нет. В 1.x вы собираете ProcessingStage в Pipeline и запускаете его исполнителем. Набор стадий и импортов отличается по модальностям, поэтому примеры ниже в этом навыке считайте концептуальными (в стиле 0.x) и за точными API 1.x идите в актуальные quickstart и руководство по тексту, а не копируйте импорты дословно.

Как выглядит пайплайн 1.x (по quickstart из апстрима):

from nemo_curator.pipeline import Pipeline
from nemo_curator.stages.base import ProcessingStage
from nemo_curator.stages.resources import Resources
from nemo_curator.backends.xenna import XennaExecutor
from nemo_curator.core.client import RayClient

# 1. Define/compose stages (load -> filter -> dedupe -> classify -> write).
#    Each stage declares its own Resources (CPU cores, GPU memory, replicas).
pipeline = Pipeline(name="curation", stages=[...])

# 2. Run it with an executor (Ray-backed).
client = RayClient()
client.start()
pipeline.run(XennaExecutor())
client.stop()

Фрагменты в стиле 0.x в следующих разделах иллюстрируют концепции (фильтрация по качеству, точная, нечёткая и семантическая дедупликация, маскирование ПДн, фильтрация классификатором). За рабочим кодом 1.x сопоставьте каждую концепцию с соответствующей стадией из руководства по модальности.

Пайплайн обработки данных

Этап 1: фильтрация качества

from nemo_curator.filters import (
    WordCountFilter,
    RepeatedLinesFilter,
    UrlRatioFilter,
    NonAlphaNumericFilter
)

# Применяем 30+ эвристических фильтров
from nemo_curator import ScoreFilter

# Фильтр по количеству слов
dataset = dataset.filter(WordCountFilter(min_words=50, max_words=100000))

# Удаление повторяющегося контента
dataset = dataset.filter(RepeatedLinesFilter(max_repeated_line_fraction=0.3))

# Фильтр по доле URL
dataset = dataset.filter(UrlRatioFilter(max_url_ratio=0.2))

Этап 2: дедупликация

Точная дедупликация:

from nemo_curator.modules import ExactDuplicates

# Удаление полных дублей
deduped = ExactDuplicates(id_field="id", text_field="text")(dataset)

Нечёткая дедупликация (в 16 раз быстрее на GPU):

from nemo_curator.modules import FuzzyDuplicates

# Дедупликация через MinHash + LSH
fuzzy_dedup = FuzzyDuplicates(
    id_field="id",
    text_field="text",
    num_hashes=260,      # Параметры MinHash
    num_buckets=20,
    hash_method="md5"
)

deduped = fuzzy_dedup(dataset)

Семантическая дедупликация:

from nemo_curator.modules import SemanticDuplicates

# Дедупликация на основе эмбеддингов
semantic_dedup = SemanticDuplicates(
    id_field="id",
    text_field="text",
    embedding_model="sentence-transformers/all-MiniLM-L6-v2",
    threshold=0.8  # Порог косинусного сходства
)

deduped = semantic_dedup(dataset)

Этап 3: маскирование персональных данных

from nemo_curator.modules import Modify
from nemo_curator.modifiers import PIIRedactor

# Маскирование персональных данных
pii_redactor = PIIRedactor(
    supported_entities=["EMAIL_ADDRESS", "PHONE_NUMBER", "PERSON", "LOCATION"],
    anonymize_action="replace"  # или "redact"
)

redacted = Modify(pii_redactor)(dataset)

Этап 4: классификаторная фильтрация

from nemo_curator.classifiers import QualityClassifier

# Оценка качества документов
quality_clf = QualityClassifier(
    model_path="nvidia/quality-classifier-deberta",
    batch_size=256,
    device="cuda"
)

# Оставляем только высококачественные документы
high_quality = dataset.filter(lambda doc: quality_clf(doc["text"]) > 0.5)

GPU-ускорение

CPU против GPU: сравнение производительности

ОперацияCPU (16 ядер)GPU (A100)Ускорение
Нечёткая дедупликация (8 ТБ)120 часов7,5 часа16×
Точная дедупликация (1 ТБ)8 часов0,5 часа16×
Фильтрация качества2 часа0,2 часа10×

Масштабирование на несколько GPU

from nemo_curator import get_client
import dask_cuda

# Инициализация GPU-кластера
client = get_client(cluster_type="gpu", n_workers=8)

# Обработка на 8 GPU
deduped = FuzzyDuplicates(...)(dataset)

Мультимодальная обработка

Изображения

from nemo_curator.image import (
    AestheticFilter,
    NSFWFilter,
    CLIPEmbedder
)

# Оценка эстетики
aesthetic_filter = AestheticFilter(threshold=5.0)
filtered_images = aesthetic_filter(image_dataset)

# Обнаружение NSFW
nsfw_filter = NSFWFilter(threshold=0.9)
safe_images = nsfw_filter(filtered_images)

# Генерация CLIP-эмбеддингов
clip_embedder = CLIPEmbedder(model="openai/clip-vit-base-patch32")
image_embeddings = clip_embedder(safe_images)

Видео

from nemo_curator.video import (
    SceneDetector,
    ClipExtractor,
    InternVideo2Embedder
)

# Детекция сцен
scene_detector = SceneDetector(threshold=27.0)
scenes = scene_detector(video_dataset)

# Извлечение клипов
clip_extractor = ClipExtractor(min_duration=2.0, max_duration=10.0)
clips = clip_extractor(scenes)

# Генерация эмбеддингов
video_embedder = InternVideo2Embedder()
video_embeddings = video_embedder(clips)

Аудио

from nemo_curator.audio import (
    ASRInference,
    WERFilter,
    DurationFilter
)

# Транскрибирование через ASR
asr = ASRInference(model="nvidia/stt_en_fastconformer_hybrid_large_pc")
transcribed = asr(audio_dataset)

# Фильтр по WER (word error rate)
wer_filter = WERFilter(max_wer=0.3)
high_quality_audio = wer_filter(transcribed)

# Фильтр по длительности
duration_filter = DurationFilter(min_duration=1.0, max_duration=30.0)
filtered_audio = duration_filter(high_quality_audio)

Типовые сценарии

Обработка веб-скрейпа (Common Crawl)

from nemo_curator import ScoreFilter, Modify
from nemo_curator.filters import *
from nemo_curator.modules import *
from nemo_curator.datasets import DocumentDataset

# Загрузка данных Common Crawl
dataset = DocumentDataset.read_parquet("common_crawl/*.parquet")

# Пайплайн
pipeline = [
    # 1. Фильтрация качества
    WordCountFilter(min_words=100, max_words=50000),
    RepeatedLinesFilter(max_repeated_line_fraction=0.2),
    SymbolToWordRatioFilter(max_symbol_to_word_ratio=0.3),
    UrlRatioFilter(max_url_ratio=0.3),

    # 2. Фильтрация по языку
    LanguageIdentificationFilter(target_languages=["en"]),

    # 3. Дедупликация
    ExactDuplicates(id_field="id", text_field="text"),
    FuzzyDuplicates(id_field="id", text_field="text", num_hashes=260),

    # 4. Маскирование персональных данных
    PIIRedactor(),

    # 5. NSFW-фильтрация
    NSFWClassifier(threshold=0.8)
]

# Запуск
for stage in pipeline:
    dataset = stage(dataset)

# Сохранение
dataset.to_parquet("curated_common_crawl/")

Распределённая обработка

from nemo_curator import get_client
from dask_cuda import LocalCUDACluster

# Многоузловой GPU-кластер
cluster = LocalCUDACluster(n_workers=8)
client = get_client(cluster=cluster)

# Обработка большого датасета
dataset = DocumentDataset.read_parquet("s3://large_dataset/*.parquet")
deduped = FuzzyDuplicates(...)(dataset)

# Завершение работы
client.close()
cluster.close()

Бенчмарки производительности

Нечёткая дедупликация (8 ТБ RedPajama v2)

  • CPU (256 ядер): 120 часов
  • GPU (8× A100): 7,5 часа
  • Ускорение: 16×

Точная дедупликация (1 ТБ)

  • CPU (64 ядра): 8 часов
  • GPU (4× A100): 0,5 часа
  • Ускорение: 16×

Фильтрация качества (100 ГБ)

  • CPU (32 ядра): 2 часа
  • GPU (2× A100): 0,2 часа
  • Ускорение: 10×

Сравнение затрат

Обработка на CPU (AWS c5.18xlarge × 10):

  • Стоимость: $3.60/час × 10 = $36/час
  • Время для 8 ТБ: 120 часов
  • Итого: $4,320

Обработка на GPU (AWS p4d.24xlarge × 2):

  • Стоимость: $32.77/час × 2 = $65.54/час
  • Время для 8 ТБ: 7,5 часа
  • Итого: $491.55

Экономия: 89% ($3,828)

Поддерживаемые форматы данных

  • Вход: Parquet, JSONL, CSV
  • Выход: Parquet (рекомендуется), JSONL
  • WebDataset: TAR-архивы для мультимодальных данных

Примеры применения

Промышленные применения:

  • NVIDIA использовала NeMo Curator для подготовки обучающих данных Nemotron-4
  • Кураторованные открытые датасеты: RedPajama v2, The Pile

Ссылки

  • Filtering Guide — 30+ фильтров качества и эвристики
  • Deduplication Guide — точная, нечёткая и семантическая дедупликация

Ресурсы

перевод и редактура:

обновлено

⌕ ESC