Scan de Contamination Benchmark
Aperçu
S'entraîner sur des benchmarks est le péché cardinal du ML. Cette skill scanne vos données d'entraînement contre une liste d'exclusion curée de 60+ benchmarks en utilisant le chevauchement d'n-grammes (rapide, haute précision) et la similarité d'embedding (lent, haute précision).
Quand l'utiliser
Obligatoire avant chaque run d'entraînement. À exécuter sur les données de pré-entraînement, les données de tuning d'instructions et les données d'alignement RL.
Liste d'Exclusion
BENCHMARKS = {
"mmlu": {"name": "MMLU", "source": "huggingface://cais/mmlu"},
"hellaswag": {"name": "HellaSwag", "source": "huggingface://Rowan/hellaswag"},
"gsm8k": {"name": "GSM8K", "source": "huggingface://gsm8k"},
"humaneval": {"name": "HumanEval", "source": "huggingface://openai_humaneval"},
"boolq": {"name": "BoolQ", "source": "huggingface://boolq"},
"arc": {"name": "ARC", "source": "huggingface://ai2_arc"},
"winogrande": {"name": "Winogrande", "source": "huggingface://winogrande"},
"piqa": {"name": "PIQA", "source": "huggingface://piqa"},
"siqa": {"name": "Social IQA", "source": "huggingface://social_i_qa"},
"openbookqa": {"name": "OpenBookQA", "source": "huggingface://openbookqa"},
"squad": {"name": "SQuAD", "source": "huggingface://rajpurkar/squad"},
"natural_questions": {"name": "Natural Questions", "source": "huggingface://natural_questions"},
"triviaqa": {"name": "TriviaQA", "source": "huggingface://trivia_qa"},
"medqa": {"name": "MedQA", "source": "huggingface://bigbio/med_qa"},
"pubmedqa": {"name": "PubMedQA", "source": "huggingface://pubmed_qa"},
# Add all evaluation datasets used in your project
}
Scan de Chevauchement d'N-grammes
from collections import defaultdict
import hashlib
class ContaminationScanner:
def __init__(self, n=13):
self.n = n
self.benchmark_ngrams = {}
self._load_benchmarks()
def _ngrams(self, text):
tokens = text.split()
return set(" ".join(tokens[i:i+self.n]) for i in range(len(tokens) - self.n + 1))
def _load_benchmarks(self):
"""Load and hash all benchmark texts."""
for bid, bm in BENCHMARKS.items():
try:
ds = load_dataset(bm["source"], split="test")
all_ngrams = set()
for example in ds:
text = " ".join(str(v) for v in example.values() if isinstance(v, str))
all_ngrams.update(self._ngrams(text))
self.benchmark_ngrams[bid] = {
"ngrams": all_ngrams,
"n_examples": len(ds),
}
except Exception as e:
print(f"Could not load {bm['name']}: {e}")
def scan_example(self, text):
"""Check a single training example. Returns list of [benchmark, n_matches]."""
example_ngrams = self._ngrams(text)
if not example_ngrams:
return []
hits = []
for bid, bm_data in self.benchmark_ngrams.items():
overlap = len(example_ngrams & bm_data["ngrams"])
if overlap > 0:
hits.append({"benchmark": BENCHMARKS[bid]["name"], "n_matching_ngrams": overlap})
return hits
def scan_dataset(self, examples, threshold=5):
"""Scan full dataset. threshold = min matching ngrams to flag."""
contaminated = []
for i, example in enumerate(examples):
text = " ".join(str(v) for v in example.values() if isinstance(v, str))
hits = self.scan_example(text)
if any(h["n_matching_ngrams"] >= threshold for h in hits):
contaminated.append({"index": i, "hits": hits})
return contaminated
Scan de Similarité d'Embedding
Pour la contamination sémantique (benchmarks paraphrasés) :
from sentence_transformers import SentenceTransformer, util
model = SentenceTransformer("all-MiniLM-L6-v2")
def embedding_scan(text, benchmark_texts, threshold=0.85):
emb_text = model.encode(text)
emb_bench = model.encode(benchmark_texts)
scores = util.cos_sim(emb_text, emb_bench)[0]
hits = [(i, float(s)) for i, s in enumerate(scores) if s > threshold]
return hits
Rapport
# Rapport de Scan de Contamination
Date: [YYYY-MM-DD]
Taille n-grammes: 13
Benchmarks scannés: [N]
Exemples d'entraînement: [N]
Exemples contaminés: [N] (X,X%)
Exclus de l'entraînement: [N]
## Par Benchmark
| Benchmark | Contaminés | Action |
|-----------|-----------|--------|
| MMLU | 142 | Supprimés |
| HellaSwag | 18 | Supprimés |
Qualité
- Tous les benchmarks connus dans la liste d'exclusion.
- Scan n-grammes exécuté (rapide, obligatoire).
- Scan embedding exécuté sur un échantillon (lent, recommandé).
- Les exemples contaminés sont SUPPRIMÉS de l'entraînement, pas seulement signalés.
- Le scan est ré-exécuté après chaque mise à jour de données.