Module: FT06 — Dedup, Filter, Decontaminate Diagram count: 5 Tool: Mermaid (primary). Each diagram validated in Mermaid Live Editor.
Type: Sequential funnel Purpose: The single diagram that anchors the module. Memorize this sequence. Reading the diagram: Top to bottom. Every stage is a filter that removes samples. The samples you remove matter as much as the ones you keep.
flowchart TD
Gen["GENERATE / COLLECT\nraw noisy corpus"]
Min["MinHash dedup\nnear-duplicate text\n(datasketch / text-dedup)"]
Sem["Semantic dedup\nembedding-cluster paraphrases\n(sentence-transformers)"]
Ppl["Perplexity filter\nsmall LM flags garbage\n(kenlm)"]
Dec["Decontaminate\nremove benchmark items\n(MMLU / GSM8K / HumanEval)"]
Qual["Quality subset\ndiverse high-quality slice\n(cluster-and-select)"]
Cur["Curriculum order\neasy -> hard (optional)"]
Train["TRAIN"]
Gen --> Min --> Sem --> Ppl --> Dec --> Qual --> Cur --> Train
style Gen fill:#14141f,stroke:#5eead4,stroke-width:1.5px,color:#e4e4e8
style Min fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style Sem fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style Ppl fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style Dec fill:#14141f,stroke:#f08080,stroke-width:1.5px,color:#e4e4e8
style Qual fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style Cur fill:#14141f,stroke:rgba(255,255,255,0.12),color:#9494a0
style Train fill:#14141f,stroke:#5eead4,stroke-width:1.5px,color:#e4e4e8
Type: Pipeline / mechanism Purpose: How near-duplicate detection works at scale. Four steps. Reading the diagram: Left to right. Shingle → Hash → Band → Verify. The LSH banding is the trick that makes this scale beyond O(n²).
flowchart LR
Doc1["Document A\n'the quick brown fox'"]
Doc2["Document B\n'the quick brown cat'"]
subgraph S1["Step 1: SHINGLE"]
SH["3-word overlapping n-grams\n{the quick brown, quick brown fox}"]
end
subgraph S2["Step 2: HASH (MinHash signature)"]
MH["k independent hash fns\nkeep min hash per fn\n-> k-length signature"]
end
subgraph S3["Step 3: BAND (LSH)"]
BAND["chop signature into b bands of r rows\nhash each band\nshared band hash -> candidate pair"]
end
subgraph S4["Step 4: VERIFY"]
VER["compute actual Jaccard\n>= threshold (0.8-0.9)\n-> drop as duplicate"]
end
Doc1 --> SH
Doc2 --> SH
SH --> MH --> BAND --> VER
style Doc1 fill:#14141f,stroke:rgba(255,255,255,0.12),color:#e4e4e8
style Doc2 fill:#14141f,stroke:rgba(255,255,255,0.12),color:#e4e4e8
style S1 fill:#08080c,stroke:rgba(94,234,212,0.4),color:#5eead4
style S2 fill:#08080c,stroke:rgba(94,234,212,0.4),color:#5eead4
style S3 fill:#08080c,stroke:rgba(94,234,212,0.4),color:#5eead4
style S4 fill:#08080c,stroke:#5eead4,stroke-width:1.5px,color:#5eead4
Type: Side-by-side scan Purpose: How benchmark contamination is detected and removed. Non-negotiable for honest evals. Reading the diagram: Two parallel inputs (your training set + the benchmark test sets). Both are reduced to n-gram sets. The intersection is the contaminated samples. Drop them.
flowchart LR
Bench["Benchmark test sets\nMMLU · GSM8K · HumanEval · MT-Bench"]
Train["Your training set\nraw or partially-cleaned"]
subgraph NG["Extract n-grams (n=13 text, n=8 code)"]
BN["benchmark n-gram set"]
TN["training n-gram set"]
end
Isec["Intersection\n= contaminated samples"]
Clean["Clean training set\n(eval is now honest)"]
Bench --> NG
Train --> NG
BN --> Isec
TN --> Isec
Isec -.remove.-> Clean
style Bench fill:#14141f,stroke:#f08080,stroke-width:1.5px,color:#e4e4e8
style Train fill:#14141f,stroke:rgba(255,255,255,0.12),color:#e4e4e8
style NG fill:#08080c,stroke:rgba(240,128,128,0.4),color:#f08080
style Isec fill:#14141f,stroke:#f08080,stroke-width:1.5px,color:#f08080
style Clean fill:#14141f,stroke:#5eead4,stroke-width:1.5px,color:#e4e4e8
Type: Quantitative funnel Purpose: How a raw corpus shrinks through the pipeline. A typical messy set loses 30-60% of samples between generate and train — and that is correct. Reading the diagram: Top to bottom. The numbers are illustrative (your retention will vary) but the shape is real: every stage removes samples, and the final clean set is materially smaller than the raw input.
flowchart TD
A["10,000 raw samples\n(generate / collect)"]
B["8,200 after MinHash dedup\n(-1,800 near-duplicates)"]
C["6,800 after semantic dedup\n(-1,400 paraphrases)"]
D["6,100 after perplexity filter\n(-700 garbage)"]
E["5,950 after decontamination\n(-150 benchmark items)"]
F["2,000 final quality subset\n(diverse, high-quality slice)"]
T["TRAIN\nretention 20% of raw"]
A --> B --> C --> D --> E --> F --> T
style A fill:#14141f,stroke:#5eead4,stroke-width:1.5px,color:#e4e4e8
style B fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style C fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style D fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style E fill:#14141f,stroke:#f08080,color:#e4e4e8
style F fill:#14141f,stroke:#5eead4,stroke-width:1.5px,color:#e4e4e8
style T fill:#14141f,stroke:#5eead4,stroke-width:2px,color:#5eead4
Type: Distribution / threshold Purpose: Why dropping high-perplexity samples removes garbage AND mitigates catastrophic forgetting. Reading the diagram: The x-axis is sample perplexity (low = expected by the small clean-trained LM; high = surprising). The right tail (high perplexity) is dropped. It overlaps with both "garbage" and "tokens that push weights hard" — the NeurIPS 2025 link.
flowchart LR
subgraph Dist["Perplexity distribution of training samples"]
direction LR
Low["LOW perplexity\nmodel expected it\nclean, well-formed\n-> keep"]
Mid["MID perplexity\nnormal variation\n-> keep"]
High["HIGH perplexity\nmodel surprised\nGARBAGE / OCR / noise\n+ tokens that push weights hard\n-> DROP"]
end
Cut["cutoff: top ~10% dropped"]
Low --> Mid --> High
High -.-> Cut
style Low fill:#14141f,stroke:#82e0aa,color:#e4e4e8
style Mid fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style High fill:#14141f,stroke:#f08080,stroke-width:1.5px,color:#e4e4e8
style Cut fill:#08080c,stroke:rgba(240,128,128,0.5),stroke-dasharray: 4 2,color:#f08080
style Dist fill:#08080c,stroke:rgba(255,255,255,0.06),color:#9494a0
#14141f panel fill, #5eead4 accent for primary, #f08080 (danger) for the decontamination / garbage signal, rgba(255,255,255,0.12) for secondary borders, #e4e4e8 / #9494a0 for text.flowchart with subgraphs) supported in current Mermaid (v10.4+).#f08080 danger accent — these are the "non-negotiable" stages of the pipeline.# Diagrams — Module FT06: Dedup, Filter, Decontaminate
**Module**: FT06 — Dedup, Filter, Decontaminate
**Diagram count**: 5
**Tool**: Mermaid (primary). Each diagram validated in [Mermaid Live Editor](https://mermaid.live).
---
## Diagram 1 — The Full Clean Pipeline
**Type**: Sequential funnel
**Purpose**: The single diagram that anchors the module. Memorize this sequence.
**Reading the diagram**: Top to bottom. Every stage is a filter that removes samples. The samples you *remove* matter as much as the ones you keep.
```mermaid
flowchart TD
Gen["GENERATE / COLLECT\nraw noisy corpus"]
Min["MinHash dedup\nnear-duplicate text\n(datasketch / text-dedup)"]
Sem["Semantic dedup\nembedding-cluster paraphrases\n(sentence-transformers)"]
Ppl["Perplexity filter\nsmall LM flags garbage\n(kenlm)"]
Dec["Decontaminate\nremove benchmark items\n(MMLU / GSM8K / HumanEval)"]
Qual["Quality subset\ndiverse high-quality slice\n(cluster-and-select)"]
Cur["Curriculum order\neasy -> hard (optional)"]
Train["TRAIN"]
Gen --> Min --> Sem --> Ppl --> Dec --> Qual --> Cur --> Train
style Gen fill:#14141f,stroke:#5eead4,stroke-width:1.5px,color:#e4e4e8
style Min fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style Sem fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style Ppl fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style Dec fill:#14141f,stroke:#f08080,stroke-width:1.5px,color:#e4e4e8
style Qual fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style Cur fill:#14141f,stroke:rgba(255,255,255,0.12),color:#9494a0
style Train fill:#14141f,stroke:#5eead4,stroke-width:1.5px,color:#e4e4e8
```
---
## Diagram 2 — MinHash + LSH Mechanism
**Type**: Pipeline / mechanism
**Purpose**: How near-duplicate detection works at scale. Four steps.
**Reading the diagram**: Left to right. Shingle → Hash → Band → Verify. The LSH banding is the trick that makes this scale beyond O(n²).
```mermaid
flowchart LR
Doc1["Document A\n'the quick brown fox'"]
Doc2["Document B\n'the quick brown cat'"]
subgraph S1["Step 1: SHINGLE"]
SH["3-word overlapping n-grams\n{the quick brown, quick brown fox}"]
end
subgraph S2["Step 2: HASH (MinHash signature)"]
MH["k independent hash fns\nkeep min hash per fn\n-> k-length signature"]
end
subgraph S3["Step 3: BAND (LSH)"]
BAND["chop signature into b bands of r rows\nhash each band\nshared band hash -> candidate pair"]
end
subgraph S4["Step 4: VERIFY"]
VER["compute actual Jaccard\n>= threshold (0.8-0.9)\n-> drop as duplicate"]
end
Doc1 --> SH
Doc2 --> SH
SH --> MH --> BAND --> VER
style Doc1 fill:#14141f,stroke:rgba(255,255,255,0.12),color:#e4e4e8
style Doc2 fill:#14141f,stroke:rgba(255,255,255,0.12),color:#e4e4e8
style S1 fill:#08080c,stroke:rgba(94,234,212,0.4),color:#5eead4
style S2 fill:#08080c,stroke:rgba(94,234,212,0.4),color:#5eead4
style S3 fill:#08080c,stroke:rgba(94,234,212,0.4),color:#5eead4
style S4 fill:#08080c,stroke:#5eead4,stroke-width:1.5px,color:#5eead4
```
---
## Diagram 3 — Decontamination Flow
**Type**: Side-by-side scan
**Purpose**: How benchmark contamination is detected and removed. Non-negotiable for honest evals.
**Reading the diagram**: Two parallel inputs (your training set + the benchmark test sets). Both are reduced to n-gram sets. The intersection is the contaminated samples. Drop them.
```mermaid
flowchart LR
Bench["Benchmark test sets\nMMLU · GSM8K · HumanEval · MT-Bench"]
Train["Your training set\nraw or partially-cleaned"]
subgraph NG["Extract n-grams (n=13 text, n=8 code)"]
BN["benchmark n-gram set"]
TN["training n-gram set"]
end
Isec["Intersection\n= contaminated samples"]
Clean["Clean training set\n(eval is now honest)"]
Bench --> NG
Train --> NG
BN --> Isec
TN --> Isec
Isec -.remove.-> Clean
style Bench fill:#14141f,stroke:#f08080,stroke-width:1.5px,color:#e4e4e8
style Train fill:#14141f,stroke:rgba(255,255,255,0.12),color:#e4e4e8
style NG fill:#08080c,stroke:rgba(240,128,128,0.4),color:#f08080
style Isec fill:#14141f,stroke:#f08080,stroke-width:1.5px,color:#f08080
style Clean fill:#14141f,stroke:#5eead4,stroke-width:1.5px,color:#e4e4e8
```
---
## Diagram 4 — The Data-Quality Funnel
**Type**: Quantitative funnel
**Purpose**: How a raw corpus shrinks through the pipeline. A typical messy set loses 30-60% of samples between generate and train — and that is correct.
**Reading the diagram**: Top to bottom. The numbers are illustrative (your retention will vary) but the shape is real: every stage removes samples, and the final clean set is materially smaller than the raw input.
```mermaid
flowchart TD
A["10,000 raw samples\n(generate / collect)"]
B["8,200 after MinHash dedup\n(-1,800 near-duplicates)"]
C["6,800 after semantic dedup\n(-1,400 paraphrases)"]
D["6,100 after perplexity filter\n(-700 garbage)"]
E["5,950 after decontamination\n(-150 benchmark items)"]
F["2,000 final quality subset\n(diverse, high-quality slice)"]
T["TRAIN\nretention 20% of raw"]
A --> B --> C --> D --> E --> F --> T
style A fill:#14141f,stroke:#5eead4,stroke-width:1.5px,color:#e4e4e8
style B fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style C fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style D fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style E fill:#14141f,stroke:#f08080,color:#e4e4e8
style F fill:#14141f,stroke:#5eead4,stroke-width:1.5px,color:#e4e4e8
style T fill:#14141f,stroke:#5eead4,stroke-width:2px,color:#5eead4
```
---
## Diagram 5 — Perplexity Filtering Concept
**Type**: Distribution / threshold
**Purpose**: Why dropping high-perplexity samples removes garbage AND mitigates catastrophic forgetting.
**Reading the diagram**: The x-axis is sample perplexity (low = expected by the small clean-trained LM; high = surprising). The right tail (high perplexity) is dropped. It overlaps with both "garbage" and "tokens that push weights hard" — the NeurIPS 2025 link.
```mermaid
flowchart LR
subgraph Dist["Perplexity distribution of training samples"]
direction LR
Low["LOW perplexity\nmodel expected it\nclean, well-formed\n-> keep"]
Mid["MID perplexity\nnormal variation\n-> keep"]
High["HIGH perplexity\nmodel surprised\nGARBAGE / OCR / noise\n+ tokens that push weights hard\n-> DROP"]
end
Cut["cutoff: top ~10% dropped"]
Low --> Mid --> High
High -.-> Cut
style Low fill:#14141f,stroke:#82e0aa,color:#e4e4e8
style Mid fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
style High fill:#14141f,stroke:#f08080,stroke-width:1.5px,color:#e4e4e8
style Cut fill:#08080c,stroke:rgba(240,128,128,0.5),stroke-dasharray: 4 2,color:#f08080
style Dist fill:#08080c,stroke:rgba(255,255,255,0.06),color:#9494a0
```
---
## Validation notes
- All five diagrams use the course design system colors: `#14141f` panel fill, `#5eead4` accent for primary, `#f08080` (danger) for the decontamination / garbage signal, `rgba(255,255,255,0.12)` for secondary borders, `#e4e4e8` / `#9494a0` for text.
- Paste each into [Mermaid Live Editor](https://mermaid.live) to render. All use stable Mermaid syntax (`flowchart` with subgraphs) supported in current Mermaid (v10.4+).
- For the slide deck (artifact 03), these are rendered as static captures from Mermaid Live, inlined into reveal.js.
- The decontamination diagram (Diagram 3) and the funnel (Diagram 4) deliberately use the `#f08080` danger accent — these are the "non-negotiable" stages of the pipeline.