news 2026/10/3 3:21:51

大模型数据清洗全攻略:质量过滤、去重与Pandas实操

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
大模型数据清洗全攻略:质量过滤、去重与Pandas实操

做模型的人常说一句话:模型能力七分靠数据,三分靠算法。这个说法在大模型时代尤其贴切,因为LLM的训练本质就是“用海量文本压缩人类知识”,如果喂进去的文本本身是垃圾、重复、带毒的,那模型学出来的东西要么是废话,要么是噪音,甚至会在推理时输出有害内容。过去我做传统机器学习项目时,数据清洗是EDA的一部分,按列做缺失值填充、异常值剔除就够了;但到了大模型场景,清洗的对象变成了“文档”而不是“字段”,数据量也从几千行变成几亿条文本,思路和方法都得换一轮。

这篇文章是“大模型数据清洗”系列的基本篇第一期,面向两类读者:一类是正在准备指令微调或继续预训练数据集的同学,想搞清楚该用什么标准筛数据;另一类是已经跑过一版baseline但发现模型效果不对,怀疑是数据有问题的工程师。我会从清洗目标、核心维度、pandas落地实操、常见坑位四个角度把地基打牢,后续几期再分别深入去重算法、质量打分、多语言数据配比等进阶话题。

1. 先想清楚再动手——大模型数据清洗的整体设计思路

1.1 清洗目标先于清洗手段

我见过不少人在拿到数据后第一反应就是写正则、调pandas,折腾了半天也不知道自己在清洗什么。大模型数据清洗和传统数据清洗最大的区别在于:传统项目以“可用性”为目标,把脏数据变成能进模型的表格;LLM项目以“学习质量”为目标,清洗标准直接决定模型的知识密度和生成质量。所以第一步不是写代码,而是确认你的数据将被用于哪个环节:预训练、指令微调、还是偏好对齐。

三种场景对数据的要求差异很明显。预训练语料追求“大规模+多样性”,以RedPajama、C4这类公开数据集为参考,清洗重点是去重、去噪、控制语种分布;指令微调数据追求“指令-回答”配对质量和格式一致性,清洗重点是去格式混乱、去答案噪声、统一提示词模板;偏好数据则更看重对比对的合理性,清洗时往往需要做内容质量的人工抽检和边界过滤。目标不同,管道设计就不同,投入也不同。

换句话说,不要一开始就想着“我要清洗这100G语料”,先回答三个问题:这些数据要学什么能力?当前数据里哪些部分是违背这个目标的?清洗后的验收标准是什么?把这三个问题写在文档开头,整个清洗过程才有评价依据。

1.2 管道设计:一次性脚本思路要丢掉

数据清洗在传统业务里常常是“跑一次脚本出结果”的临时任务,但在大模型场景里必须改成管道化、可追溯、可复跑的设计。原因很简单:数据量大、清洗规则多,你不可能检查每一条结果,只能靠每一阶段的统计指标来确认规则是否生效;而且规则需要迭代,今天发现误删太严重,改了规则就得重新跑全链路,如果没有管道设计,返工成本高到你怀疑人生。

我建议把一个完整的清洗流程拆成如下几个阶段:

  • 探查与样本标注:抽样看数据长什么样,标出明显问题类型(乱码、脏HTML、无意义重复、敏感词、语言混杂)。
  • 规则清洗:统一编码、去HTML标签、去URL/邮箱等噪声、过滤超短超长文本。
  • 质量过滤:语种识别、困惑度过滤、字符重复率过滤、符号占比过滤。
  • 去重:精确去重配合MinHash近似去重,去除训练集内重复和与下游测试集重叠的样本。
  • 隐私与合规过滤:识别手机号、身份证、地址等个人信息,做脱敏或剔除。
  • 统计报告输出:每阶段记录输入输出量、去掉比例、抽样保留样本,形成清洗日志。

每个阶段都尽量输出独立的中间结果,比如清洗后的parquet分片、过滤统计JSON、抽样校验文本。这样当你发现最后一批数据有问题时,能快速定位是哪个阶段造成的。这套思路比任何具体代码都值钱,因为LLM项目的清洗不是一个“做完就结束”的事,而是一个会随业务演进不断迭代的过程。

2. 大模型数据清洗绕不开的四个核心维度

2.1 质量过滤:规则启发式与模型打分并用

质量过滤是清洗管道里最耗时间的一环,也是影响模型效果的关键。业界常用的思路分成两层:第一层是规则启发式,第二层是用小型模型打分排序。

规则启发式的核心是设置合理的阈值组合,把明显低质量的文本丢掉。常用的特征包括:文本长度、特殊字符占比、重复n-gram比例、句子长度的方差、HTML标签残留数量等。比如C4数据集的过滤规则里有一条:去重率(去掉连续重复行)太低或者标点缺失率过高就连续丢弃对应的文档。实际操作中,你可以用pandas计算一列“有效文本长度”、一列“URL链接数量”、一列“乱码字符占比”,然后按各自阈值做布尔过滤。

模型打分思路更适合中等以上规模的团队。比如用fastText的语言识别模型判断文本语种,再用KenLM语言模型算困惑度(perplexity),困惑度偏高的文本大概率是乱拼词、机器翻译痕迹或无关广告内容,可以直接丢弃。如果你手头有分类模型,也可以把“文本是否像网页正文”“文本是否包含完整语义”这类的评分器并进管道。规则和模型结合起来,效果远比单独用规则好。

需要特别注意的是,质量过滤最容易犯的错是“规则过强导致数据量骤降”。我看到有人用“文本必须大于512字符”过滤微调数据,结果把大量高质量的短问答全丢了。正确做法是先看长度分布,再定阈值,时刻想到“我筛掉的数据里有多少是误杀”。

2.2 去重:精确去重只是开始,MinHash让你处理百万级文本

去重是大模型预训练数据清洗里最硬核的环节。重复数据会让模型产生记忆偏差,导致生成内容陷入重复循环,还会白白浪费算力。去重分两个层次:精确去重和近似去重。

精确去重最简单,pandas一行drop_duplicates(subset=['text'])就能做,也可以用哈希值快速去重。但现实里的重复往往不是完全相同的字符串,而是“几乎相同”的文本——可能改了标点、加了空格、删了几个字。这种重复精确去重根本发现不了,必须做模糊去重。

近似去重的主流方案是MinHash配合LSH(局部敏感哈希)。核心思路是:把一条文本的字符n-gram集合转成MinHash签名,再用LSH把签名相近的文本分进同一个桶,桶内再精确比较。实际操作可以用datasketch这个库,MinHashLSH处理几百万条文本没什么压力。签名长度和n-gram大小会影响召回率,我一般对中文语料取n=5,英文取n=7,签名维数128或256,相似度阈值设到0.7~0.8。中文比英文更难做近似去重,因为中文没有天然分词边界,5-gram已经是比较保守的选择。

去重这件事别只盯着训练集内部,测试集和训练集之间的去重同样重要。很多同学在训练时觉得很正常,一到评测时发现效果虚高,一查原因才发现评测数据早就出现在训练语料里了。这种泄漏是所有“刷分”现象里最隐蔽也最伤人的一种,必须提前在管道里加一层交叉去重逻辑。

2.3 隐私与个人信息过滤:不可省略的底线操作

个人信息过滤在LLM项目里具有合规意义,处理目标比传统项目更宽,不仅包含结构化表格里的“手机号列”,还包括模型文本中出现的人名、机构、地址、电话、邮箱等。这类内容一旦进了预训练语料,模型可能记住并在生成时输出,带来隐私风险。

基本做法先用正则把显式的手机号、邮箱、身份证号、银行卡号等做模式匹配。移动号码段现在变化快,正则别写太死,1[3-9]\d{9}这种模式对国内手机号基本够用。邮箱的正则简单但容易误伤,“连续字符+@+域名”的组合在中英文混合语料里误报率不低,建议多保留一条“脱敏为邮箱占位符”的策略而不是直接删除整条文档。

地址和人名的识别就要上实体识别模型了,中文可以用LAC或者HanLP这类工具,英文可以直接用spaCy的Ner组件。性能上这种模型跑百万级文本会偏慢,建议并行化处理,或者只对预处理后的高价值样本做实体识别。识别出的实体可以做替换脱敏,也可以直接把包含实体的文档剔除,具体看数据用途。不管怎么做,我都建议在隐私过滤后保存一份脱敏日志,既能排查误报,也能作为合规审计依据。

2.4 数据配比与格式规整:别让清洗完的数据还处在“原始森林”里

格式规整是清洗管道中最不起眼却最容易出问题的一项。网页爬下来的语料里,标题、正文、列表、导航信息混在一起,如果不统一结构,模型学到的格式规律就是“网页噪声”。业界通用做法是先把原始抓取数据转换成统一的JSONL格式,每行一条文档,字段至少包含text、source、url、timestamp,方便后续按来源和时间做下钻分析。

配比调控是结构化数据之外的另一层问题。中文社区里大家手头最常见的是中英文混合的网页文本,如果直接混合训练,模型会严重偏向英文甚至其他语言,因为英文语料量级远超中文。清洗时最好把语种分布统计出来,按目标比例过采样或下采样。比如预训练阶段中文数据目标占比30%,你手里英文语料占90%,就得做亚采样或者用额外的中文语料来补偿。这类配比决策虽然不属于“清洗”本身,但在清洗报告里必须留一个章节专门记录,否则后续改动分布时将无从下手。

3. 用pandas快速落地一套基础清洗流程

3.1 环境准备与数据探查

基础篇先不用上Spark,pandas配合Python标准库足够处理千万级以下的中小语料。环境准备很简单:Python 3.10以上,安装pandas、numpy、datasketch、pyarrow,中文处理再加jieba,语言识别用fasttext或者更轻量的langdetect。

拿到数据源后先抽样探查,我习惯分三步走:

  • 用pd.read_json(path, lines=True)读入前5000条样本,直接print出来看内容形态。
  • 用df.describe()和自定义函数统计文本长度分布、空值比例、重复比例。
  • 手动抽20~50条,记录你看到的明显问题(乱码、广告、不完整句子、重复段落等)。

探查这一步别省。清洗规则的80%来自样本观察,只有20%来自公开数据集的处理经验。我见过不少团队直接在公开清洗规则上复制粘贴,结果自己的行业语料被规则误删三分之一,最后还得慢慢调阈值。

3.2 基础清洗实操:编码统一、字段规整、噪声移除

先处理编码问题。现实中拿到的很多语料是GBK或GB18030编码,统一转成UTF-8后再进pandas。如果读取时就报编码错误,用errors='ignore'不是好选择,它会静默删除非法字节导致数据残缺。建议分文件读,先二进制检查编码再转换,或者用第三方库charset-normalizer批量判定。

字段规整的重点是清理不可见字符和多余空白。可以用如下代码对text列做标准化:

import pandas as pd import re def clean_text(s: str) -> str: if not isinstance(s, str): return "" # 统一换行和制表符 s = s.replace("\r", "\n").replace("\t", " ") # 去掉零宽字符和非法控制字符 s = re.sub(r"[\u0000-\u0008\u000b\u000c\u000e-\u001f\ufeff]", "", s) # 合并连续空白 s = re.sub(r"[ \t]+", " ", s) # 去除多余空行 s = re.sub(r"\n{3,}", "\n\n", s) return s.strip() df["text_clean"] = df["text"].apply(clean_text)

这段代码看起来简单,但很多坑就藏在“看起来简单”里。比如\ufeff是BOM头,Excel导出数据经常带;零宽字符在文本里肉眼看不见,却会让模型训练时产生无效token;连续空行看似无关紧要,但会干扰模型对段落结构的理解。跑完基础清洗后,重新统计text_clean的空值比例和长度分布,如果长度缩水严重,说明原始文本有大量纯空格或控制字符,你其实是在清理一些“根本不算文本”的样本。

3.3 质量过滤:长度、语言、符号占比三板斧

基础清洗完成后进入质量过滤。我把最简单的过滤规则按优先级列出来:

  • 空值过滤:df = df[df["text_clean"].str.len() > 0]。
  • 最短长度过滤:预训练语料一般过滤掉小于100字符的短文;微调数据则依任务而定,不是越短越差。
  • 最长长度过滤:防止单条文本过长导致训练时截断产生过多碎片,一般保留20000字符以内的文档。
  • 符号占比过滤:计算非汉字、非字母、非数字的字符比例,超过30%的文本大概率是乱码或代码噪声。
  • 重复段落过滤:把文本按空行切成段落,统计重复段落的占比,高比例说明是“内容农场”类站点。

实际操作时,我会把这些规则统一写进一个函数,返回布尔掩码:

def quality_filter(s: str) -> bool: if len(s) < 100 or len(s) > 20000: return False # 计算有效字符比例 total = len(s) useful = len(re.findall(r"[\u4e00-\u9fa5a-zA-Z0-9]", s)) if useful / total < 0.5: return False # 段落重复率检查 paras = [p for p in s.split("\n") if p.strip()] if len(paras) > 3: dup = max(paras.count(p) for p in paras) if dup / len(paras) > 0.5: return False return True df = df[df["text_clean"].apply(quality_filter)]

这里有一个容易被轻视的点:中文汉字占文本比例的计算。用[\u4e00-\u9fa5a-zA-Z0-9]这个正则对中英文混合文本很好用,但如果你有代码、数学公式类语料,它会误杀大量样本。所以质量过滤规则必须按数据来源分组设定,比如网页文章类使用中文比例,代码类使用括号和缩进特征,而不是全网共用一组阈值。

3.4 精确去重与MinHash近似去重实战

基础篇里去重分两步走。第一步,精确去重:

df = df.drop_duplicates(subset=["text_clean"], keep="first")

第二步,对精确去重后的数据做MinHash近似去重。用datasketch实现非常简单:

from datasketch import MinHash, MinHashLSH import re def ngrams(text, n=5): text = re.sub(r"\s+", "", text) return {text[i:i+n] for i in range(len(text)-n+1)} def get_minhash(text, num_perm=128): m = MinHash(num_perm=num_perm) for g in ngrams(text): m.update(g.encode("utf-8")) return m lsh = MinHashLSH(threshold=0.7, num_perm=128) for idx, row in df.iterrows(): m = get_minhash(row["text_clean"]) lsh.insert(str(idx), m)

插入完后,LSH会把近似文本分到同一桶中,再在桶内做两两相似度确认。这里要提醒几个实际工程问题:第一,插入百万条文本时,内存会涨得很快,建议分批插入;第二,Python的for循环在百万级别上非常慢,建议把itertuples或parallel用起来;第三,threshold不要设太低,不然误判率很惊人,我实测0.7阈值在中文语料上的误判率还可以接受,0.5以下基本就全是误判了。

另外,精确去重前记得先给文本做一次“指纹归一化”,比如去掉所有标点、统一大小写、压缩空白后再算哈希,这样很多“伪差异”文本会被识别为重复。这一步通常在基础清洗阶段完成,不然后面做近似去重时计算量大几十倍。

3.5 清洗报告与验收标准

清洗报告是整条管道里最容易偷懒,却最有价值的部分。每经过一个清洗阶段,我要求管道自动输出一份JSON或Markdown,记录当前阶段的样本量、过滤量和过滤原因占比。最终清洗完成后,按来源域名统计各来源的保留率。这个报告的妙处在于:它会暴露数据采集阶段的失衡。比如说某个网站来源的保留率只有5%,而这个网站却贡献了原始数据的60%,那你就要反思是不是爬虫策略出了问题,而不是清洗规则有问题。

验收标准方面,我一般做三个检查:一是抽样20条清洗后的文本,人工确认没有残留的HTML标签、导航菜单、广告文本;二是跑一个快速的语言识别,确认目标语言占比符合配比预期;三是做一个“测试集重叠”检查,把测试集和训练集做一次MinHash交叉去重,确认没有泄漏。这三个检查通过后,数据才能称为“可训练状态”。

4. 踩坑记录与常见问题速查

4.1 编码与读取问题:有些坑不会报错,但会让结果悄悄变错

最隐蔽的编码问题是“读取成功但内容全乱”。有些文件明明是GBK,但恰好每个字节都能被UTF-8解码,结果吐出来一串乱码还不报错。碰到这种情况,建议在探查阶段直接算一下乱码字符比例,例如检测是否包含大量Unicode替换符\ufffd,或者汉字比例是否异常低。别迷信读取器的编码检测,它面对短的标题可能猜对,面对长文档一样会翻车。

另一个低级错误是把CSV直接当JSON读,或者把JSONL当作普通文本处理。大模型语料最常见格式是JSONL,按行读取没有问题;但JSONL文件往往会很长,pandas直接read_json默认会尝试加载整个文件,内存不够就崩。建议加chunksize参数分批读取,或者用read_json(path, lines=True, chunksize=10000)迭代处理。我踩过最大的坑是把一个12G的JSONL一次性加载,服务器直接OOM,后来改成流式处理后稳如老狗。

4.2 正则规则的误杀与漏杀

正则看似简单,实际是清洗管道里最需要反复调的地方。一个经典误杀:用[\u4e00-\u9fa5]判定中文,结果把“C++”“MacBook”“iPhone”里的英文字母全当成“有效中文”之外的字符,进一步被质量过滤误杀。另一个经典漏杀:用“手机号正则”去匹配隐私信息时,漏了区号或分机号,导致部分样本带着手机号混入训练集。

正则规则我当时的原则是:记录每条规则在样本集上的命中率和误杀率。用2000条人工标注样本跑一个小评估,比凭感觉调规则可靠得多。比如隐私过滤规则,你可以手工构造200条带手机号、邮箱的样本,和200条“看起来很像但不是隐私”的文本,跑一遍正则,算精确率和召回率。大模型训练语料对“漏杀”零容忍,所以这类规则宁可误杀也不要漏杀,尤其是涉及个人信息的字段,误删一条文本的代价远低于漏掉一条。

4.3 测试集泄漏问题

交叉去重是很多人前期忽略的环节。常见现象:明明模型没有记忆能力,但评测分数奇高;或者把训练数据切分成train/val时,直接按行随机切分,导致同一文档的不同副本出现在两个集合中。这个问题在“网页采集语料”里尤其容易出现——同一篇文章被不同网站转载,内容相似但URL不同。

解决办法是:对训练集、验证集、测试集都做全局MinHash签名,然后做两两集合的相似度比对。阈值设在0.7附近,一旦发现相似样本跨集合出现,就把较新的样本从训练集移除。这步做得好,你后面调参时得到的每一个分数都是可信的,否则你会在模型效果上浪费大量时间而浑然不知。

4.4 清洗速度和计算资源平衡

大模型数据清洗最容易被低估的是计算资源。单机pandas处理几万条数据毫无压力,一旦到千万条级别,很多操作会慢到你怀疑人生。我当时碰到过一个真实案例:用pandas跑了一个5-gram正则替换,在100万条样本上跑了快三小时还没完,原因就是正则引擎在长文本上的回溯爆炸。解决方案很简单——先把文本裁剪到固定长度再做正则,或者改用re.compile预编译模式,并用regex库替代标准库的re,性能提升非常明显。

如果数据量到了亿级,pandas就扛不住了,这时候就得换Spark或者Dask。但我不建议一开始就上Spark,因为分布式调度的调试成本远高于单机。更合理的路径是:先在小样本上把规则打磨好,再平滑迁移到大数据引擎。规则逻辑不变,变的只是执行引擎。

4.5 常见问题速查表

以下是我在实操中经常遇到的问题及处理办法,整理成速查表,方便大家直接对照排查:

常见问题可能原因排查方法推荐处理
读取文件后大量乱码编码判定错误或混合编码用工具检测实际编码,抽样打印前200字符统一转UTF-8,跳过无法识别的文件
文本长度过滤后数据量骤减阈值设得过于激进画长度分布直方图,观察峰值按分布分位数设定阈值
去重后数据量下降超预期同源转载文本过多或归一化过度统计各域名保留率按来源分组保留不同篇目
MinHash误判率高threshold过低或n-gram太小抽样人工查看被去重样本调整threshold到0.7以上
模型生成重复内容训练语料重复文本残留检查精确去重后的重复比例补充近似去重,加强指纹归一化
文档出现网页残留标签HTML标签清除不彻底搜索<div、<a href等模式引入HTML解析器(如BeautifulSoup)剥离
忘记处理测试集泄漏只做了训练集内部去重检查评测分数是否异常虚高对全部数据集做交叉MinHash比对

这个速查表我贴在工位上很久了,基本每次清洗管道报问题,都能在这张表里找到对应的影子。建议大家也建立自己的“清洗异常案例库”,每个坑记一条,时间久了会发现很多问题其实是可以提前预判的。

做了这么久的大模型数据清洗,我最大的体会是:数据管道的价值不是某一条规则多精妙,而是它能把“数据质量”变成一个可度量、可追踪、可回归的对象。每清洗一版数据,报告的指标都应该能回答三个问题:这版数据和上一版比发生了什么变化?哪些规则带来了预期收益,哪些误伤了数据?下一版数据采集应该重点补什么?如果你的管道能稳定回答这些问题,那数据质量问题就已经解决了一大半。

最后分享一个小技巧:在清洗管道里,务必把“人工抽样校验”固化成一个自动检查单元,每清洗1万条,自动抽20条存到一个review/目录,定期快速翻一遍。这个动作看起来不起眼,却是对抗“管道结果看着很合理、实际不可用”的最有效手段。数据清洗从来不是一次性的流水线操作,它更像做菜时的“试吃环节”——流程跑得再顺,最终还是要靠舌头确认味道对了,才敢端上桌。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 3:21:01

实时期货行情 WebSocket 链路实战:从连接到稳定运行

凌晨两点半&#xff0c;多数人已经睡了&#xff0c;我盯着屏幕上滚动的行情帧&#xff0c;心里想的却不是价格本身&#xff0c;而是那条 WebSocket 链路到底还能撑多久。这不是矫情——真实网络环境里&#xff0c;一条看起来"连接正常"的行情通道&#xff0c;很可能早…

作者头像 李华
网站建设 2026/10/3 3:20:57

C#网络应用编程实战:从TCP流到Modbus多设备管理

干我们这行&#xff0c;搞上位机和设备联调的&#xff0c;最常碰到的需求就是“把设备的数据拿回来&#xff0c;处理完再发回去”。这句话听起来简单&#xff0c;真做起来&#xff0c;卡界面、丢包、协议对不上、多台设备相互干扰&#xff0c;能把你一天的耐心消磨干净。这篇文…

作者头像 李华
网站建设 2026/10/3 3:20:56

Spring Boot学生宿舍管理系统:源码解析、部署与答辩指南

又到了毕设季&#xff0c;后台经常收到这类私信&#xff1a;老师&#xff0c;我选题选了springboot学生宿舍管理系统&#xff0c;源码也拿到了&#xff08;就是带编号25537的那套工程&#xff09;&#xff0c;但压根不知道从哪看起&#xff0c;跑起来全是报错&#xff0c;答辩也…

作者头像 李华
网站建设 2026/10/3 3:20:09

Python电影推荐系统源码解析:从协同过滤到Flask部署实战

简介&#xff1a;这份Python电影推荐系统源码包面向具备一定Python基础、希望深入理解推荐系统原理与工程实现的学习者与开发者&#xff0c;围绕sparrowrecsys项目展开&#xff0c;覆盖数据预处理、协同过滤、矩阵分解、评价指标、模型训练优化及服务化部署等完整链路&#xff…

作者头像 李华
网站建设 2026/10/3 3:20:05

DeepSeek时代,计算机专业四年学习顺序指南

每年开学季&#xff0c;都会有人私信我同一个问题&#xff1a;计算机科学与技术这个专业&#xff0c;到底按什么顺序学才不浪费大学四年&#xff1f;尤其是在DeepSeek这类大模型已经能写代码、能解释报错的今天&#xff0c;很多人的困惑从"学不会"变成了"不知道…

作者头像 李华
网站建设 2026/10/3 3:20:04

环形链表判环:从哈希表到快慢指针,详解Floyd判圈算法

说实话&#xff0c;刷到 Hot100 第 22 题的时候&#xff0c;我心里是有点轻视的——环形链表&#xff0c;这题名听着太基础了&#xff0c;第一反应就是“哈希表嘛&#xff0c;遍历一遍记个地址就行”。但后来在一次模拟面试里被面试官追问了一句“不用额外空间怎么做”&#xf…

作者头像 李华