全套解决方案:中文 NLP 训练框架,支持大模型训练和文本生成,快速上手,海量训练数据!
全套解决方案:基于 pytorch、transformers 的中文 NLP 训练框架,支持大模型训练和文本生成,快速上手,海量训练数据!
1.简介
目标
:基于pytorch
、transformers
做中文领域的 nlp 开箱即用的训练框架,提供全套的训练、微调模型(包括大模型、文本转向量、文本生成、多模态等模型)的解决方案;数据
:从开源社区,整理了海量的训练数据,帮助用户可以快速上手;
同时也开放训练数据模版,可以快速处理垂直领域数据;
结合多线程、内存映射等更高效的数据处理方式,即使需要处理
百GB
规模的数据,也是轻而易举;流程
:每一个项目有完整的模型训练步骤,如:数据清洗、数据处理、模型构建、模型训练、模型部署、模型图解;模型
:当前已经支持gpt2
、clip
、gpt-neox
、dolly
、llama
、chatglm-6b
、VisionEncoderDecoderModel
等多模态大模型;多卡串联
:当前,多数的大模型的尺寸已经远远大于单个消费级显卡的显存,需要将多个显卡串联,才能训练大模型、才能部署大模型。因此对部分模型结构进行修改,实现了训练时
、推理时
的多卡串联功能。
模型训练
2.文本分类模型
本部分,介绍中文的文本分类模型,适用于二分类、多分类等情况。使用 transformers 库。
处理数据
code_01_processdata.ipynb
数据介绍
本案例使用的是一个外卖平台的评论数据,对评论的文本做了分类(分为好评和差评)
当你把
code_01_processdata.ipynb
文件跑完之后,就可以看到在📁data_all
里面有一个📁data
,里面有三个文件,样式都是像下面👇这样的
上图是一个batch
的数据,或者所有的文本分类的数据样式:
text
下面的红色条,就是一个个句子。label
里面有红色有绿色,就是表示标签分类。transformers
包做分类的时候,数据要求就这两列。
注意点:
数据需要分为
train_data.csv
,test_data.csv
,valid_data.csv
,这三个csv
文件注意是使用,
分割开的。数据不可以有缺失值
数据最好只含有两列:
label
,text
label
:表示标签,最好为整型数值。0,1,2,3,4 等text
:表示文本,(看你需求,可以有符号,也可以没有标点符号)
train_data.csv
,test_data.csv
,valid_data.csv
这三个数据里面,不要有数据相同的,不然会造成数据泄漏。
训练模型
code_02_trainmodel.ipynb
数据训练流程 以一个 batch 为例:
Tokenizer
会将数据中的text
转换成三个矩阵(或者叫三个Tensor
),分别叫input_ids
,token_type_ids
,attention_mask
,至于怎么转换的,我们先不做详细介绍(本仓库后续会介绍)。pretrained model
在被加载之前,需要设置一大堆模型的参数,至于要设置什么参数,我们也不做详细介绍。Trainer
就是一个训练器,也需要预先设置好一大堆参数。至于要设置什么参数,我们也不做详细介绍。Trainer
会把input_ids
,token_type_ids
,attention_mask
;还有数据自带的标签label
;还有pretrained model
都加载进来,进行训练;当所有 batch 的数据更新完之后,最终就会生成一个模型。
your new model
就诞生了。对于刚开始学习
大模型做nlp分类
的任务,其实不需要考虑那么多细节,只需要注意数据流程。注意点:
这个步骤非常看显存大小。显卡显存越大越好。
batch_size
,eval_size
大小取决于显存大小。在实际工程中,会先使用
Tokenizer
把所有的文本转换成input_ids
,token_type_ids
,attention_mask
,然后在训练的时候,这步就不再做了,目的是减少训练过程中 cpu 处理数据的时间,不给显卡休息时间。在使用
Tokenizer
把所有的文本做转换的期间,如果设置的文本的长度上限为 64,那么会把大于 64 的文本截断;那些少于 64 的文本,会在训练的时候,在喂入模型之前,把长度补齐,这么做就是为了减少数据对内存的占用。预测
code_03_predict.ipynb
这个时候,就是搞个句子,然后丢给一个
pipeline
(这个就是把Tokenizer
和你的大模型
放在一起了),然后这个pipeline
就给你返回一个分类结果。常见的就是使用
pipeline
,如果更加复杂的话,比如修改模型,这个时候,就比较复杂了(后面会再次介绍)。部署
简单的
部署
相对于预测
,其实就是再加一层 web 端口,fastapi 包就可以实现。高级一点的
部署
相对于预测
,就需要把模型从pytorch
转换成onnx
格式的,这样可以提高推理效率(也不一定,就是举个例子),可能也不会使用 web 端口(http 协议)了,会使用 rpc 协议等方法。这部分现在先不看。
3.中文 gpt2
本文,将介绍如何使用中文语料,训练一个 gpt2
可以使用你自己的数据训练,用来:写新闻、写古诗、写对联等
我这里也训练了一个中文 gpt2 模型,使用了
612万
个样本,每个样本有 512 个 tokens,总共相当于大约31亿个tokens
安装包
需要准备好环境,也就是安装需要的包
像是pytorch
这种基础的包肯定也是要安装的,就不提了。
数据来源
获得数据:数据链接,关注公众号【
统计学人
】,然后回复【gpt2
】即可获得。获得我训练好的模型(使用了 15GB 的数据(
31亿个tokens
),在一张 3090 上,训练了 60 多小时)数据格式
数据其实就是一系列文件夹📁,然后每一个文件夹里面有大量的文件,每一个文件都是
.csv
格式的文件。其中有一列数据是content
每一行的
content
就代表一句话虽然数据有 15GB 那么大,但是处理起来一点也不复杂,使用
datasets
包,可以很轻松的处理大数据,而我只需要传递所有的文件路径即可,这个使用glob
包就能完成。训练代码
train_chinese_gpt2.ipynb
现在训练一个 gpt2 代码,其实很简单的。抛开处理数据问题,技术上就三点:
tokenizer
、gpt2_model
、Trainer
tokenizer
使用的是bert-base-chinese,然后再添加一下bos_token
、eos_token
、pad_token
。gpt2_model
使用的是gpt2,这里的 gpt2 我是从 0 开始训练的。而不是使用别人的预训练的gpt2
模型。Trainer
训练器使用的就是transformers
的Trainer
模块。(支撑多卡并行,tensorboard 等,都写好的,直接调用就行了,非常好用)模型
推理代码
infer.ipynb
这个是chinese-gpt2
的推理代码
将代码中的
model_name_or_path = "checkpoint-36000"
里面的"checkpoint-36000"
,修改为模型所在的路径。然后运行下面一个代码块,即可输出文本生成结果
可以参考这个代码,制作一个 api,或者打包成一个函数或者类。
交互机器人界面
chatbot.py
修改代码里面的第 4 行,这一行值为模型所在的位置,修改为我分享的模型文件路径。
运行
点击链接,即可在浏览器中打开机器人对话界面
更多
这个完整的项目下来,其实我都是全靠
huggingface
文档、教程度过来的.我做的东西,也就是把
Tokenizer
改成中文的了,然后也整理了数据,别的大部分东西,都不是我做的了.
其实,我更喜欢做应用,但是也要理解相关的背后原理,目前还在研究相关的 gpt2 原理还有相关的推理细节,这是我整理的链接,希望可以共同进步
4.中文 clip 模型
本文将介绍,如何从 0 到 1 的训练一个中文 clip 模型。
在处理数据的过程中,训练的过程中,需要的注意事项。
从数据流的角度,看看 clip 模型是怎么处理数据的,模型是怎么构建的。image 和 text 的模型的差异性,两个模型是怎么合并起来计算 loss 的。
clip 模型介绍
CLIP 的英文全称是 Contrastive Language-Image Pre-training,即一种基于对比文本-图像对的预训练方法或者模型。CLIP 是一种基于对比学习的多模态模型,与 CV 中的一些对比学习方法如 moco 和 simclr 不同的是,CLIP 的训练数据是文本-图像对
:一张图像和它对应的文本描述,这里希望通过对比学习,模型能够学习到文本-图像对的匹配关系。如下图所示,CLIP 包括两个模型:
Text Encoder 和 Image Encoder,其中 Text Encoder 用来提取文本的特征,可以采用 NLP 中常用的 text transformer 模型;
Image Encoder 用来提取图像的特征,可以采用常用 CNN 模型或者 vision transformer。
上面这段文字来源于https://zhuanlan.zhihu.com/p/493489688
从数据上看:之前相似度计算,都是两个文本对:
text - text
。只不过现在都是text - image
了。clip 是两个模型(具体长什么样子,后面再说)
2.1
text-model
:负责把text
转换成向量。2.2
image-model
:负责把image
转换成向量。2.3 然后把上面两个向量,做交叉计算 loss,然后 loss 反向传播,这样两个模型的参数都会更新。
其实你想啊,这个
image-model
处理图像的,其实也可以改为处理视频、处理 3d 模型等。那简直是格局打开🫴了。我现在没有数据,后面也打算做一个。你再想想,
text-image
=>text-image-video-3d
这样联合起来,是不是更好。没数据,没机器,做不了。有些人可能感觉,
你这人,就知道TMD吹牛
,来来来,我带你研究研究 clip 模型的源码。
数据
直接点击链接https://pan.baidu.com/s/1wGmXUNP021OWnW7Kik7q1A?pwd=gd3c来获得。
把下载好的文件,也就是
test-2.6w.csv
、train-137w.csv
放在文件夹📁bigdata/raw_data
里面。以此运行
processdta_01.ipynb
、processdta_02.ipynb
、processdta_02.ipynb
用来处理数据。
3.1
processdta_01.ipynb
:用来下载数据,大概下载了 10 多个小时。3.2
processdta_02.ipynb
:用来筛选数据,不是所有的图片数据都是可以用的,这一步非常坑。需要留意。如果图片没有筛选好,在你训练到中间的时候,突然一下因为图片无法加载导致错误,从而训练中断了。3.3
processdta_03.ipynb
:用来把数据干净的数据处理好,合并好,生成新的,漂亮的训练数据。
其实完整下来看,数据清洗,就是把符合格式的照片筛选出来,然后进行训练。
数据总结
说到底,你的数据只要整理成这样的一个样式即可
text
:这一列对应图片的标注,或者和图片相关的文本。image_path
:这一列对应图片所在你电脑本地上的路径。是的,搞了半天,数据就是这么简单。
数据预处理
这里的数据预处理,是我随便起的名字。说白了,就是这么会是:
使用
tokenizer
把text
转换成input_ids
和attention_mask
.使用
processor
把image
转换成pixel_values
.处理
text
,那还是很快的。百万级别的数据,可能 2~3 分钟就行了。因为
image
太大了,只能在训练的时候,每一 batch,才能去加载image
,这就导致训练的时候特别慢。倒不是因为我的 3090 算力不行,全都TMD
卡在计算机 IO 上了,非常让人难受。
模型部分
终于讲解到 clip 的模型部分了。这个 clip 模型实在是太灵活了,你可以做很多个版本,这里我们挑几个比较常见的结构,来分享一下。
常见的 clip 模型
这里值得是常见的 clip 模型,特指的是transformers
包的 clip 模型。
clip 主要就是分为两个部分,一个是
CLIPTextTransformer
,一个是CLIPVisionTransformer
,说白了就是一个处理 text,一个处理 image。CLIPTextTransformer
和CLIPVisionTransformer
的核心,都共用了一个模型结构CLIPEncoder
。也就是 CLIP 编码部分。(这里说的共用,值得是模型框架相同,而不是模型训练的时候,参数也相同。)
Q:有些人就问了,text 和 image 两个生成的数据都不一样,比如text
转换成input_ids
和attention_mask
;image
转换成pixel_values
;他们怎么可以使用一个模型结构CLIPEncoder
?
A:这个也是非常好回答的,因他俩又不是直接使用CLIPEncoder
,前后都加了一些万金油的模型组件(比如embedding
、linear
等),模型输出的时候,也是这么做的。还是应了那句话,就看你怎么吧数据转换成hidden_states
,以及怎么把hidden_states
输出出去。
Q:CLIPTextTransformer
和CLIPVisionTransformer
输出的维度也不一定一样吧,怎么计算交叉损失?
A: 也很简单啦,加个linear
对齐一下就行了。
看看CLIPTextTransformer
和CLIPVisionTransformer
的内心:
中文版本的 clip 模型
上面的常见的clip模型
,确实是好,其实你只要换一个支持中文的新tokenizer
,然后从 0️⃣开始训练即可。但是这么搞,没什么创意呀。其实我第一次就是这么干的,直接支持中文的新tokenizer
。但是训练了一天,loss 基本上没变化。我内心其实是崩溃的。
后来,我研究了一下transformers
包里面的chinese-clip
模型代码。我发现,chinese-clip
相对于clip
。就是把常规的CLIPTextTransformer
换成了bert
版本的。啊对,这就破案了。这个奉上代码截图。
后续改进
因为训练 image 这类型的任务,非常吃资源,不管是我的显存还是我的磁盘。目前数据占用我硬盘
100GB
针对 loss 不下降,下次如果再让我做,我打算先把
clip
模型的vit
部分先固定住,然后训练 bert 来拟合vit-output
。也可也固定 bert 模型,训练 vit 模型;
也可以拆开做,反正本质上都是
Encoder
,然后计算相似度。
5. 图生文 image-encoder-decoder
之前在 huggingfacehttps://huggingface.co/nlpconnect/vit-gpt2-image-captioning上看到这个模型.
感觉这个模型很有趣,想法很好。
发现这个模型关于中文的不多。
之前的
clip
训练其实挺失败的,loss
没有下降.
主要也就是抱着学习的态度,把源码看懂,把流程跑通。分享中间的细节和踩坑经历。
使用
vit
来作为encoder
部分,输出encoder_hidden_states
,绿色部分1
。使用
gpt2
来作为decoder
部分,接受encoder_hidden_states
,绿色部分3
。如果
encoder
输出的encoder_hidden_states
和decoder
接受的encoder_hidden_states
维度不一样,就加个linear
,绿色部分2
。
模型训练需要的数据样式训练的时候,模型需要的数据主要有两个维度:
pixel_value
:image
通过processor
生成label
:text
通过tokenizer
生成的input_ids
。计算
loss
的时候,其实和gpt2
一模一样的(自回归,本质上就是向后错位一下)。
目前已经把训练好的模型,发布在huggingface
上了。https://huggingface.co/yuanzhoulvpi/vit-gpt2-image-chinese-captioning
本模块处理数据的方式和clip
模型差不多,可以看隔壁文件夹,训练clip
的数据处理思路。
只要把
processdta_02.ipynb
文件替换即可。执行顺序依然按照着
processdta_01.ipynb
、processdta_02.ipynb
、processdta_03.ipynb
。
训练部分
train_encoder_decoder.ipynb
处理图像,使用的是
"google/vit-base-patch16-224"
模型。处理文本,使用的是
"yuanzhoulvpi/gpt2_chinese"
模型。最后就是把两个模型通过
VisionEncoderDecoderModel
粘起来。训练的 loss
训练的信息 gpu 使用的是 3090,模型大概是 2.16 亿个参数。花了超过 20 个小时。但是大部分时间都是卡在 IO 上(加载图片上)
推理用你自己训练参考
infer_encoder_decoder.ipynb
直接用
6.vit 源码
之前都搞过
clip
、image-encoder-decoder
。现在哪里还怕搞不懂vit
.这里主要分享一下
vit
的最核心的部分。
vit 核心的数据内容
vit 想法非常牛,但是数据处理的思想更牛,之前都没提出来过。
载对于一个图片,将一个图片分割成 N 块。巧妙的使用nn.Conv2d
。
初始化
创建一个分块器和一个样本数据(一个
batch
)
输出分块的大小
数据再转换一下,image 的 embedding 就完成了。
这个时候,就已经和文本的数据一样了。维度都是(batch_size, seq_length, embedding_dim
),再向下推导,就是transformers
了。没什么可介绍的了。
项目链接:https://github.com/yuanzhoulvpi2017/zero_nlp
更多优质内容请关注公号:汀丶人工智能;会提供一些相关的资源和优质文章,免费获取阅读。
版权声明: 本文为 InfoQ 作者【汀丶人工智能】的原创文章。
原文链接:【http://xie.infoq.cn/article/50c4e648ecc760492172393da】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论