数学相关训练数据集, 数据量为17.4B tokens, 大小为27.4GB.
数据集构造pipeline
- 使用简单过滤器, 预过滤所有不含数学内容的html语料.
- 从HTML文档中 拆分文本与Latex内容的同时移除模版内容..
- 内容分类与过滤:
-
- 用FastText筛选出英文文件
- 用KenLM筛选出高困惑度文件
- 用自有MathScore模型筛选非数学文件 (那些可能含有数学内容, 但在这一步打分不够高的doc会被筛出来)
- 使用SimHash进行数据去重
- 人工审查
论文
高质量数据对大模型性能有极大增幅. 目前主流dataset没有很忠实地保留数学概念. 因此推出OpenWebMath, 在这个数据集上训练的模型, 性能要优于在20倍大其他数据集上训练的相同模型.
数学推理能力已经成为评估大模型能力的评估指标之一. 人们对模型数学推理能力的关注也激励着更新的去尝试提高推理能力的方法.
本文主要贡献:
- 开源 OpenWebMath数据集.
- 开源相关pipeline以及代码以供复现.
- 对OpenWebMath数据集质量做出分析.
如何构建数据集
构建的目的是: 在保留数学内容原本格式的情形下, 尽可能多的获取数学相关数据.
作者希望这个数据集仅仅是作为一个预训练的辅助数据集, 因此, 只保留了少量非数学相关的内容, 因为删除它们会影响到其他相关数据.
预过滤
为减少需要处理的文档数量进行预过滤.
- 首先检查常用数学字符, 如tex 类, 标签, 单词"mathjax". 如果检测到有Latex公式插入, 则将$ 视为公式的开始.
- 若无这些关键词, 寻找是否有top 100 freq的Latex符号出现. 使用正则表达式在plain text中进行匹配.
- 若无这些Latex符号, 则使用自有Math Score classifier(下面会介绍)打分, 置信度高于0.8则保留.
通过这样一步步分层选择更昂贵更精准的分层分类器, 就既能减少计算代价, 又能对相关内容有比较高的召回率.
文本拆分
不同于以往工作: 从Common Crawl提取文本.
作者选择了从html文档中提取. 因为作者发现其他方式对于这种数学内容的提取效果并不好. 因此, 整个工作基于Resiliparse库. 它是用于解析html文件并获取其主要内容的cython库. 附录显示, 它比同类库更高效.
另一个值得注意的地方是, 作者随机化了提取的参数以增加数据集多样性.
即随机决定使用纯文本还是md格式文本...
拆分有四个阶段: 拆分Latex, 拆分文本, DOM处理, 行处理.
Latex拆分
数学公式可能以多种方式出现在html文件中, 当前常见方式不能很好的应对.
网络上的主要公式都是以MathJax形式放入html页面.
为识别MathJax, 作者先通过搜索mathJax来判断它是否在页面被导入...
DOM 处理
在Latex等式被拆分后, 作者对DOM-tree做了处理, 包括:移除不可见元素, 移除按钮和连接集群, 注释, 表格, 头部和一些可能存在问题的元素.
文本拆分
使用Resiliparse库的方法来提取文本内容.
行处理
作者使用自有的处理方式去移除了模版行, 以及那些不属于Latex公式的$符号.
过滤
过滤掉那些非英文的文档, 再次进行非数学内容的过滤与低质量文档的过滤.
- 使用fasttext分类并移除那些非英语文档.
- 使用MathScore cls判断当前文件是否是数学相关的, 并依据之前是否提取出Latex公式而设置不同阈值.
- 使用KenLM来进行困惑度打分, 移除那些困惑度分数过高的文档(可能对模型训练有害).
去重
使用SimHash去移除临近相似的文档.即0.7以上的, 作者发现这个阈值已经足够去移除大多数重复的文档.
人为审查
找文档最多的域,名, 当它们明显不存在数学相关内容时, 将其加入黑名单, 在过滤的时候可以直接过滤掉.
数据集分析
作者从token count, data composition, downstream performance三个方面进行了分析...
代码
结构:
extract_from_cc
extract_from_warc.py文件
- 通过加载3个模型, 定义了计算math_score, 计算困惑度, 判断判断是否为英语的方法.
- contains_math: 正则匹配判断是否存在常用数学符号 -> 判断是否存在Latex常用符号 -> 判断math_score
都不通过则认为不存在数学相关内容.
- process_warc: 从warc提取包含数学内容的文件信息, 并做处理和评分, 最终将相关信息保存并统计到一个文本文件中.
text_normalizer.py文件
- 定义多个阶段的规范化方法
- normalize: 规范化函数,可以通过输入参数决定是否进行某项规范化.