前面从广义数据的角度对数据集进行了处理,但是没有考虑到大模型的角度。在和负责大模型部分的同学沟通后,进一步对数据进行了处理,使其更贴合大规模预训练模型。通过一番查找对比,我在这里选择了llm_corpus_quality这个项目。
llm_corpus_quality集成了包含清洗、敏感词过滤、广告词过滤、语料质量自动评估等功能在内的多个数据处理工具与算法,为中文AI大模型提供安全可信的主流数据。项目采用java实现,完整项目见https://github.com/jiangnanboy/llm_corpus_quality
llm_corpus_quality支持以下特性:
- 规则清洗
- 敏感词过滤
- 广告过滤
- 去重
- 质量评估
处理流程如下
大模型训练语料清洗流程,共包括4个阶段5个模块:
- 语料清洗规则过滤:通常经过格式转换后的json文件仍存在很多问题,不能直接用于构建训练数据集。通常会以句子或篇章作为过滤单位,通过检测句子或篇章内是否含有大量的怪异符号、是否存在html网页标签等来判断文本是否为合格文本。
- 敏感词过滤器:利用自动机,过滤色情、赌博、部分低质量广告等内容的文本。
- 广告过滤:利用textcnn模型,过滤涉嫌广告内容。(见https://github.com/jiangnanboy/ad_detect_textcnn)
- 去重:利用simhash对相似文本片段进行去重。
- 质量评估:采用ngram语言模型评估的方法,对语料进行概率预估,文本质量越高的语句,困惑度ppl越低,设定一个ppl阈值,高于这个阈值为低质量语料,可过滤。
下面是作者给出的示例代码,我稍加改动,对预处理的数据集进行了适配大模型的清洗,得到了最终数据集。
// hash data of corpus to deduplication (read and save)
var hashFile = PropertiesReader.get("dedeplication_hash_path");
//1.rule
var ruleQuality = new RuleQuality();
//2.sensitivity and advertising detection
var simpleSenDetectionProcessor = SimpleSenDetectionProcessor.newInstance();
var senDetection = simpleSenDetectionProcessor.getKWSeeker("sensitive_words_path");
var ad_detect_model_path = PropertiesReader.get("ad_detect_model_path");
var ad_dict_path = PropertiesReader.get("ad_dict_path");
var stop_words_path = PropertiesReader.get("stop_words_path");
var adDetection = new AdDetection(ad_detect_model_path, ad_dict_path, stop_words_path);
//3.text deduplication
var deDuplication = new DeDuplication(4, 3);
//4.quality evaluation
var ngramModelPath = PropertiesReader.get("language_model_path");
var qualityEvaluation = new QualityEvaluation(ngramModelPath);
// load hash
if(Files.exists(Paths.get(hashFile))) {
deDuplication.loadHash(hashFile);
}
var corpusQuality = new CorpusQuality(ruleQuality, senDetection, adDetection, deDuplication, qualityEvaluation, 100);
var corpus = "对未按土地、环保和投资管理等法律法规履行相关手续或手续不符合规定的违规项目,地方政府要按照要求进行全面清理。一,凡是未开工的违规项目,一律不得开工建设;二,凡是不符合产业政策、准入标准、环保要求的违规项目一律停建。";
var result = corpusQuality.quality(corpus);
System.out.println(result);
// save hash
deDuplication.saveHash(hashFile);
不过在这里,我对清洗前后的数据进行观察,发现并没有明显变化,因为原本的数据集已经是在上传者处理过后上传至平台上的。