Skip to main content

distributed-curator

Partition-aware MinHash LSH deduplication library for large-scale text data curation on Apache Spark.

Headline

2.53 billion documents deduplicated on a 63-node EMR cluster for ~$620 using partition-aware MinHash LSH — zero shuffle during local deduplication.

Quick Start

pip install distributed-curator
from distributed_curator import partition_aware_deduplicate, get_jar_path
from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .config("spark.jars", get_jar_path()) \
    .getOrCreate()

# input_df must have a "doc_id" column and a text column
result = partition_aware_deduplicate(
    spark=spark,
    input_df=df,
    text_column="text",
    similarity_threshold=0.8,
    num_partitions=1000,
)

# result has original columns + "representative_id" and "is_duplicate"
unique_docs = result.filter(~result.is_duplicate)

How It Works

The pipeline assigns documents to partitions based on LSH band hashes so that similar documents are co-located. All comparisons happen locally within partitions with no shuffle, then a two-phase union-find merges components across partition boundaries.

Step What happens Shuffle?
1. MinHash Cython/NumPy SIMD computes signatures via pandas_udf No
2. Partition assignment Scala UDF maps LSH bands to partition IDs No
3. Identity repartition Documents move to assigned partitions Yes (once)
4. Local dedup Scala mapPartitions finds similar pairs within each partition No
5a. Local union-find Scala partition-local connected components No
5b. Global union-find Driver-side union-find with Eclipse Collections LongLongHashMap No
6. Mark duplicates Join results back to input Yes (once)

For a detailed architecture walkthrough, see docs/architecture.md.

Benchmark Results

All benchmarks run on Common Crawl WET files (CC-MAIN-2024-22) with similarity_threshold=0.9, num_hashes=64, num_bands=8.

Scale Documents Duplicates Rate Cluster Time Cost
9K WET 253M 55M 21.82% 9× r5ad.8xlarge ~1.5 hr ~$50
90K WET 2.53B 767M 30.39% 63× r6gd.8xlarge ~4.5 hr ~$620

Configuration

partition_aware_deduplicate(
    spark,                          # SparkSession
    input_df,                       # DataFrame with doc_id + text columns
    text_column="text",             # name of the text column
    similarity_threshold=0.8,       # Jaccard similarity threshold (0.0–1.0)
    num_hashes=64,                  # MinHash signature length
    num_bands=8,                    # LSH bands (num_hashes must be divisible by num_bands)
    num_partitions=1000,            # number of partitions for dedup
    ngram=9,                        # character n-gram size for shingling
    checkpoint_path=None,           # [optional] S3/HDFS path to cache intermediate results
    enable_diagnostics=False,       # [optional] enable driver memory logging and heap capture
)

When to tune:

  • similarity_threshold: lower catches more near-duplicates, higher is stricter. 0.8–0.9 is typical for web text.
  • num_partitions: set to spark.sql.shuffle.partitions. More partitions = less memory per partition but more overhead.
  • num_bands / num_hashes: controls the LSH probability curve. More bands = higher recall but more comparisons. num_hashes must be divisible by num_bands.
  • checkpoint_path: recommended for runs over 1K WET files. Saves MinHash signatures so you don't recompute on retry.
  • ngram: 9 works well for English web text. Shorter n-grams increase recall but reduce precision.

Version Compatibility

Component Supported Planned
PySpark 3.5.x 4.0+
Python 3.9, 3.10, 3.11, 3.12
Scala 2.12
AWS EMR 7.5–7.12 (Spark 3.5)
Java 8, 11, 17 (runtime)

The Scala UDF JAR is compiled against Spark 3.5. Spark 4.0 support requires recompilation due to breaking API changes in StructType.

Documentation

  • Architecture — detailed pipeline walkthrough, design decisions, and performance characteristics
  • EMR Deployment — Terraform setup, bootstrap configuration, and spark-submit examples
  • Contributing — development setup, running tests, and how to submit changes

License

Apache License 2.0 — see LICENSE for details.

Metadata

Release files for distributed-curator 0.1.6

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

Source distribution (sdist)

Source distribution for distributed-curator 0.1.6
File Size Uploaded
distributed_curator-0.1.6.tar.gz 15.5 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for distributed-curator 0.1.6
File Interpreter ABI Platform
distributed_curator-0.1.6-cp39-cp39-macosx_26_0_arm64.whl CPython 3.9 CPython 3.9 macOS 26.0+ ARM64 Details

Total release size: 31.0 MB

Release files / distributed_curator-0.1.6.tar.gz

Download URL distributed_curator-0.1.6.tar.gz
Size 15.5 MB
Tags Source
SHA-256 checksum
How to use checksums
4ecfa510046964143fa6c204cee3cdacead99d39aebfac99c5f9468ef33770fa
BLAKE2b-256 checksum
How to use checksums
791409dd37fe577d19e7368f713426d6bf639e05ce5401e23f2c8c0830a38b28
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release files / distributed_curator-0.1.6-cp39-cp39-macosx_26_0_arm64.whl

Download URL distributed_curator-0.1.6-cp39-cp39-macosx_26_0_arm64.whl
Size 15.5 MB
Tags CPython 3.9 macOS 26.0+ ARM64
SHA-256 checksum
How to use checksums
3ea7994501f4f51e3cc4bc431d5e60d9b6568ff584d733a40841336b081f5de7
BLAKE2b-256 checksum
How to use checksums
5cb21cd2ba73d35ea8608472c7129a6fb0f328c5b7a06c9eedc6c94302a7c1fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release history Release notifications | RSS feed

This release

0.1.6 This release

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.2

2 release files

0.1.1

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