hf-datasets

Par mkurman · zorai

Chargez, streamez, traitez et publiez des datasets avec la bibliothèque HuggingFace datasets. Couvre le streaming basé sur Apache Arrow pour les grands datasets, les opérations map/filter, le découpage train/val/test, l'interleaving, la concaténation et le push vers le Hub.

npx skills add https://github.com/mkurman/zorai --skill hf-datasets

Jeux de données HuggingFace

Présentation

La bibliothèque datasets de HuggingFace offre un accès efficace en mémoire, basé sur Apache Arrow, à des dizaines de milliers de jeux de données publics et à vos données locales/distantes. Elle supporte le streaming pour les jeux de données qui ne tiennent pas en RAM et s'intègre directement aux tokenizers et boucles d'entraînement de transformers.

Quand l'utiliser

Utilisez cette skill quand :

  • Charger des jeux de données depuis le HuggingFace Hub ou des fichiers locaux (Parquet, JSONL, CSV, Arrow).
  • Faire du streaming sur des jeux de données trop volumineux pour la mémoire.
  • Appliquer du prétraitement, de la tokenization ou du filtrage à grande échelle avec .map() et .filter().
  • Pousser des jeux de données curés vers le Hub pour le partage ou la versioning.
  • Entrelancer ou concaténer plusieurs jeux de données.

Ne l'utilisez pas pour :

  • Les petits DataFrames pandas en mémoire avec < 100 K lignes — utilisez pandas directement.
  • L'inférence de modèle — utilisez les skills transformers ou vllm.
  • Le calcul d'embeddings — utilisez la skill embedding-analysis.

Installation

uv pip install datasets pyarrow huggingface_hub

Démarrage rapide

Chargement

from datasets import load_dataset, load_from_disk

# Depuis le Hub
dataset = load_dataset("imdb", split="train")

# Depuis des fichiers locaux
dataset = load_dataset("parquet", data_files="data/*.parquet", split="train")

# Depuis le disque (pré-sauvegardé)
dataset = load_from_disk("./my_saved_dataset")

# Streaming (ne charge jamais le jeu de données complet en mémoire)
dataset = load_dataset("c4", "en", split="train", streaming=True)

Inspection

print(dataset)                    # Infos du jeu de données
print(dataset.shape)              # (n_rows, n_columns)
print(dataset.features)           # Schéma
print(dataset[0])                 # Première ligne
print(dataset[:5])                # 5 premières lignes en dict
print(dataset.column_names)       # Liste des colonnes

Opérations principales

Map (Appliquer une fonction)

# Mapping basique
def add_length(example):
    example["text_length"] = len(example["text"])
    return example

dataset = dataset.map(add_length)

# Mapping par batch (plus rapide pour les gros jeux de données)
dataset = dataset.map(add_length, batched=True, batch_size=1000)

# Tokenization avec transformers
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")

def tokenize(batch):
    return tokenizer(batch["text"], truncation=True, padding="max_length", max_length=512)

dataset = dataset.map(tokenize, batched=True)

Filter

# Filtre de qualité : supprimer les exemples courts ou de faible qualité
dataset = dataset.filter(lambda x: len(x["text"]) > 100)
dataset = dataset.filter(lambda x: x["score"] > 0.5 if x["score"] is not None else False)

# Filtre de langue
from langdetect import detect
dataset = dataset.filter(lambda x: detect(x["text"]) == "en")

Split

# Split aléatoire
train_test = dataset.train_test_split(test_size=0.2, seed=42)
train = train_test["train"]
test = train_test["test"]

# Split stratifié (nécessite des labels de classe)
from datasets import ClassLabel, DatasetDict

split_dataset = dataset.class_encode_column("label").train_test_split(
    test_size=0.2, stratify_by_column="label", seed=42
)

Select, Shuffle, Sort

# Mélanger
dataset = dataset.shuffle(seed=42)

# Sélectionner des indices spécifiques
dataset = dataset.select(range(1000))

# Trier
dataset = dataset.sort("timestamp")

Concatenate et Interleave

from datasets import concatenate_datasets, interleave_datasets

# Concaténer
combined = concatenate_datasets([dataset_a, dataset_b])

# Entrelancer (mélange round-robin)
mixed = interleave_datasets([dataset_a, dataset_b], probabilities=[0.7, 0.3], seed=42)

Motif de pipeline de streaming

Pour les jeux de données qui ne tiennent pas en RAM, composez un pipeline de streaming :

dataset = load_dataset("bigcode/the-stack", "python", split="train", streaming=True)

# Filtrer d'abord (opération peu coûteuse)
dataset = dataset.filter(lambda x: len(x["content"]) > 500)

# Ensuite mapper (opération coûteuse seulement sur les données filtrées)
dataset = dataset.map(enrich_with_heuristics)

# Prenez seulement ce dont vous avez besoin
for i, example in enumerate(dataset):
    if i >= 10000:
        break
    process(example)

Sauvegarder et publier

Sauvegarder localement

# Sauvegarder sur le disque (format Arrow, rechargement plus rapide)
dataset.save_to_disk("./my_dataset")

# Exporter vers d'autres formats
dataset.to_parquet("./my_dataset.parquet")
dataset.to_json("./my_dataset.jsonl")
dataset.to_csv("./my_dataset.csv")

Pousser vers le HuggingFace Hub

from huggingface_hub import login
login()

dataset.push_to_hub("my-username/my-curated-dataset")

# Avec un DatasetDict (train/val/test)
dataset_dict = DatasetDict({
    "train": train_dataset,
    "validation": val_dataset,
    "test": test_dataset,
})
dataset_dict.push_to_hub("my-username/my-curated-dataset")

Conseils de performance

  1. Utilisez batched=True dans .map() — 10 à 100 fois plus rapide que le mapping au niveau des lignes.
  2. Filtrez avant de mapper — évitez les opérations coûteuses sur les données que vous allez rejeter.
  3. Utilisez le streaming + take pour l'exploration avant de vous engager dans un chargement complet.
  4. Préférez Parquet à JSONL/CSV pour le stockage sur disque — l'accès colonnaire est plus rapide.
  5. Définissez num_proc pour les opérations de map liées au CPU :
dataset = dataset.map(heavy_function, batched=True, num_proc=4)

Porte de qualité

Un pipeline de chargement de jeu de données est correct quand :

  • .features correspond au schéma attendu.
  • Le mode streaming fonctionne pour les jeux de données > RAM disponible.
  • Les opérations de filtrage sont déterministes (seed fixe si pertinent).
  • Le jeu de données est sauvegardé sur le disque ou poussé vers le Hub avec tous les splits.

Skills similaires