全套解决方案:基于pytorch、transformers的中文NLP训练框架,反对大模型训练和文本生成,疾速上手,海量训练数据!

1.简介

  1. 指标:基于pytorchtransformers做中文畛域的nlp开箱即用的训练框架,提供全套的训练、微调模型(包含大模型、文本转向量、文本生成、多模态等模型)的解决方案;
  2. 数据

    • 从开源社区,整顿了海量的训练数据,帮忙用户能够疾速上手;
    • 同时也凋谢训练数据模版,能够疾速解决垂直畛域数据;
    • 联合多线程、内存映射等更高效的数据处理形式,即便须要解决百GB规模的数据,也是轻而易举;
  3. 流程:每一个我的项目有残缺的模型训练步骤,如:数据荡涤、数据处理、模型构建、模型训练、模型部署、模型图解;
  4. 模型:以后曾经反对gpt2clipgpt-neoxdollyllamachatglm-6bVisionEncoderDecoderModel等多模态大模型;
  5. 多卡串联
    :以后,少数的大模型的尺寸曾经远远大于单个生产级显卡的显存,须要将多个显卡串联,能力训练大模型、能力部署大模型。因而对局部模型构造进行批改,实现了训练时推理时
    的多卡串联性能。
  • 模型训练
中文名称文件夹名称数据数据荡涤大模型模型部署图解
中文文本分类chinese_classifier
中文gpt2chinese_gpt2
中文clipchinese_clip
图像生成中文文本VisionEncoderDecoderModel
vit外围源码介绍vit model
Thu-ChatGlm-6b(v1)simple_thu_chatglm6b
chatglm-v2-6bchatglm_v2_6b_lora
中文dolly_v2_3bdolly_v2_3b
中文llamachinese_llama
中文bloomchinese_bloom
中文falcon(留神:falcon模型和bloom构造相似)chinese_bloom
中文预训练代码model_clm
百川大模型model_baichuan
模型修剪✂️model_modify
llama2 流水线并行pipeline

2.文本分类模型

本局部,介绍中文的文本分类模型,实用于二分类、多分类等状况。应用transformers库。

  • 解决数据code_01_processdata.ipynb
  • 数据介绍

    1. 本案例应用的是一个外卖平台的评论数据,对评论的文本做了分类(分为好评和差评)
    2. 当你把code_01_processdata.ipynb文件跑完之后,就能够看到在data_all外面有一个data,外面有三个文件,款式都是像上面这样的

上图是一个batch的数据,或者所有的文本分类的数据款式:

  1. text上面的红色条,就是一个个句子。
  2. label外面有红色有绿色,就是示意标签分类。
  3. transformers包做分类的时候,数据要求就这两列。

留神点:

  1. 数据须要分为train_data.csv,test_data.csv,valid_data.csv,这三个csv文件留神是应用,宰割开的。
  2. 数据不能够有缺失值
  3. 数据最好只含有两列:label,text

    • label:示意标签,最好为整型数值。0,1,2,3,4等
    • text:示意文本,(看你需要,能够有符号,也能够没有标点符号)
  4. train_data.csv,test_data.csv,valid_data.csv这三个数据外面,不要有数据雷同的,不然会造成数据透露。
  • 训练模型code_02_trainmodel.ipynb

  • 数据训练流程
    以一个batch为例:

    1. Tokenizer会将数据中的text转换成三个矩阵(或者叫三个Tensor),别离叫input_ids,token_type_ids,attention_mask,至于怎么转换的,咱们先不做具体介绍(本仓库后续会介绍)。
    2. pretrained model在被加载之前,须要设置一大堆模型的参数,至于要设置什么参数,咱们也不做具体介绍。
    3. Trainer就是一个训练器,也须要事后设置好一大堆参数。至于要设置什么参数,咱们也不做具体介绍。
    4. Trainer会把input_ids,token_type_ids,attention_mask;还有数据自带的标签label;还有pretrained model都加载进来,进行训练;
    5. 当所有batch的数据更新完之后,最终就会生成一个模型。your new model就诞生了。
    6. 对于刚开始学习大模型做nlp分类的工作,其实不须要思考那么多细节,只须要留神数据流程。
  • 留神点:

    1. 这个步骤十分看显存大小。显卡显存越大越好。batch_size,eval_size大小取决于显存大小。
    2. 在理论工程中,会先应用Tokenizer把所有的文本转换成input_ids,token_type_ids,attention_mask,而后在训练的时候,这步就不再做了,目标是缩小训练过程中cpu解决数据的工夫,不给显卡休息时间。
    3. 在应用Tokenizer把所有的文本做转换的期间,如果设置的文本的长度下限为64,那么会把大于64的文本截断;那些少于64的文本,会在训练的时候,在喂入模型之前,把长度补齐,这么做就是为了缩小数据对内存的占用。
    1. 预测code_03_predict.ipynb

      1. 这个时候,就是搞个句子,而后丢给一个pipeline(这个就是把Tokenizer你的大模型放在一起了),而后这个pipeline就给你返回一个分类后果。
      2. 常见的就是应用pipeline,如果更加简单的话,比方批改模型,这个时候,就比较复杂了(前面会再次介绍)。
    1. 部署

      1. 简略的部署绝对于预测,其实就是再加一层web端口,fastapi包就能够实现。
      2. 高级一点的部署绝对于预测,就须要把模型从pytorch转换成onnx格局的,这样能够进步推理效率(也不肯定,就是举个例子),可能也不会应用web端口(http协定)了,会应用rpc协定等办法。这部分当初先不看。

3.中文gpt2

  1. 本文,将介绍如何应用中文语料,训练一个gpt2
  2. 能够应用你本人的数据训练,用来:写新闻、写新诗、写对联等
  3. 我这里也训练了一个中文gpt2模型,应用了612万个样本,每个样本有512个tokens,总共相当于大概31亿个tokens
  • 安装包

须要筹备好环境,也就是装置须要的包

pip install -r requirements.txt

像是pytorch这种根底的包必定也是要装置的,就不提了。

  • 数据起源

    1. 取得数据:数据链接,关注公众号【统计学人】,而后回复【gpt2】即可取得。
    2. 取得我训练好的模型(应用了15GB的数据(31亿个tokens),在一张3090上,训练了60多小时)
  • 数据格式

    1. 数据其实就是一系列文件夹,而后每一个文件夹外面有大量的文件,每一个文件都是.csv格局的文件。其中有一列数据是content
    2. 每一行的content就代表一句话
    3. 尽管数据有15GB那么大,然而解决起来一点也不简单,应用 datasets
      包,能够很轻松的解决大数据,而我只须要传递所有的文件门路即可,这个应用 glob 包就能实现。
  • 训练代码train_chinese_gpt2.ipynb

    1. 当初训练一个gpt2代码,其实很简略的。抛开解决数据问题,技术上就三点:tokenizergpt2_modelTrainer
    2. tokenizer应用的是bert-base-chinese
      ,而后再增加一下bos_tokeneos_tokenpad_token
    3. gpt2_model应用的是gpt2,这里的gpt2我是从0开始训练的。而不是应用他人的预训练的gpt2模型。
    4. Trainer训练器应用的就是transformersTrainer模块。(撑持多卡并行,tensorboard等,都写好的,间接调用就行了,十分好用)
  • 模型
  • 推理代码infer.ipynb

这个是chinese-gpt2的推理代码

  1. 将代码中的model_name_or_path = "checkpoint-36000"外面的"checkpoint-36000",批改为模型所在的门路。
  2. 而后运行上面一个代码块,即可输入文本生成后果
  3. 能够参考这个代码,制作一个api,或者打包成一个函数或者类。
  • 交互机器人界面chatbot.py
  1. 批改代码外面的第4行,这一行值为模型所在的地位,批改为我分享的模型文件门路。
model_name_or_path = "checkpoint-36000"
  1. 运行
python chatbot.py
  1. 点击链接,即可在浏览器中关上机器人对话界面
    <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原理还有相干的推理细节,这是我整顿的链接,心愿能够共同进步

  1. https://huggingface.co/blog/how-to-generate
  2. https://huggingface.co/gpt2
  3. https://huggingface.co/gpt2-large

4.中文clip模型

  1. 本文将介绍,如何从0到1的训练一个中文clip模型。
  2. 在解决数据的过程中,训练的过程中,须要的注意事项。
  3. 从数据流的角度,看看clip模型是怎么解决数据的,模型是怎么构建的。image和text的模型的差异性,两个模型是怎么合并起来计算loss的。
  • clip模型介绍

CLIP的英文全称是Contrastive Language-Image Pre-training,即一种基于比照文本-图像对的预训练方法或者模型。
CLIP是一种基于比照学习的多模态模型,与CV中的一些比照学习办法如moco和simclr不同的是,
CLIP的训练数据是文本-图像对:一张图像和它对应的文本形容,这里心愿通过比照学习,
模型可能学习到文本-图像对的匹配关系。
如下图所示,CLIP包含两个模型:

  1. Text Encoder和Image Encoder,其中Text Encoder用来提取文本的特色,能够采纳NLP中罕用的text transformer模型;
  2. Image Encoder用来提取图像的特色,能够采纳罕用CNN模型或者vision transformer。

下面这段文字来源于https://zhuanlan.zhihu.com/p/493489688

  1. 从数据上看:之前类似度计算,都是两个文本对:text - text。只不过当初都是text - image了。
  2. clip是两个模型(具体长什么样子,前面再说)
  • 2.1 text-model:负责把text转换成向量。
  • 2.2 image-model:负责把image转换成向量。
  • 2.3 而后把下面两个向量,做穿插计算loss,而后loss反向流传,这样两个模型的参数都会更新。
  1. 其实你想啊,这个image-model解决图像的,其实也能够改为解决视频、解决3d模型等。那几乎是格局关上了。我当初没有数据,前面也打算做一个。
  2. 你再想想,text-image => text-image-video-3d这样联结起来,是不是更好。没数据,没机器,做不了。
  3. 有些人可能感觉,你这人,就晓得TMD吹牛,来来来,我带你钻研钻研clip模型的源码。
  • 数据
  1. 间接点击链接[https://pan.baidu.com/s/1wGmXUNP021OWnW7Kik7q1A?pwd=gd3c
    ](https://pan.baidu.com/s/1wGmXUNP021OWnW7Kik7q1A?pwd=gd3c)来取得。
  2. 把下载好的文件,也就是test-2.6w.csvtrain-137w.csv放在文件夹bigdata/raw_data外面。
  3. 以此运行processdta_01.ipynbprocessdta_02.ipynbprocessdta_02.ipynb用来解决数据。
  • 3.1 processdta_01.ipynb:用来下载数据,大略下载了10多个小时。
  • 3.2 processdta_02.ipynb:用来筛选数据,不是所有的图片数据都是能够用的,这一步十分坑。须要注意。如果图片没有筛选好,在你训练到两头的时候,忽然一下因为图片无奈加载导致谬误,从而训练中断了。
  • 3.3 processdta_03.ipynb:用来把数据洁净的数据处理好,合并好,生成新的,丑陋的训练数据。
  1. 其实残缺下来看,数据荡涤,就是把合乎格局的照片筛选进去,而后进行训练。
  • 数据总结

说到底,你的数据只有整顿成这样的一个款式即可

textimage_path
河南一村民继承祖上的一金碗,专家鉴定:此碗是溥仪皇帝用过的bigdata/image_data/test-9282.jpg
驰名钢琴家郎朗:我永远不会放弃演奏bigdata/image_data/test-2644.jpg
科幻动作电影《超体》10月24日来袭bigdata/image_data/test-13199.jpg
  1. text:这一列对应图片的标注,或者和图片相干的文本。
  2. image_path:这一列对应图片所在你电脑本地上的门路。
  3. 是的,搞了半天,数据就是这么简略。
  • 数据预处理

这里的数据预处理,是我轻易起的名字。说白了,就是这么会是:

  1. 应用tokenizertext转换成input_idsattention_mask.
  2. 应用processorimage转换成pixel_values.
  1. 解决text,那还是很快的。百万级别的数据,可能2~3分钟就行了。
  2. 因为image太大了,只能在训练的时候,每一batch,能力去加载image
    ,这就导致训练的时候特地慢。倒不是因为我的3090算力不行,全都TMD卡在计算机IO上了,十分让人好受。
  • 模型局部

终于解说到clip的模型局部了。这个clip模型切实是太灵便了,你能够做很多个版本,这里咱们挑几个比拟常见的构造,来分享一下。

  • 常见的clip模型

这里值得是常见的clip模型,特指的是transformers包的clip模型。

  1. clip次要就是分为两个局部,一个是CLIPTextTransformer,一个是CLIPVisionTransformer,说白了就是一个解决text,一个解决image。
  2. CLIPTextTransformerCLIPVisionTransformer的外围,都共用了一个模型构造CLIPEncoder
    。也就是CLIP编码局部。(这里说的共用,值得是模型框架雷同,而不是模型训练的时候,参数也雷同。)

Q:有些人就问了,text和image两个生成的数据都不一样,比方text转换成input_idsattention_maskimage
转换成pixel_values;他们怎么能够应用一个模型构造CLIPEncoder

A:这个也是十分好答复的,因他俩又不是间接应用CLIPEncoder
,前后都加了一些万金油的模型组件(比方embeddinglinear
等),模型输入的时候,也是这么做的。还是应了那句话,就看你怎么吧数据转换成hidden_states,以及怎么把hidden_states输入进来。

Q:CLIPTextTransformerCLIPVisionTransformer输入的维度也不肯定一样吧,怎么计算穿插损失?

A: 也很简略啦,加个linear对齐一下就行了。

看看CLIPTextTransformerCLIPVisionTransformer的心田:

  • 中文版本的clip模型

下面的常见的clip模型,的确是好,其实你只有换一个反对中文的新tokenizer,而后从0️开始训练即可。
然而这么搞,没什么创意呀。其实我第一次就是这么干的,间接反对中文的新tokenizer。然而训练了一天,loss基本上没变动。我心田其实是解体的。

起初,我钻研了一下transformers包外面的chinese-clip模型代码。我发现,chinese-clip绝对于clip
。就是把惯例的CLIPTextTransformer换成了bert版本的。啊对,这就破案了。这个奉上代码截图。

  • 后续改良
  1. 因为训练image这类型的工作,十分吃资源,不论是我的显存还是我的磁盘。目前数据占用我硬盘100GB
  2. 针对loss不降落,下次如果再让我做,我打算先把clip模型的vit局部先固定住,而后训练bert来拟合vit-output
  3. 也可也固定bert模型,训练vit模型;
  4. 也能够拆开做,反正实质上都是Encoder,而后计算类似度。

5. 图生文image-encoder-decoder

之前在huggingfacehttps://huggingface.co/nlpconnect/vit-gpt2-image-captioning上看到这个模型.

  1. 感觉这个模型很乏味,想法很好。
  2. 发现这个模型对于中文的不多。
  3. 之前的clip训练其实挺失败的,loss没有降落.

次要也就是抱着学习的态度,把源码看懂,把流程跑通。分享两头的细节和踩坑经验。

  1. 应用vit来作为encoder局部,输入encoder_hidden_states绿色局部1
  2. 应用gpt2来作为decoder局部,承受encoder_hidden_states,绿色局部3
  3. 如果encoder输入的encoder_hidden_statesdecoder承受的encoder_hidden_states维度不一样,就加个linear,绿色局部2
  • 模型训练须要的数据款式
    训练的时候,模型须要的数据次要有两个维度:
  • pixel_valueimage通过processor生成
  • labeltext通过tokenizer生成的input_ids
  • 计算loss的时候,其实和gpt2截然不同的(自回归,实质上就是向后错位一下)。

目前曾经把训练好的模型,公布在huggingface上了。https://huggingface.co/yuanzhoulvpi/vit-gpt2-image-chinese-captioning

本模块解决数据的形式和clip模型差不多,能够看隔壁文件夹,训练clip的数据处理思路。

  1. 只有把processdta_02.ipynb文件替换即可。
  2. 执行程序仍然依照着processdta_01.ipynbprocessdta_02.ipynbprocessdta_03.ipynb
  • 训练局部train_encoder_decoder.ipynb

    1. 解决图像,应用的是"google/vit-base-patch16-224"模型。
    2. 解决文本,应用的是"yuanzhoulvpi/gpt2_chinese"模型。
    3. 最初就是把两个模型通过VisionEncoderDecoderModel粘起来。
  • 训练的loss
  • 训练的信息
    gpu应用的是3090,模型大略是2.16亿个参数。花了超过20个小时。然而大部分工夫都是卡在IO上(加载图片上)

  • 推理用你本人训练
    参考infer_encoder_decoder.ipynb
  • 间接用

    from transformers import (VisionEncoderDecoderModel,                         AutoTokenizer,ViTImageProcessor)import torchfrom 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 = 16num_beams = 4gen_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 predspredict_step(['bigdata/image_data/train-1000200.jpg'])

6.vit 源码

  1. 之前都搞过clipimage-encoder-decoder。当初哪里还怕搞不懂vit.
  2. 这里次要分享一下vit的最外围的局部。
  • vit 外围的数据内容

vit想法十分牛,然而数据处理的思维更牛,之前都没提出来过。

载对于一个图片,将一个图片宰割成N块。奇妙的应用nn.Conv2d

  • 初始化

    import torchfrom torch import nn #base parameterimage_size=224 # 图片的width和heightpatch_size=16  # 将图片的分为块,每一块的大小为16x16,这样就有(224//16)^2 = 14 ^2 = 196个num_channels=3 #  R,G, Bhidden_size=768 # 输入的hidden_sizebatch_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.shapepixel_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

更多优质内容请关注公号:汀丶人工智能;会提供一些相干的资源和优质文章,收费获取浏览。