Skip to main content

RupuData

Follow the path of your data.

RupuData answers an uncomfortable question: does my training data overlap with data I use to evaluate my model?

Local CLI for duplicates, train/eval overlap, and benchmark overlap signals, with deterministic JSON reports. Technical signals, not legal certification.

Install

Requires Python 3.9+.

pip install rupudata
rupudata --help

Quick start

rupudata scan dataset.jsonl
rupudata compare train.jsonl eval.jsonl
rupudata compare train.jsonl eval.jsonl --text-field question
rupudata compare train.jsonl eval.jsonl --fail-on-overlap
rupudata benchmark-check train.jsonl --benchmark gsm8k
rupudata benchmark-check train.jsonl --benchmark gsm8k --fail-on-overlap

compare defaults to full records. Use --text-field when only one column should participate in matching.

--fail-on-overlap exits 2 when exact or normalized overlap is found (CI gate). Exit 1 is reserved for errors. The JSON report is written either way.

Real-world example (GSM8K)

Export train/test from Hugging Face (openai/gsm8k) to JSONL. Each line looks like:

{"question": "Natalia sold clips to 48 of her friends in April…", "answer": "72"}
pip install datasets
python - <<'PY'
from datasets import load_dataset
import json

def write_jsonl(path, split, key="question"):
    rows = load_dataset("openai/gsm8k", "main", split=split)
    with open(path, "w", encoding="utf-8") as f:
        for row in rows:
            f.write(json.dumps({key: row[key]}, ensure_ascii=False) + "\n")
    print(split, len(rows), "->", path)

write_jsonl("gsm8k_train.jsonl", "train")
write_jsonl("gsm8k_test.jsonl", "test")
PY

Path A — inject three test questions (overlap)

head -n 3 gsm8k_test.jsonl > leak.jsonl
cat gsm8k_train.jsonl >> leak.jsonl

rupudata benchmark-check leak.jsonl \
  --benchmark gsm8k \
  --reference gsm8k_test.jsonl
╭───────────────────────────────╮
│ RupuData v0.7.0               │
│ Follow the path of your data. │
╰───────────────────────────────╯

Benchmark check: leak.jsonl vs GSM8K

Benchmark
──────────────────────────────
  Benchmark                GSM8K
  Reference                user_reference
  Benchmark records        1,319
  Dataset rows             7,476
  Benchmark fingerprint    rupu:a75016197e210681

Overlap
──────────────────────────────
  Exact matches                  3
  Normalized matches             3
  Status                         OVERLAP_DETECTED
  Evidence pairs (exact)         3
  Evidence pairs (normalized)    3

Evidence (sample)
──────────────────────────────
  dataset_row    reference_row    field
  0              0                question
  1              1                question
  2              2                question

3 exact GSM8K test-set overlaps detected under the configured matching methodology.

Path B — clean train (no leak)

rupudata compare gsm8k_train.jsonl gsm8k_test.jsonl --text-field question
rupudata benchmark-check gsm8k_train.jsonl --benchmark gsm8k --reference gsm8k_test.jsonl
rupudata scan gsm8k_train.jsonl

→ compare / benchmark-check: 0 overlaps, NO_OVERLAP_DETECTED.

→ scan (7,473 rows): 0 exact duplicates; 2 lexical near-dupe pairs. JSON evidence:

"near_duplicates": {
  "pairs": 2,
  "records_flagged": 4,
  "evidence": [
    { "left": 1174, "right": 7233, "jaccard": 0.8688, "field": "question" },
    { "left": 2483, "right": 6691, "jaccard": 0.9262, "field": "question" }
  ],
  "evidence_truncated": false
}
Rows Jaccard What differs
11747233 0.87 Same “Martha / butterflies” template; different totals and which color is asked
24836691 0.93 Same gift / cassette / headphone word problem; only the name (JosieAmanda)
Record 2483
  Josie received $50 as a gift. She plans to buy two cassette tapes…

Record 6691
  Amanda received $50 as a gift. She plans to buy two cassette tapes…

Similarity (Jaccard on character shingles): 0.93

That is lexical near-duplication. RupuData does not claim the questions are the same math problem for a student, nor plagiarism — only that the strings share enough character shingles under the configured threshold.

Benchmark reference: demo sample vs real audit

Warning: Without --reference, default gsm8k uses a tiny packaged sample. A NO_OVERLAP_DETECTED against that sample does not mean your dataset is free of GSM8K. For an actual audit, pass the real export with --reference.

rupudata benchmark-check train.jsonl --benchmark gsm8k --reference /path/to/gsm8k.jsonl

Try the packaged examples

git clone https://github.com/EmanuelCorreaAR/rupudata.git
cd rupudata
pip install -e .
rupudata compare examples/train.jsonl examples/eval.jsonl
rupudata benchmark-check examples/train_with_gsm8k_overlap.jsonl --benchmark gsm8k
rupudata scan examples/near_dupes.jsonl --near-duplicate-threshold 0.85

Status

0.8.0--fail-on-overlap for CI/pipelines on compare and benchmark-check.

Not in this release (on purpose): semantic / paraphrase matching, streaming multi-GB scans, provenance/license detectors.

Next: driven by real usage.

Development

git clone https://github.com/EmanuelCorreaAR/rupudata.git
cd rupudata
pip install -e ".[dev]"
pytest
python -m build

Technical audit contract

Methodology, matching units, and evidence shapes: docs/AUDIT.md.

License

Apache License 2.0

Release files for rupudata 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rupudata 0.8.0
File Size Uploaded
rupudata-0.8.0.tar.gz 37.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rupudata 0.8.0
File Interpreter ABI Platform
rupudata-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 71.4 kB

Release files / rupudata-0.8.0.tar.gz

Download URL rupudata-0.8.0.tar.gz
Size 37.0 kB
Tags Source
SHA-256 checksum
How to use checksums
3356f10fb7dbbca5474953b7f0da2560e8eeab318a04662912c8d4a9c7ac17d5
BLAKE2b-256 checksum
How to use checksums
636722d300d3af92e3a91ca55a7317a6c4820ecf0963c2993e1ea3b258fc3aa1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / rupudata-0.8.0-py3-none-any.whl

Download URL rupudata-0.8.0-py3-none-any.whl
Size 34.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0e4d0391b1b415b4d90378bf83c49907923c5bc8d610c557dcd897893a06eabc
BLAKE2b-256 checksum
How to use checksums
b2ad8609b44967329617ad4f82f46b1b557c23df2f6ab83351310fdd7143cdef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

0.9.0

2 release files

0.8.1

2 release files

This release

0.8.0 This release

2 release files

0.7.0

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page