# 🧩 Summary
## 场景
:训练 LLM 时,数据集可能有几十亿条文本:
- 直接逐对比较相似度 → 计算量爆炸 O(n²)
- 需要快速找出"几乎重复"的文本并删除
```Java
小红书数据特点:
- 爆款帖子被大量抄袭/改写
- "杭州三日游攻略" 有100篇相似内容
不去重的后果:
检索结果全是重复内容 → LLM生成千篇一律
```
## 解决
解决:把文本转换成一个**小的指纹(signature)**,相似的文本有相似的指纹。**MinHash** 是一种**快速找出相似文本**的算法,在大规模数据清洗中用来**去重**。
### **MinHash工作原理(通俗版)**
```python
# 类比:比较两篇作文相似度
传统方法(慢):
逐字比对,计算相同词占比
MinHash方法(快):
1. 把文章分成词的集合
文章A = {杭州, 西湖, 灵隐寺, 三日游, 攻略}
文章B = {杭州, 西湖, 雷峰塔, 三日游, 推荐}
2. 用N个哈希函数"采样"
Hash1(A) = 灵隐寺, Hash1(B) = 雷峰塔 ✗
Hash2(A) = 西湖, Hash2(B) = 西湖 ✓
Hash3(A) = 杭州, Hash3(B) = 杭州 ✓
3. 相同采样占比 ≈ 真实相似度
2/3 ≈ 0.67 → 判定为重复
# 实际代码
from datasketch import MinHash, MinHashLSH
lsh = MinHashLSH(threshold=0.7, num_perm=128)
for doc_id, text in documents:
m = MinHash(num_perm=128)
for word in text.split():
m.update(word.encode('utf8'))
lsh.insert(doc_id, m)
# 查询相似文档
result = lsh.query(m) # 秒级返回
```
**参数建议:**
- `threshold=0.7`:相似度>70%视为重复
- `num_perm=128`:准确度与速度平衡点
## 通俗例子
假设有两篇文章:
```Java
文章A: "今天天气很好,适合出去玩"
文章B: "今天天气不错,适合出去玩"
(只有"很好"换成了"不错")
```
**传统方法:**
```python
# 需要比较完整的文本
similarity = compare_full_text(A, B) # 慢!
```
**MinHash 方法:**
```python
# 1. 先把文本转成"指纹"
hash_A = minhash(A) # 例如: [3, 7, 12, 45, 89]
hash_B = minhash(B) # 例如: [3, 7, 12, 48, 91]
# 2. 比较指纹(超快!)
similarity = compare_hash(hash_A, hash_B) # 3/5 = 60% 相似
```
## MinHash 工作原理
### 1. 文本 → N-gram 集合
```python
文本: "今天天气很好"
# 提取 3-gram (shingles)
shingles = {
"今天天",
"天天气",
"天气很",
"气很好"
}
```
### 2. 多次哈希,取最小值
```python
# 用很多个哈希函数(比如 128 个)
def minhash_signature(shingles):
signature = []
for i in range(128): # 128 个哈希函数
min_hash = min(hash_i(s) for s in shingles)
signature.append(min_hash)
return signature
# 得到一个 128 维的向量
sig_A = [3, 7, 12, 45, 89, ...] # 128 个数
sig_B = [3, 7, 12, 48, 91, ...]
```
### 3. 比较签名
```python
# Jaccard 相似度估计
similarity = sum(a == b for a, b in zip(sig_A, sig_B)) / 128
# 如果 100/128 位相同 → 约 78% 相似
```
## 在 LLM 数据清洗中的应用
### 场景: CommonCrawl 网页去重
```python
# 有 10 亿个网页
# 目标: 删除几乎重复的页面
# 步骤:
for document in corpus:
# 1. 计算 MinHash 签名
signature = compute_minhash(document)
# 2. 用 LSH (Locality Sensitive Hashing) 快速找相似文档
similar_docs = lsh_index.query(signature)
# 3. 如果相似度 > 80%,标记为重复
if similar_docs:
mark_as_duplicate(document)
```
### 实际案例
**GPT-3 的数据清洗:**
- 使用 MinHash 去除重复文档
- 过滤掉低质量、过度重复的内容
**LLaMA 的数据清洗:**
- 用 MinHash 在 CommonCrawl 中去重
- 相似度阈值设为 0.8 (80% 相似就删除)
## 为什么比直接比较快?
```Java
直接比较:
10亿个文档 × 10亿个文档 = 10^18 次比较 ❌
MinHash + LSH:
1. 每个文档算一次签名: 10亿次
2. LSH 分桶,只比较同一桶里的
3. 总比较次数 ≈ 10^8 次 ✅ (快 10^10 倍!)
```
## 代码示例(简化版)
```python
from datasketch import MinHash
# 文档 A
mh1 = MinHash(num_perm=128)
for word in "今天天气很好".split():
mh1.update(word.encode('utf8'))
# 文档 B
mh2 = MinHash(num_perm=128)
for word in "今天天气不错".split():
mh2.update(word.encode('utf8'))
# 估计 Jaccard 相似度
print(mh1.jaccard(mh2)) # 0.75 (75% 相似)
```
## 你说的"模型结构比较收敛"
是的,现在的趋势确实是:
✅ **模型架构:** 基本就是 Transformer + 一些小改进
- Pre-norm vs Post-norm
- RoPE, ALiBi 等位置编码
- 激活函数(SwiGLU, GeGLU)
✅ **数据质量更重要:**
- 去重(MinHash)
- 去毒(过滤有害内容)
- 多样性(不同领域平衡)
- 质量过滤(去除低质量文本)
**"Data-centric AI"** - 与其设计新架构,不如清洗更好的数据!
# 💡 Cues
# Notes