This repository contains the implementation and experimental code for BloomScrub, a method for mitigating copyright infringement in large language model outputs through iterative quote detection and rewriting.
Paper: Certified Mitigation of Worst-Case LLM Copyright Infringement (EMNLP 2025)
ArXiv: arXiv:2504.16046
Authors: Jingyu Zhang, Jiacan Yu, Marc Marone, Benjamin Van Durme, Daniel Khashabi
- Scripts Guide - Documentation for all experiment scripts
- Original CoTaEval Documentation - Documentation for the base CoTaEval benchmark
BloomScrub addresses worst-case copyright risks in LLM generations by:
- Detecting verbatim quotes from copyrighted sources using Bloom filters (via Data Portraits/QUIP)
- Dynamically rewriting detected quotes using LLM-based paraphrasing
- Iteratively repeating this process until outputs fall within safe risk thresholds
- Abstaining from answering when rewriting cannot reduce risk sufficiently
This repository extends the CoTaEval benchmark for evaluating copyright takedown methods.
This repository builds on CoTaEval by adding:
- Multiple rewriting strategies for copyright mitigation
- Iterative rewriting with configurable rounds
- Dynamic rewriting with risk thresholds
- Abstention mechanism for high-risk cases
- NewsSpan: NYT articles dataset for copyright evaluation
- Gigaword/NYT: Additional news article datasets
- Processing scripts and evaluation data
- Question generation for utility evaluation
- Longform evaluation metrics (relevance, faithfulness, hallucination)
- Integration with external LLM judges (Llama 3.3, GPT-4, etc.)
- Context-aware decoding with FAISS-based retrieval
- Efficient similarity search for copyright filtering
- QUIP API integration for quote detection
- Infinigram API for frequency analysis
- PTB tokenizer utilities
- Helper functions for data processing
conda env create -f environment.yml
conda activate cotaevalcd cad/transformers_cad
pip install -e .
cd ../..pip install sentence-transformers faiss-cpuBloomScrub requires a running QUIP server for quote detection. See data-portraits/memfree_usage.md for setup instructions.
python main.py \
--model_name llama3.1-8b-newsspan-fullft-ep2 \
--num_test 1000 \
--context_len 200 \
--completion_len 200 \
--datatype newsspan \
--eval_infringement \
--no_context \
--intervention quip-rewrite-mix \
-r 5 \
-t 50 \
--rewrite_model llama3.1-8b-inst \
--dynamic_rewrite--intervention: Rewriting method (see below)-r, --rewrite_times: Maximum number of rewriting iterations (default: 5)-t, --abstain_threshold: Character threshold for abstention (default: 50)--dynamic_rewrite: Enable dynamic rewriting (stop when below threshold)--rewrite_model: Model to use for rewriting (default: same as base model)
BloomScrub supports multiple rewriting strategies:
-
quip-rewrite-mix(Recommended)- First iteration: General paraphrasing
- Subsequent iterations: Targeted rewriting of QUIP-detected quotes
- Balances fluency and copyright mitigation
-
quip-rewrite-para- Paraphrases text with special focus on quoted segments
- Uses natural language instructions to highlight quotes
-
quip-rewrite- Directly instructs model to rewrite verbatim quotes
- Provides explicit quoted segments to remove
-
rewrite-paraphrase- General paraphrasing without quote detection
- Baseline method for comparison
quip-rewrite-paramulti: Handles multiple quoted segments with highlightingquip-rewrite-multiple: Provides numbered list of quoted segmentsrewrite: System prompt-based rewritingrewrite-no-minor: Emphasizes substantial changes
# Run 5 rounds of rewriting, abstain if longest quote > 50 chars
python main.py \
--intervention quip-rewrite-mix \
-r 5 \
-t 50 \
--dynamic_rewrite \
...
# Use different model for rewriting
python main.py \
--model_name llama3.1-8b-newsspan-fullft-ep2 \
--rewrite_model llama3.1-8b-inst \
--intervention quip-rewrite-mix \
...Primary dataset for BloomScrub experiments:
# Full NewsSpan dataset (1000 examples)
python main.py --datatype newsspan ...
# Small debug set (100 examples)
python main.py --datatype newsspan100 ...# NewsQA (original CoTaEval)
python main.py --datatype newsqa ...
# Gigaword/NYT
python main.py --datatype nyt100 ...
python main.py --datatype nyt1000 ...Evaluate copyright risk using multiple metrics:
python main.py \
--eval_infringement \
--model_name llama3.1-8b-newsspan-fullft-ep2 \
--datatype newsspan \
--intervention quip-rewrite-mix \
-r 5 -t 50 --dynamic_rewriteMetrics computed:
- ROUGE-1, ROUGE-L
- Longest Common Subsequence (character and word)
- Average Common Subsequence
- Levenshtein Distance
- Semantic Similarity
- MinHash Similarity
# Compute all metrics
python process.py \
--input_dir res/output_res \
--output_dir res/output_res_processed \
--file_name <output_csv_file>
# Compute win rates
python winrate_compute.py \
--data_type newsspan \
--model_name llama3.1_8b \
--scenario memorizationEvaluate relevance, faithfulness, and hallucination:
# Relevance
bash scripts/longform_eval/relevance.sh
# Faithfulness
bash scripts/longform_eval/faithfulness.sh
# Hallucination
bash scripts/longform_eval/hallucination.shThese scripts use an external judge model (e.g., Llama 3.3-70B) to evaluate response quality.
python src/parse_judge_response.py \
<dataset_path_1> <dataset_path_2> ... \
--output_name relevance_evalPre-configured scripts for reproducing paper experiments:
# Baseline (no intervention)
bash scripts/inf_newsspan/none.sh
# System prompts
bash scripts/inf_newsspan/sysp-dbrx.sh
# MemFree (n-gram filtering)
bash scripts/inf_newsspan/memfree-n3.sh
bash scripts/inf_newsspan/memfree-n6.sh
# CAD-FAISS
bash scripts/inf_newsspan/cad-faiss-a1.sh
bash scripts/inf_newsspan/cad-faiss-a3.sh
# BloomScrub variants
bash scripts/inf_newsspan/quip-rewrite-mix_r5_t50_lm3rm.sh
bash scripts/inf_newsspan/quip-rewrite-para_r5_t50_lm3rm.sh
bash scripts/inf_newsspan/rewrite-paraphrase_r5_t50_lm3rm.shbash scripts/run_question_gen.shmain.py: Main entry point for infringement evaluationlib/decoding_intervention.py: Rewriting methods and CAD implementationlib/eval.py: Evaluation functions for different datasetsprocess.py: Metric computationwinrate_compute.py: Win rate analysis
src/quip_api.py: QUIP API integration for quote detectionsrc/build_faiss.py: FAISS index building for CAD-FAISSsrc/parse_judge_response.py: Parse LLM judge evaluationsinfinigram_api.py: Infinigram API for frequency analysisjack_utils.py: General utility functions
src/process_newsspan.py: NewsSpan dataset processingsrc/cond_perplexity.py: Perplexity-based filteringsrc/mapping_normalized_to_original.py: Text normalization utilities
prompt_templates/: JSON templates for evaluation promptsrelevance_eval.json: Relevance scoringfaithfulness_eval.json: Faithfulness scoringhallucination_eval.json: Hallucination detectionquestion_gen.json: Question generation
scripts/inf_newsspan/: Infringement evaluation scriptsscripts/longform_eval/: Utility evaluation scriptsscripts/create_bf_newsspan.sh: Bloom filter creation
eval_data/newsspan/: NewsSpan evaluation dataeval_data/gigaword/: NYT/Gigaword dataeval_data/newsqa/: Original CoTaEval NewsQA data
Edit modeltype2path in main.py to configure model paths:
modeltype2path = {
'llama3.1-8b-inst': "meta-llama/Llama-3.1-8B-Instruct",
'llama3.1-8b-newsspan-fullft-ep2': '/path/to/finetuned/model',
...
}Set in your shell or scripts:
export PROJ_DIR=/path/to/copyright-at-scale
export DATA_DIR=/path/to/data
export MODEL_DIR=/path/to/modelsError: QUIP API Request failed with exception: Connection refused
Solution: Start the QUIP server:
cd data-portraits
python easy_redis.py --start-from-dir /path/to/bloom_filterError: FileNotFoundError: faiss_index/newsspan_minilm-l6-v2/faiss.index
Solution: Build the FAISS index:
python src/build_faiss.py \
--dataset newsspan \
--output_dir faiss_index/newsspan_minilm-l6-v2If you use this code or the BloomScrub method, please cite:
@inproceedings{zhang2025bloomscrub,
title={Certified Mitigation of Worst-Case LLM Copyright Infringement},
author={Zhang, Jingyu and Yu, Jiacan and Marone, Marc and Van Durme, Benjamin and Khashabi, Daniel},
booktitle={Proceedings of the 2025 Conference on Empirical Methods in Natural Language Processing},
year={2025},
url={https://aclanthology.org/2025.emnlp-main.1784.pdf}
}This repository is built on the CoTaEval benchmark. We thank the original authors for their excellent work and for making their code publicly available. See COTAEVAL_ORIGINAL.md for the original CoTaEval documentation.
For questions or issues, please open a GitHub issue, or email the authors (see paper for email address).