LLM大模型: 常用的数据清洗方法总结

news/2024/11/17 1:44:17/文章来源:https://www.cnblogs.com/theseventhson/p/18293145

  LLM的三大要素:

  • 算力:算力的本质是拼财力,普通人是无力改变的;
  • 算法/模型结构:目前最流行的还是transformer架构, 各种LLM都是基于transformer改细节,暂时没有用新的框架替代transformer。至于后续manba会不会替代transformer架构,有待观察!
  • 数据:这块是做LLM pre-train或fine-tune最大的苦力活,做这块业务的研发堪比苦力强~~~  以前做传统数据挖掘和NLP,80%的时间都花在了数据的采集和清洗上。没想到现在搞LLM,虽说比以前好些,还是要花大量时间来采集和清洗各种数据,真的是造孽啊.......

  根据scanling law,tokens越多、模型越大、计算量越大,loss就越小!所以大量的优质数据是必不可少的!

      

   在安全垂直领域,数据清洗的核心思路总结如下:

  • 质量过滤:数据质量低,模型生成的数据会前言不搭后语,前后没任何逻辑性可言
    • 分类器过滤:用传统的分类器对文章打分,接近1的就是质量好的文章,可以人为设定一个阈值,比如0.8,超过阈值的就是高质量文章。传闻GPT-3在训练时用的数据就是使用了分类器精选优质数据;问题又来了:分类器也需要训练数据啊,”冷启动“阶段的数据哪来了?可以从一些权威的网站,比如维基百科、arxiv.org等,这些站点的文章作为正样本,人工选一些 不入流的N线网站文章作为作为负样本训练分类器
    • 人为设定规则:比如去掉网页标签、&nbsp、%20、\u3000等无用字符;
    • Perplexity困惑度:Perplexity本质是根据之前所有的token预测下一个token生成的概率值,比如  I am a 这三个token后面跟上student的概率较大,跟上air的概率很小,如果后面街上了air,那么这份语料的质量就大打折扣了,可以直接去掉啦!困惑都计算公式:

       示例代码如下:

      import torch
      from transformers import GPT2LMHeadModel, GPT2Tokenizer
      import math# 加载预训练的GPT-2模型和分词器
      model_name = 'gpt2'
      model = GPT2LMHeadModel.from_pretrained(model_name)
      tokenizer = GPT2Tokenizer.from_pretrained(model_name)# 准备测试集文本
      test_texts = ["I am a student. I go to school everyday cause I like every of my classmates and teachers","Mike is a software engineer,he programs on working days. he has very high skill to produce good quality software!","haha, I adrt gqsf fgwf  dgwa wuklala.","The quick brown fox jumps over a lazy dog, the dog didn't take any actions."
      ]def calculate_perplexity(model, tokenizer, text):model.eval()inputs = tokenizer(text, return_tensors='pt')with torch.no_grad():outputs = model(**inputs, labels=inputs['input_ids'])loss = outputs.lossperplexity = torch.exp(loss)return perplexity.item()# 设置困惑度阈值
      perplexity_threshold = 200filtered_texts = []
      for text in test_texts:ppl = calculate_perplexity(model, tokenizer, text)if ppl < perplexity_threshold:filtered_texts.append((text, ppl))print(f"Text: {text}, Perplexity: {ppl}")print("\nFiltered Texts:")
      for text, ppl in filtered_texts:print(f"Text: {text}, Perplexity: {ppl}")

      结果:质量差的文本被正确筛选出来!

       注意:GPT2对中文支持很差,实际操作时建议换成千问、chatglm等国产大模型

    • 利用统计特征过滤:安全领域有些出名的论坛,比如看雪、52pojie、先知等,有部分网友发帖并不是做技术分享,而是灌水/打广告等,这部分语料也是要去掉的,可以根据标点符号分布、符号字比(Symbol-to-WordRatio)、文本长度等过滤
  • 冗余去重:互联网有部分人自己创作内容的能力差,只会转载、洗稿,导致爬虫爬取的数据大量重复。这些数据用于训练时会让loss明显降低,但这是过拟合,模型生成数据时会明显倾向于重复的数据,陷入重复循环(RepetitionLoops),无法回答其他问题,所以一定要去重。具体操作时,面临一个颗粒度的选择:句子、段落和文章!句子颗粒度去重最精细,但是数量巨大,我的算力不够。所以我个人最终选择段落和文本的颗粒度去重!大量文本去重的算法思路有:
    • 利用向量数据库:先用embedding模型把文本转成向量,然后存储向量数据库;每个新向量存入向量数据库时先计算一下库里面有没有相似度大于阈值(比如0.8)的向量,没有再入库;有就说明重复了,直接丢弃。等所有的文本都这么操作一次后,向量数据库的数据就是唯一的啦!这种思路本质是利用向量数据库去重
    • 和google对网页去重的算法一样:simhash!

     总的来讲:simhash的计算量小于使用向量数据库的计算量,所以这里选择simhash去重!核心demo代码如下:

from simhash import Simhash, SimhashIndex# 示例中文文本数据
texts = ["rerank: 经过第一步使用cosin余弦相似度从密集向量数据库 + keyword search(稀疏向量召回)初步召回top K相似度的文本,按理来说就可以让LLM根据用户的query + 召回的context生成最终答案了,还要这个rerank干啥了?实际操作时,还是会发现一些问题:包含正确答案的文本在context中的排名可能并不靠前。比如query = “清华大学在哪座城市?” 。正确答案肯定是“北京”啦!但实际召回的context中包含北京的文本不一定排在前面,可能在中间甚至后面,给最后一个LLM输入的context会很大,直接导致LLM需要处理很长的文本,推理效率低不说,还容易出错,核心问题还是在于:初步召回的context还是有进一步压缩提炼的空间!造成这种现象的原因是啥了","rerank: 经过第一步使用sim相似度从密集向量数据库 +关键词初步召回K个相似度的文本,按理来说就可以让LLM根据用户的问题 + 召回的文本生成最终答案了,还要这个重排干啥了?实际操作时,还是会发现一些问题:包含正确答案的文本在context中的排名可能并不靠前。比如问题 = “北京大学在哪座城市?” 。正确答案肯定是“北京”啦!但实际召回的context中包含北京的文本不一定排在前面,可能在中间甚至后面,给最后一个LLM输入的context会很大,直接导致LLM需要处理很长的文本,推理效率低不说,还容易出错,核心问题还是在于:初步召回的context还是有进一步压缩提炼的空间!造成这种现象的原因是啥了","利用cosin求两个向量的相似度,本质是看两个向量的距离。比如“北京”、“上海”、“深圳”这些都是中国的一线大城市,这3个词的嵌入向量的余弦相似度会很近,所以使用cosin召回的时候也可能把“上海”、“深圳”这些不是正确答案的sentence召回,所以要用tf-idf这类稀疏向量补充召回部分向量,整个过程称为 hybrid search。经过hybird search后,召回的context变多,给最后一步的LLM生成最终答案带来了麻烦,所以需要进一步从context中继续提炼,优中选优!比如初步召回20条,需要通过重排选择更接近的3~5条,这个过程就是rerank!","利用距离求两个向量的相似度,本质是看两个向量的距离。比如“北京”、“上海”、“深圳”这些都是中国的一线大城市,这3个词的embedding的cosin会很近,所以使用cosin召回的时候也可能把“上海”、“深圳”这些不是正确答案的sentence召回,所以要用tf-idf这类稀疏向量补充召回部分向量,整个过程称为 混合检索。经过混合检索后,召回的上下文变多,给最后一步的LLM生成最终答案带来了麻烦,所以需要进一步从context中继续提炼,优中选优!比如初步召回20条,需要通过rerank选择更接近的3~5条,这个过程就是rerank!","确定要做rerank后,怎么做才能达到既定的目的?要想明白这个问题,还要回到最初的动机:cosin计算的是两个向量的距离,只考虑语义相似,不考虑字面符号是否一致;而稀疏检索tf-idf只考虑字面的符号, 不考虑语义,怎么整合这两种retrieve的优势,摒弃其劣势了?这就需要用到传统NLP常见的手段了:classifier",
]# 计算每个文本的Simhash值
simhashes = [(str(i), Simhash(text)) for i, text in enumerate(texts)]# 创建Simhash索引
index = SimhashIndex(simhashes, k=10)# 检查文本是否重复
def is_duplicate(new_text, index):new_simhash = Simhash(new_text)duplicates = index.get_near_dups(new_simhash)return duplicates# 检查每个文本是否重复
for i, text in enumerate(texts):duplicates = is_duplicate(text, index)if len(duplicates) > 1:  # 因为自己也会在重复列表中,所以长度大于1print(f"文本 {i} 是重复的,重复文本索引:{duplicates}")else:print(f"文本 {i} 没有重复。")# 例如,添加一个新文本并检查是否重复
new_text = "按理来说就可以让LLM根据用户的query + 召回的context生成最终答案了,还要这个rerank干啥了?实际操作时,还是会发现一些问题:包含正确答案的文本在context中的排名可能并不靠前."
if is_duplicate(new_text, index):print("新文本是重复的。")
else:print("新文本没有重复。")# 如果没有重复,则将其添加到索引中index.add(str(len(texts)), Simhash(new_text))

  我这里执行的结果:

文本 0 是重复的,重复文本索引:['1', '0']
文本 1 是重复的,重复文本索引:['1', '0']
文本 2 是重复的,重复文本索引:['3', '2']
文本 3 是重复的,重复文本索引:['3', '2']
文本 4 没有重复。
新文本没有重复。

  注意事项:

  • 看了很多资料,说是k=3就能判断是否重复。但就我个人的实测来看,3显然不够,我这里把k提升到了10就能准确找到重复的文档了!当然,如果只是简单复制粘贴,没有对内容做实质性地更改,k=3也能查重
  • 对文本计算hash前,建议先用正则去掉换行、回车、逗号、句号、感叹号、问号等符号,只保留文字和数字,减少对hash值的干扰
  • 对于长篇的文章分段,可以使用自然段落,也可以使用语义聚类的方式划分段落,详见:https://www.cnblogs.com/theseventhson/p/18279980

   

   

参考:

1、https://arxiv.org/pdf/2001.08361  scaling law

2、https://geek.digiasset.org/pages/affiliate/text-simhash-good-re-process-deep_21Apr03114628313403/    https://www.cnblogs.com/maybe2030/p/5203186.html#_label4  simhash原理

3、https://leons.im/posts/a-python-implementation-of-simhash-algorithm/   A Python Implementation of Simhash Algorithm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/741975.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker部署若依开源java项目微服务版

查看容器IDdocker ps 后面以进入mysql容器为例 进入容器sudo docker exec -it 27e /bin/bash 进入成功,由于是mgsql容器,我们可以输入命令操作看一下mysql文件夹,如下看到了我们建的数据库:退出容器回到centosexit

【考研数学】大家喜欢这种用不同颜色标记解题思路的方式嘛?

今天要给大家分享的笔记是:《如何确定行列式展开式中有效项的个数?》,大家喜欢类似下面这样在文章中用不同的文字颜色和背景颜色对计算推导过程中需要注意的不同部分做高亮显示嘛?可以在下方留言哦 >_< 原文:如何确定行列式展开式中有效项的个数? - 荒原之梦 (zhao…

大气热力学(12)——强对流指数之一(能量参数)

从本篇文章开始,都不是我原有手写笔记上的内容,都是全新添加的内容。本篇文章介绍了根据预报员多年经验总结的各种强对流预报指数,希望这部分内容能对你有所帮助。 @目录12.1 对流有效势能(CAPE)12.1.1 CAPE的概念与相关公式12.1.2 CAPE与上升气块的起始高度的关系12.1.3 …

苍穹外卖 - day1

1.项目介绍 业务功能技术选型环境搭建前端 前端部分非重点,直接由平台提供,部署在nginx服务器上。nginx概念反向代理与负载均衡动态监听80端口,将请求转发到目标服务器,若有多个目标服务器,则采取负载均衡策略进行请求的分发(如轮询)接口文档 1. YApi 通过上传json文件或…

2024最新Zibll子比主题V7.7版本源码 开心版 | WordPress主题

简介: 2024最新Zibll子比主题V7.7版本源码 开心版 | WordPress主题 安装教程在压缩包内V7.7更新日志: 新功能新增数字翻页输入页码跳转的功能(注:总页数超过 8 页才会显示) 新增后台批量设置文章阅读量、点赞数、显示布局等文章扩展功能 新增后台批量设置论坛帖子阅读量、置…

成为MySQL DBA后,再看ORACLE数据库(十三、物理备份)

前面总结了ORACLE的逻辑备份,本文来总结以下ORACLE的物理备份。数据库的备份一般分为冷备份和热备份,其中冷备份是指将数据库彻底关闭后进行的一致性备份,由于需要关停数据库所以在实际应用中很少用到冷备份。而热备份是指在数据库运行的同时对数据库进行备份,本文主要总结…

开源流程表单设计器都有哪些值得一提的优势?

通过本文,可以随时来了解开源流程表单设计器的优势。如果需要提质、增效、降本,不妨来了解下低代码技术平台、开源流程表单设计器的功能和优势特点。想要实现流程化办公,低代码技术平台是助力增效的理想工具。功能灵活、操作方便、好维修、可视化操作等优势都是其深受行业喜…

玩机社区系统源码 | 2024年最美社区源码 全开源 带后端

简介:玩机社区系统源码 | 2024年最美社区源码 全开源 带后端 图片: 点击下载

业务开发时,接口不能对外暴露怎么办?

在业务开发的时候,经常会遇到某一个接口不能对外暴露,只能内网服务间调用的实际需求。面对这样的情况,我们该如何实现呢?今天,我们就来理一理这个问题,从几个可行的方案中,挑选一个来实现。 1. 内外网接口微服务隔离 将对外暴露的接口和对内暴露的接口分别放到两个微服务…

博客园XSS漏洞测试

<img src=1 onerror=alert(document.cookie)> `

06-Web API

Web API种的概念以及提供的相关方法的使用01 DOM的概念02 BOM概念除了DOM对象以外都是BOM,例如上图浏览器上的一些东西 03 DOM的继承关系图04 节点之间的导航 获取一个节点之后,可以根据这个节点去获取其它节点,称之为节点之间的导航获取节点代码示例 <!DOCTYPE html> …

实战篇——SSRF漏洞Redis反弹shell实战

实战篇——SSRF漏洞Redis反弹shell实战 SSRF之Redis实战 上一章中利用file伪协议实现了内网的主机探测,发现存在192.168.118.151,对其进行端口探测:可见开放了6379端口,结合响应判断为Redis服务。 而Redis存在未授权访问漏洞,可以利用该漏洞实现信息泄露、数据删除以及反弹…