全套解决方案:基于 pytorch、transformers 的中文 NLP 训练框架,反对大模型训练和文本生成,疾速上手,海量训练数据!
1. 简介
指标
:基于pytorch
、transformers
做中文畛域的 nlp 开箱即用的训练框架,提供全套的训练、微调模型(包含大模型、文本转向量、文本生成、多模态等模型)的解决方案;-
数据
:- 从开源社区,整顿了海量的训练数据,帮忙用户能够疾速上手;
- 同时也凋谢训练数据模版,能够疾速解决垂直畛域数据;
- 联合多线程、内存映射等更高效的数据处理形式,即便须要解决
百 GB
规模的数据,也是轻而易举;
流程
:每一个我的项目有残缺的模型训练步骤,如:数据荡涤、数据处理、模型构建、模型训练、模型部署、模型图解;模型
:以后曾经反对gpt2
、clip
、gpt-neox
、dolly
、llama
、chatglm-6b
、VisionEncoderDecoderModel
等多模态大模型;多卡串联
:以后,少数的大模型的尺寸曾经远远大于单个生产级显卡的显存,须要将多个显卡串联,能力训练大模型、能力部署大模型。因而对局部模型构造进行批改,实现了训练时
、推理时
的多卡串联性能。
- 模型训练
中文名称 | 文件夹名称 | 数据 | 数据荡涤 | 大模型 | 模型部署 | 图解 |
---|---|---|---|---|---|---|
中文文本分类 | chinese_classifier | ✅ | ✅ | ✅ | ❌ | ✅ |
中文gpt2 |
chinese_gpt2 | ✅ | ✅ | ✅ | ✅ | ❌ |
中文clip |
chinese_clip | ✅ | ✅ | ✅ | ❌ | ✅ |
图像生成中文文本 | VisionEncoderDecoderModel | ✅ | ✅ | ✅ | ❌ | ✅ |
vit 外围源码介绍 | vit model | ❌ | ❌ | ❌ | ❌ | ✅ |
Thu-ChatGlm-6b (v1 ) |
simple_thu_chatglm6b | ✅ | ✅ | ✅ | ✅ | ❌ |
🌟chatglm-v2 -6b🎉 |
chatglm_v2_6b_lora | ✅ | ✅ | ✅ | ❌ | ❌ |
中文dolly_v2_3b |
dolly_v2_3b | ✅ | ✅ | ✅ | ❌ | ❌ |
中文llama |
chinese_llama | ✅ | ✅ | ✅ | ❌ | ❌ |
中文bloom |
chinese_bloom | ✅ | ✅ | ✅ | ❌ | ❌ |
中文falcon (留神:falcon 模型和 bloom 构造相似) |
chinese_bloom | ✅ | ✅ | ✅ | ❌ | ❌ |
中文 预训练 代码 | model_clm | ✅ | ✅ | ✅ | ❌ | ❌ |
百川大模型 | model_baichuan | ✅ | ✅ | ✅ | ✅ | ❌ |
模型修剪✂️ | model_modify | ✅ | ✅ | ✅ | ||
llama2 流水线并行 | pipeline | ✅ | ✅ | ✅ | ❌ | ❌ |
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
- 安装包
须要筹备好环境,也就是装置须要的包
pip install -r requirements.txt
像是 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 等,都写好的,间接调用就行了,十分好用)
- 当初训练一个 gpt2 代码,其实很简略的。抛开解决数据问题,技术上就三点:
- 模型
- 推理代码
infer.ipynb
这个是 chinese-gpt2
的推理代码
- 将代码中的
model_name_or_path = "checkpoint-36000"
外面的"checkpoint-36000"
, 批改为模型所在的门路。 - 而后运行上面一个代码块,即可输入文本生成后果
- 能够参考这个代码,制作一个 api,或者打包成一个函数或者类。
- 交互机器人界面
chatbot.py
- 批改代码外面的第 4 行,这一行值为模型所在的地位,批改为我分享的模型文件门路。
model_name_or_path = "checkpoint-36000"
- 运行
python chatbot.py
- 点击链接,即可在浏览器中关上机器人对话界面
<img src=”https://github.com/yuanzhoulvpi2017/zero_nlp/raw/main/images/chinesegpt2_bot.png”/>
- 更多
- 这个残缺的我的项目下来,其实我都是全靠
huggingface
文档、教水平过去的. - 我做的货色,也就是把
Tokenizer
改成中文的了,而后也整顿了数据,别的大部分货色,都不是我做的了. - 原文链接为 https://huggingface.co/course/zh-CN/chapter7/6?fw=pt.
其实,我更喜爱做利用,然而也要了解相干的背地原理,目前还在钻研相干的 gpt2 原理还有相干的推理细节,这是我整顿的链接,心愿能够共同进步
- https://huggingface.co/blog/how-to-generate
- https://huggingface.co/gpt2
- https://huggingface.co/gpt2-large
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
](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 |
---|---|
河南一村民继承祖上的一金碗, 专家鉴定: 此碗是溥仪皇帝用过的 | bigdata/image_data/test-9282.jpg |
驰名钢琴家郎朗: 我永远不会放弃演奏 | bigdata/image_data/test-2644.jpg |
科幻动作电影《超体》10 月 24 日来袭 | bigdata/image_data/test-13199.jpg |
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
-
间接用
from transformers import (VisionEncoderDecoderModel, AutoTokenizer,ViTImageProcessor) import torch from PIL import Image
vision_encoder_decoder_model_name_or_path = "yuanzhoulvpi/vit-gpt2-image-chinese-captioning"#"vit-gpt2-image-chinese-captioning/checkpoint-3200" processor = ViTImageProcessor.from_pretrained(vision_encoder_decoder_model_name_or_path) tokenizer = AutoTokenizer.from_pretrained(vision_encoder_decoder_model_name_or_path) model = VisionEncoderDecoderModel.from_pretrained(vision_encoder_decoder_model_name_or_path) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model.to(device)
max_length = 16 num_beams = 4 gen_kwargs = {"max_length": max_length, "num_beams": num_beams} def predict_step(image_paths): images = [] for image_path in image_paths: i_image = Image.open(image_path) if i_image.mode != "RGB": i_image = i_image.convert(mode="RGB") images.append(i_image) pixel_values = processor(images=images, return_tensors="pt").pixel_values pixel_values = pixel_values.to(device) output_ids = model.generate(pixel_values, **gen_kwargs) preds = tokenizer.batch_decode(output_ids, skip_special_tokens=True) preds = [pred.strip() for pred in preds] return preds predict_step(['bigdata/image_data/train-1000200.jpg'])
6.vit 源码
- 之前都搞过
clip
、image-encoder-decoder
。当初哪里还怕搞不懂vit
. - 这里次要分享一下
vit
的最外围的局部。
- vit 外围的数据内容
vit 想法十分牛,然而数据处理的思维更牛,之前都没提出来过。
载对于一个图片,将一个图片宰割成 N 块。奇妙的应用nn.Conv2d
。
-
初始化
import torch from torch import nn #base parameter image_size=224 # 图片的 width 和 height patch_size=16 # 将图片的分为块,每一块的大小为 16x16,这样就有(224//16)^2 = 14 ^2 = 196 个 num_channels=3 # R,G, B hidden_size=768 # 输入的 hidden_size batch_size = 16 # 一批数据有多少
-
创立一个分块器和一个样本数据(一个
batch
)# 分块器 project = nn.Conv2d(num_channels, hidden_size, kernel_size=patch_size, stride=patch_size) #样本数据(一个 `batch`) #batch_size, num_channels, height, width = pixel_values.shape pixel_values = torch.randn(batch_size, num_channels, image_size, image_size) pixel_values.shape
-
输入分块的大小
project(pixel_values).shape #> torch.Size([16, 768, 14, 14])
-
数据再转换一下,image 的 embedding 就实现了。
image_embedding = project(pixel_values).flatten(2).transpose(1, 2) image_embedding.shape #> torch.Size([16, 196, 768]) # batch_size, seq_length, embedding_dim
这个时候,就曾经和文本的数据一样了。维度都是 (batch_size, seq_length, embedding_dim
),再向下推导,就是transformers
了。没什么可介绍的了。
我的项目链接:https://github.com/yuanzhoulvpi2017/zero_nlp
更多优质内容请关注公号:汀丶人工智能;会提供一些相干的资源和优质文章,收费获取浏览。