EN

LLM 文本去重实战教程

使用 AI 嵌入向量对大规模文本数据集进行去重

返回教程列表
进阶10 分钟

LLM 文本去重实战教程

使用 AI 嵌入向量对大规模文本数据集进行去重

LLM 文本去重实战(2026):三级漏斗——哈希(免费)→嵌入近邻(便宜)→LLM 仲裁灰区(精确),阈值用 200 对标注校准出自动合并/自动判异两条线。含聚类保留策略、增量模式、合并溯源。

LLM 文本去重实战教程

文本数据集中的重复项——重复提交的工单、同一产品以五种方式列出、几乎相同的文章——会破坏分析、膨胀 RAG 索引并使训练数据产生偏差。精确匹配去重无法捕捉任何有趣的情况(“无法登录我的账户” vs “登录对我没用”)。生产环境的解决方案是三级漏斗:廉价哈希 → 嵌入相似度 → LLM 仲裁,仅在必要时使用昂贵的工具。

为什么采用漏斗形状

比较所有对是 O(n²) 的——100 万条记录意味着 5000 亿对;你无法天真地通过 LLM(甚至嵌入比较)来处理。每个阶段将候选数量减少几个数量级:

  • 阶段 1 —— 标准化 + 哈希(免费):小写、去除标点/空白、哈希。立即捕获琐碎的重复项。MinHash/SimHash 将其扩展到大规模语料库中“大部分相同词语”的对——经典的预 LLM 技术,对于网络规模语料库仍然是正确的第一道关卡。
  • 阶段 2 —— 嵌入 + 最近邻(便宜):对每条记录进行一次嵌入,找到高于相似度阈值的近邻对。这可以捕获语义重复,无论措辞如何。
  • 阶段 3 —— LLM 对灰区进行裁决(精确):高相似度 ≠ 重复(“iPhone 15 手机壳,黑色” vs “iPhone 15 手机壳,红色”嵌入几乎相同,但它们是不同的产品)。LLM 正是对这些情况进行仲裁。
  • 阶段 2:嵌入 + ANN

    python
    import numpy as np
    from openai import OpenAI

    client = OpenAI()

    def embed_batch(texts: list[str]) -> np.ndarray: resp = client.embeddings.create(model='text-embedding-3-small', input=texts) return np.array([d.embedding for d in resp.data])

    对于实际规模,将向量放入 pgvector/FAISS 并查询邻居;

    内存中的余弦相似度适用于最多约 5 万条记录:

    emb = embed_batch(records) emb /= np.linalg.norm(emb, axis=1, keepdims=True) sims = emb @ emb.T cand_pairs = [(i, j) for i in range(len(records)) for j in range(i+1, len(records)) if sims[i, j] > 0.85] # 阈值:参见下面的校准

    阈值校准是整个游戏的关键:一次标记约 200 对跨相似度带的对,然后选择两个截止点——高于约 0.95 自动合并,低于约 0.80 自动判异,只有中间带进入阶段 3。该带通常只占对数的几个百分点,这使得 LLM 仲裁变得经济实惠。(将向量存储在 pgvector 中,这也可以作为你的搜索索引。)

    阶段 3:LLM 仲裁

    python
    def judge(a: str, b: str) -> dict:
        prompt = f'''这两条记录是重复的(同一真实事物),还是不同的?
    措辞/拼写/格式的变化 = 重复。不同的尺寸/颜色/版本/意图 = 不同。
    A: {a}
    B: {b}
    JSON: {{"verdict": "duplicate"|"distinct", "reason": "<一行>"}}'''
        resp = client.chat.completions.create(
            model='gpt-4o-mini',
            response_format={'type': 'json_object'},
            messages=[{'role': 'user', 'content': prompt}],
        )
        return json.loads(resp.choices[0].message.content)
    

    生产中重要的注意事项:

  • 在提示中为你的领域定义“重复”——上面的尺寸/颜色/版本行在做实际工作;工单、产品和文章各自需要自己的“相同事物”定义。
  • 通过 Batch API 批量处理灰区——仲裁从不紧急。
  • 聚类,而不仅仅是配对:对确认重复的对进行并查集可以得到组;每组保留最佳代表(最长、最完整或 LLM 挑选的),并将其余映射到它。
  • 此管道的用武之地

  • RAG 索引清洁:重复的块浪费检索槽并使答案重复——在嵌入到你的存储之前进行去重(语义搜索指南)。
  • 支持/CRM 数据:使用实体感知判断(“J. Smith, Acme” vs “John Smith, Acme Corp”)进行工单和账户去重——相同的漏斗,先通过 丰富 规范化字段。
  • 训练/评估数据:训练集和评估集之间的近重复会夸大指标——跨分割去重,而不仅仅是在内部。
  • 操作说明

  • 溯源:记录每次合并(对、裁决、原因、模型版本)——合并具有破坏性;你需要一个撤销轨迹。
  • 增量模式:新记录仅与现有聚类代表进行比较——保持每日运行成本低廉。
  • 每季度审计自动合并带:阈值会随着数据分布的变化而漂移;当来源发生变化时,重新运行 200 对校准。
  • 常见问题

    成本大概多少? 嵌入每千条短记录只需几分之一美分;LLM 仲裁仅触及灰带。10 万条记录的去重通常只需个位数美元——上述设计就是原因

    我可以跳过嵌入只做哈希吗? 对于格式相同的数据,也许可以;但你会错过所有释义。嵌入阶段正是找到“相同含义,不同词语”的关键。

    跨语言重复? 多语言嵌入模型会将翻译聚类在一起——相同的漏斗有效;只需确认你的阶段 3 提示说明翻译是否算作重复(取决于你的用例)。


    *最后更新:2026 年 6 月。*

    相关工具

    openaipython
    所属主题:OpenAI 开发实战