1.llm_aigc
下载本文pdf:https://github.com/daiwk/collections/blob/master/pdfs/llm_aigc.pdf
各种学习相关代码
https://github.com/daiwk/llms_new
从word2v到Transformer
LSTM
fasttext&word2vec
注:w2v训练时的内积不是2个emb-in的内积,而是emb-in和emb-out的内积
Dictionary::readWord
:空格分割,一次读出来一个wordDictionary::add
:每个word求个hash,加进词典时,id就是从0开始的序号,同时记录一下词频Dictionary::threshold
:按词频排序,扔掉低频词Dictionary::initNgrams
:每个词,加上前缀BOW(<)和后缀(>),然后先扔进这个词的subwords里,然后再调用Dictionary::computeSubwords
把这个词的ngrams也扔进它的subwords里
整个词表,是word数+bucket这么大,其中bucket表示可容纳的subwords和wordNgrams的数量,默认200w
为什么Word2Vec训练中, 需要对负采样权重开3/4次幂?
Distributed Representations of Words and Phrases and their Compositionality里提到
通过对权重开3/4次幂,可以提升低频词被抽到的概率。在保证高频词容易被抽到的大方向下,通过权重3/4次幂的方式,适当提升低频词、罕见词被抽到的概率。如果不这么做,低频词,罕见词很难被抽到,以至于不被更新到对应的Embedding。
BPE/WordPiece分词
【Subword】深入理解NLP Subword算法:BPE、WordPiece、ULM
Transformer原理
http://jalammar.github.io/illustrated-transformer/
Transformers Assemble(PART I) 讲了3篇
Transformers Assemble(PART II) 又讲了三篇
为什么层次化softmax没人用了
Transformer 结构中最后一层 softmax 为什么不再使用 层次化softmax了呢?
主要还是计算资源的问题。
Mikolov发明word2vec的几个版本大概在13-14年前后。那个时候GPU非常少见,印象里面CMU的NLP组没有GPU,Stanford NLP lab只有6块K40。
大规模直接算softmax是在google的14年那篇seq2seq做MT的文章。为了快,把一个softmax并行在4块GPU上,每个GPU负责四分之一。那个年代,大多数NLP组全组都不会有4块GPU。
hierarchical softmax是softmax的近似,suboptimal的。当如今计算资源足够大的时候,当然包括时间和显存 (BERT 和 Elmo 都没有用hierarchical),hierarchical softmax就逐渐退出了历史舞台。
Transformer会不会规划未来
Do Language Models Plan for Future Tokens?
在训练期间的梯度既会为当前token位置的损失优化权重,也会为该序列后面的token进行优化,那么这二者会以怎样的比例分配资源?
预缓存假设(pre-caching hypothesis):在时间步计算与当前时间步的推理任务无关但可能对未来时间步有用的特征
面包屑假设(breadcrumbs hypothesis):与时间步最相关的特征已经等同于将在时间步最有用的特征。
设计了一种合成场景,其中只能通过显式的预缓存完成任务,即模型必须为下一token预先计算信息,**否则就无法在一次单向通过中准确计算出正确答案。**发现明显的证据说明transformer可以学习预缓存,即当必须预计算信息来最小化损失时,它们就会这样做。
但在真实语言数据上,语言模型并不会显著地准备用于未来的信息。相反,它们是计算对预测下一个token有用的特征——事实证明这对未来的步骤也很有用。
Transformer的FLOPS和访存带宽
https://zhuanlan.zhihu.com/p/624740065
的shape是,的shape是,那么矩阵乘法需要次的乘法,也需要同样多次的加法,所以FLOPS是
假设batchsize是,序列长度,原来的emb是,即输入的是,一般,、、都是,对应的Q、K、V矩阵都是,有个头,每个头的维度
attention的FLOPS
attention的公式:
计算3个Q、K、V:要算三次和的矩阵乘法,所以是:
输入:和3个
输出:,再把最后一维拆成份,再把中间两维互换一下,得到
计算Q和K的相似度:要算一次和的矩阵乘法,
输入:和
输出:
把相似度用到V上:要算一次和的矩阵乘法,,
输入:和
输出:
最后过一个线性映射:要算一次的和的矩阵乘法,
输入:和
输出:
因为,单纯计算attention总共就是
FFN的FLOPS
FFN的公式:
在原始Transformer中,的shape是,的shape是,
第一个线性层:
输入:和
输出:
第二个线性层:
输入:和
输出:
所以一层Transformer,即attention+FFN的计算量为
有两点需要注意的:
对NLP任务来讲,一般是个比较固定的值,如512,而变大,效果会更好,所以一般是,所以复杂度取决于的大小。
但有些模型的初始设置不是这样的,例如GPT3的175B模型里,,当然,算力够的话也可以把变大
自己感觉:既然是,其实就是和的大小,即和的大小,如果,则起主导,反之起主导
DIN的FLOPS
特殊地,对于推荐中的DIN那种,看当前item和历史s个item的相关性,即q的序列长度只有1,不考虑多头,而这其实也是decoder预测下一个词时过一层Transformer的复杂度
已经有3个序列长度为的QKV的cache,要算第个词和这个词的attention
计算第个词的3个Q、K、V:要算三次$1\times d$和的矩阵乘法,所以是:
输入:和3个
输出:
计算Q和K的相似度:要算一次和的矩阵乘法,【这里的K是历史长度的序列拼上当前词,当然对DIN来讲要去掉当前词,这里先忽略这个】
输入:和
输出:
把相似度用到V上:要算一次和的矩阵乘法,,【同样地,这里的V是历史长度的序列拼上当前词,当然对DIN来讲要去掉当前词,这里先忽略这个】
输入:和
输出:
最后过一个线性映射:要算一次的和的矩阵乘法,
输入:和
输出:
第一个线性层:
输入:和
输出:
第二个线性层:
输入:和
输出:
总共是
Transformer的访存
GPU架构的介绍参考https://developer.nvidia.com/blog/nvidia-ampere-architecture-in-depth/和https://www.zhihu.com/question/319355296/answer/2193938981,GPU对比CPU如下:
任务模式
CPU由专为顺序串行处理而优化的几个核心组成
GPU则拥有一个由数以千计的更小、更高效的核心(专为同时处理多重任务而设计)组成的大规模并行计算架构。同时CPU相当的一部分时间在执行外设的中断、进程的切换等任务,而GPU有更多的时间并行计算。
功能定位
CPU不但要承担计算任务还有承担逻辑控制等任务。
GPU在渲染画面时需要同时渲染数以百万记的顶点或三角形,故GPU的设计是可以充分支持并行计算。
系统集成
GPU作为一类外插设备,在尺寸、功率、散热、兼容性等方面的限制远远小于CPU,这样可以让GPU有较大的显存和带宽。
以A100为例,整体架构如下
PCIE层:通过PCIE接口以外设的方式集成到服务器上。
中间一坨绿色的部分是GPU的计算核心SM(Streaming Multiprocessor),在A100中,一个SM有64个用于计算的Core,共108个SM(图里是GA100,有128个SM),故共6192个Core。
中间蓝色部分是L2缓存
NVLink:多个GPU间进行通信的组件,会优化GPU间的通信,提升传输效率。
两侧的HBM2是显存,目前的A100的显存有两种40G and 80G
A100的SM如图所示,
GPU的显存分成两部分:
Global Memory:整体架构图中的两侧HBM2部分,例如A100 80G就有80G的global memory,2TB/s带宽,访问速度比较慢
Shared Memory:SM图中浅蓝色的L1 Data Cache,例如A100中每个SM中有192KB,访问速度比较快
从图中可见,A100的FP16有312T的FLOPS
以矩阵乘法为例,,
计算时间:
访存时间为:,因为首先要读取和这两个矩阵,然后结果还要写入这个矩阵里。假设是fp16,占2bytes,那就还要乘以2
假设,以计算Q和K的相似度为例,对比一下训练和预测时的计算耗时和访存耗时
训练时:==>计算是瓶颈
FLOPS:
计算耗时:
访存耗时:
预测时:==>访存是瓶颈
FLOPS:
计算耗时:
访存耗时:
一些常见的名词:
H2D:host to device,从cpu拷贝到gpu
D2H:device to host,从gpu拷贝到cpu
Transformer加速
lightseq
LightSeq: A High Performance Inference Library for Transformers
LightSeq2: Accelerated Training for Transformer-based Models on GPUs
https://github.com/bytedance/lightseq
PLM:仅编码器/仅解码器/编码器+解码器
仅编码器的BERT
BERT小学生级上手教程,从原理到上手全有图示,还能直接在线运行
主要讲了下面3篇:
Language Models as Knowledge Bases?
Linguistic Knowledge and Transferability of Contextual Representations
What does BERT learn about the structure of language?
A Primer in BERTology: What we know about how BERT works
摘要:目前,基于 Transformer 的模型已经广泛应用于自然语言处理中,但我们依然对这些模型的内部工作机制知之甚少。在本文中,来自麻省大学洛威尔分校的研究者对流行的 BERT 模型进行综述,并综合分析了 40 多项分析研究。他们还概览了对模型和训练机制提出的改进,然后描画了未来的研究方向。
Pre-trained Models for Natural Language Processing: A Survey
ALBERT、XLNet,NLP技术发展太快,如何才能跟得上节奏?
绝对干货!NLP预训练模型:从transformer到albert
ALBERT一作蓝振忠:预训练模型应用已成熟,ChineseGLUE要对标GLUE基准
BERT模型超酷炫,上手又太难?请查收这份BERT快速入门指南!
multi-head att 实现
输入原始的query(即from_tensor)之后, 把[batch, from_seq, emb]
变成[?, emb]
,其中?=batch*from_seq
然后再接一个fc,把[?, emb]
变成[?, head_num * per_head]
,一般head_num * per_head=emb
。
因为?=batch*from_seq
,所以可以直接做如下变换
实际就是把?
拆开成batch, from_seq
,整个变成[batch, from_seq, head_num, per_head]
,然后做了个 transpose,把1和2互换了下,得到[batch, head_num, from_seq, per_head]
然后key也做完全一样的操作(不过处理的是to_tensor,如果是self-attention,那to_tensor=from_tensor), 得到[batch, head_num, to_seq, per_head]
:
然后就算了,注意这里对key取了转置,也就是[batch, head_num, from_seq, per_head]
乘以[batch, head_num, per_head, to_seq]
,得到的结果是[batch, head_num, from_seq, to_seq]
:
然后看下value的操作:
再确认一点,是[batch, head_num, from_seq, to_seq]
,而是[batch, head_num, to_seq, per_head]
,所以context_layer是[batch, head_num, from_seq, per_head]
最后,再搞一下,变回[batch, from_seq, head_num * per_head]
:
如上过程是,其中。包装在了函数attention_layer
之中,我们注意到原文还有一个大小为的,也就是大小为,再看看源码。。也就是说,正常的bert里,attention_heads
就只有一个元素,然后接了个hidden_size
的fc,而前面的代码里也提到了hidden_size
正好就是,所以这就是。
关于 mask,可以看看这个https://juejin.im/post/5b9f1af0e51d450e425eb32d
摘抄一下:
什么是padding mask呢?回想一下,我们的每个批次输入序列长度是不一样的!也就是说,我们要对输入序列进行对齐!具体来说,就是给在较短的序列后面填充0。因为这些填充的位置,其实是没什么意义的,所以我们的attention机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。 具体的做法是,把这些位置的值加上一个非常大的负数(可以是负无穷),这样的话,经过softmax,这些位置的概率就会接近0!
而sequence mask是为了使得decoder不能看见未来的信息。也就是对于一个序列,在time_step为t的时刻,我们的解码输出应该只能依赖于t时刻之前的输出,而不能依赖t之后的输出。因此我们需要想一个办法,把t之后的信息给隐藏起来。 那么具体怎么做呢?也很简单:产生一个上三角矩阵,上三角的值全为1,下三角的值权威0,对角线也是0。把这个矩阵作用在每一个序列上,就可以达到我们的目的啦。
masked-language-model的实现
如下,其中hidden_size
就是是:
其中的gather如下:
注意调用时传的是如下参数
BERT的可解释性
What does BERT learn about the structure of language?
探索BERT深层次的表征学习是一个非常有必要的事情,一是这可以帮助我们更加清晰地认识BERT的局限性,从而改进BERT或者搞清楚它的应用范围;二是这有助于探索BERT的可解释性
更复杂的BERT
Bert时代的创新(应用篇):Bert在NLP各领域的应用进展
中文BERT
WWM
哈工大讯飞联合实验室发布基于全词覆盖的中文BERT预训练模型
https://github.com/ymcui/Chinese-BERT-wwm
论文:Pre-Training with Whole Word Masking for Chinese BERT
ERNIE
参考中文任务全面超越BERT:百度正式发布NLP预训练模型ERNIE
ERNIE: Enhanced Representation through Knowledge Integration
使用entity-level masking和phrase-level masking两种mask方法
输入的每个样本由5个 ';' 分隔的字段组成,数据格式:
token_ids
sentence_type_ids:两句话,第一句都是0,第二句都是1
position_ids
seg_labels:分词边界信息: 0表示词首、1表示非词首、-1为占位符, 其对应的词为 CLS 或者 SEP;
next_sentence_label
例如:
和bert在mask上的区别:
一个句子的不同level的mask方式:
ERNIE 2.0: A CONTINUAL PRE-TRAINING FRAMEWORK FOR LANGUAGE UNDERSTANDING
跨语言
XLM
Massively Multilingual Sentence Embeddings for Zero-Shot Cross-Lingual Transfer and Beyond,XLM的主要思想还是来自于这篇文章,借用了BERT的框架最后成了XLM。本文提出了LASER(Language-Agnostic SEntence Representations)
XLM:facebook提出Cross-lingual Language Model Pretraining,加了language emb
无监督的方法:只依赖单语种数据(monolingual data)
有监督的方法:对平行语料使用新的跨语言loss
Facebook最新语言模型XLM-R:多项任务刷新SOTA,超越单语BERT
XLM-R
Unsupervised Cross-lingual Representation Learning at Scale
来自facebook。针对多种跨语言的传输任务,大规模地对多语言语言模型进行预训练可以显著提高性能。在使用超过 2TB 的已过滤 CommonCrawl 数据的基础上,研究者在 100 种语言上训练了基于 Transformer 的掩模语言模型。该模型被称为 XLM-R,在各种跨语言基准测试中,其性能显著优于多语言 BERT(mBERT),其中 XNLI 的平均准确度为+ 13.8%,MLQA 的平均 F1 得分为+ 12.3%,而 FQ 的平均 F1 得分为+ 2.1% NER。XLM-R 在低资源语言上表现特别出色,与以前的 XLM 模型相比,斯瓦希里语(Swahili)的 XNLI 准确性提升了 11.8%,乌尔都语(Urdu)的准确性提升了 9.2%。研究者还对获得这些提升所需的关键因素进行了详细的实证评估,包括(1)积极转移和能力稀释;(2)大规模资源资源的高低性能之间的权衡。最后,他们首次展示了在不牺牲每种语言性能的情况下进行多语言建模的可能性。XLM-Ris 在 GLUE 和 XNLI 基准测试中具有强大的单语言模型,因此非常具有竞争力。
更长序列
transformer-xl
Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context
最简单的处理长文本方法:对长文本直接切成多个segment,每个segment独立过transformer,segment间是没有信息流动的
transformer-xl的处理方法:参考RNN的隐藏记忆单元,对上一个segment计算的隐藏状态序列进行fixed和cached,并在模型处理下一个新的segment时将其缓存为可重用的扩展上下文。
如图,第k+1层的第i个元素,用到了第k层的第i-1, i-2, ...,i - segment_len+1这几个元素,所以对于最顶层的来讲,实际看到的窗口就更长了。为此还提出了相对位置编码,即使用两个token的相对距离代替之前的绝对位置。
此外,Stabilizing Transformers for Reinforcement Learning说明了为什么标准的transformer架构很难在强化学习中优化。研究者同时提出了一种架构Gated Transformer-XL(GTrXL),可以很好地提升transformer架构和变体的稳定性,并加速学习,可以超过LSTM,在多任务学习 DMLab-30 基准上达到 SOTA 的水平。
XLNet
20项任务全面碾压BERT,CMU全新XLNet预训练模型屠榜(已开源)
XLNet: Generalized Autoregressive Pretraining for Language Understanding
代码:https://github.com/zihangdai/xlnet
自回归(autoregressive, AR):主要的论文有这几篇:Semi-supervised sequence learning、Deep contextualized word representations、Improving language understanding by generative pre-training。通过一个autoregressive的模型来估计文本语料库的概率分布。也就是给定一个文本序列,AR将likelihood因式分解(factorize)成一个前向的乘积,或者是一个后向的乘积。由于 AR 语言模型仅被训练用于编码单向(uni-directional)语境(前向或后向),因而在深度双向语境建模中效果不佳。而下游语言理解任务通常需要双向语境信息,导致 AR 语言建模无法实现有效预训练。
自编码(autoencoding, AE):相关的预训练模型不会进行明确的密度估计(explicit density estimation),而是从残缺的(corrupted)输入中重建原始数据。例如bert,使用一定比例的
[MASK]
,然后预测被mask掉的是什么东西。由于目标并不是密度估计,所以在重建的时候,可以考虑双向的上下文信息。但存在如下两个问题:finetune时的真实数据缺少预训练期间使用的
[MASK]
这些mask信息,这导致预训练和微调效果的差异(pretrain-finetune discrepancy)。输入中要预测的token是被mask掉的,所以无法像AR那样使用乘积rule来建立联合概率分布。也就是说,给定未mask的 token,BERT假设预测的token之间彼此独立,这其实是对自然语言中普遍存在的高阶、长期依赖关系的一种过度简化。
基于这些优缺点,提出了一种泛化的自回归预训练模型XLNet:
Permutation Language Model(PLM):在自回归LM模式下,最大化所有可能的因式分解顺序的对数似然,学习双向语境信息;
把原来的
[MASK]
这个token干掉了,转而用attention mask来搞引入了排列:即原来是1234,可以输入3241,这个时候改一下mask就行
引入了Transformer-XL的主要思路:相对位置编码以及分段RNN机制,实践已经证明这两点对于长文档任务是很有帮助的
更多的任务
MT-DNN
Multi-Task Deep Neural Networks for Natural Language Understanding
其他改进
RoBERTa
参考重回榜首的BERT改进版开源了,千块V100、160GB纯文本的大模型
RoBERTa: A Robustly Optimized BERT Pretraining Approach
修改了一些超参
删掉nsp任务
更大的batchsize和学习率
RoBERTa中文预训练模型,你离中文任务的「SOTA」只差个它
https://github.com/brightmart/roberta_zh
DeBERTa
Deberta: Decoding-enhanced bert with disentangled attention
disentangled attention mechanism:每个词使用2个向量,编码内容,编码相对位置,i和j间的attention如下:
预训练:使用enhanced mask decoder,把绝对位置信息引入解码层,来预估被mask掉的token
finetune:virtual adversarial training
ELECTRA
2019最佳预训练模型:非暴力美学,1/4算力超越RoBERTa
ELECTRA: 超越BERT, 19年最佳NLP预训练模型
ELECTRA: pre-training text encoders as discriminators rather than generators
使用新的预训练task:RTD(replaced token detection):
使用一个生成网络采样出token,替换一些原有的token
训练一个判别模型,预估一个token是否是被替换的
RTD比MLM更sample-efficient,因为RTD只做二分类,而MLM需要做全词表的softmax
sentence Transformers
Matryoshka representation learning
俄罗斯套娃嵌入模型旨在将更重要的信息存储在早期的维度中,将不太重要的信息存储在后面的维度中。俄罗斯套娃嵌入模型的这一特点允许我们截断模型产生的原始 (大) 嵌入,同时仍保留足够的信息以在下游任务上表现良好。
https://sbert.net/examples/training/matryoshka/README.html
训练时:
预测时
注意,如果嵌入已经归一化,那么在截断后它们将不再归一化,因此你可能需要重新归一化。
Piccolo2
拿下SOTA!最强中文Embedding模型对标OpenAI,技术路线公开
Piccolo2: General Text Embedding with Multi-task Hybrid Loss Training
https://huggingface.co/sensenova/piccolo-large-zh-v2
更小的BERT
BERT 瘦身之路:Distillation,Quantization,Pruning
albert
刚刚,Google发布24个小型BERT模型,直接通过MLM损失进行预训练
谷歌ALBERT模型V2+中文版来了:之前刷新NLP各大基准,现在GitHub热榜第二
超小型BERT中文版横空出世!模型只有16M,训练速度提升10倍
https://github.com/brightmart/albert_zh
预训练小模型也能拿下13项NLP任务,谷歌ALBERT三大改造登顶GLUE基准
ALBERT 模型在 GLUE、RACE 和 SQuAD 基准测试上都取得了新的 SOTA 效果,并且参数量还少于 BERT-large。
ALBERT: a lite bert for self-supervised learning of language representations
通过对词嵌入矩阵进行因式分解,再为下游任务共享不同层的所有参数,这样可以大大降低 BERT 的参数量。
还提出了一种新型句间连贯性损失函数,它可以强迫模型学习句间的连贯性表达,从而有利于各种下游 NLP 任务。
ALBERT 通过两个参数削减技术克服了扩展预训练模型面临的主要障碍。
对嵌入参数化进行因式分解:将大的嵌入矩阵分解为两个小的矩阵,从而将隐藏层的大小与词汇嵌入的大小分离开来。这种分离使得隐藏层的增加更加容易,同时不显著增加词汇嵌入的参数量。
跨层参数共享:避免参数量随着网络深度的增加而增加。
两种技术都显著降低了 BERT 的参数量,同时不对其性能造成明显影响,从而提升了参数效率。ALBERT 的配置类似于 BERT-large,但参数量仅为后者的 1/18,训练速度却是后者的 1.7 倍。这些参数削减技术还可以充当某种形式的正则化,可以使训练更加稳定,而且有利于泛化。
为了进一步提升 ALBERT 的性能,还引入了一个自监督损失函数,用于句子级别的预测(SOP)。SOP 主要聚焦于句间连贯,用于解决原版 BERT 中下一句预测(NSP)损失低效的问题。
albert_tiny:
input_ids先查word_embeddings(\(V\times E=21118*128)
),得到dim=128的表示,再查word_embeddings_2(\(E\times M =128*312\)
),得到dim=312的表示。
搞positionembedding时,并不用输入0 1 2...,只需要做一些slice的变换就行了
然后会通过create_attention_mask_from_input_mask把input_ids和input_mask搞一下,得到attention_mask去和attention做mask,主要是算loss啥的,把后面的mask掉不算
distillbert
1.4w个stars。。
https://huggingface.co/transformers
DistilBERT, a distilled version of BERT: smaller, faster, cheaper and lighter
tinybert
TinyBERT:模型小7倍,速度快8倍,华中科大、华为出品
TinyBERT: Distilling BERT for Natural Language Understanding
提出了一个two-stage learning framework,在pre-training阶段和task-specific阶段都进行distill。
相比baseline,只有28% parameters和31%的inference时间
在glue上,7.5x小,infer上有9.4x快。
NEZHA: Neural Contextualized Representation for Chinese Language Understanding
https://github.com/huawei-noah/Pretrained-Language-Model
reformer
哈希革新Transformer:这篇ICLR高分论文让一块GPU处理64K长度序列
Reformer: The Efficient Transformer
https://github.com/google/trax/blob/master/trax/models/research/reformer.py
大型的 Transformer 往往可以在许多任务上实现 sota,但训练这些模型的成本很高,尤其是在序列较长的时候。在 ICLR 的入选论文中,我们发现了一篇由谷歌和伯克利研究者发表的优质论文。文章介绍了两种提高 Transformer 效率的技术,最终的 Reformer 模型和 Transformer 模型在性能上表现相似,并且在长序列中拥有更高的存储效率和更快的速度。论文最终获得了「8,8,6」的高分。在最开始,文章提出了将点乘注意力(dot-product attention)替换为一个使用局部敏感哈希(locality-sensitive hashing)的点乘注意力,将复杂度从 O(L2 ) 变为 O(L log L),此处 L 指序列的长度。此外,研究者使用可逆残差(reversible residual layers)代替标准残差(standard residuals),这使得存储在训练过程中仅激活一次,而不是 n 次(此处 n 指层数)。最终的 Reformer 模型和 Transformer 模型在性能上表现相同,同时在长序列中拥有更高的存储效率和更快的速度。
大幅减少GPU显存占用:可逆残差网络(The Reversible Residual Network)
LTD-bert
内存用量1/20,速度加快80倍,腾讯QQ提出全新BERT蒸馏框架,未来将开源
Q-bert
AAAI 2020 | 超低精度量化BERT,UC伯克利提出用二阶信息压缩神经网络
Q-BERT: Hessian Based Ultra Low Precision Quantization of BERT
Adabert
推理速度提升29倍,参数少1/10,阿里提出AdaBERT压缩方法
AdaBERT: Task-Adaptive BERT Compression with Differentiable Neural Architecture Search
仅解码器的GPT
GPT
2018年的Improving language understanding by generative pre-training,生成式预训练(Generative pre-training, gpt),用transformer的decoder,参数量117m(0.1b),无监督预训练和有监督微调。
微调阶段为每种下游任务专门设计:
分类:输入一段文本,经过transformer,最后接一个Linear
entailment(蕴含):输入2段文本,premise(假设)和hypothesis(假说),经过transformer,最后接一个Linear
相似度:输入2段文本a和b,a+b过transformer,b+a过transformer,再合起来接一个Linear
多选题:输入context+答案1过transformer+Linear,答案2、答案3同样操作,将3个输出合在一起求softmax
GPT2
2019年的Language models are unsupervised multitask learners模型结构小改,增加数据,参数量变大为15亿(1.5b),无监督语言建模。
layernorm前移到每个sub-block之前
additional layernorm在最后的self-attention block才加上
修改初始化方法,以考虑残差路径上的累积并缩放残差层的权重
15亿参数最强通用NLP模型面世!Open AI GPT-2可信度高于所有小模型
中文GPT2
https://github.com/imcaspar/gpt2-ml
https://colab.research.google.com/github/imcaspar/gpt2-ml/blob/master/pretrained_model_demo.ipynb
huggingface的distill gpt-2:https://github.com/huggingface/transformers
nanogpt代码解读
简化版的gpt, tiktoken:gpt2中使用的开源分词工具,比huggingface的tokenizer快得多
类似的:https://github.com/karpathy/llm.c
https://github.com/karpathy/build-nanogpt/tree/master
fork了一个:https://github.com/daiwk/build-nanogpt
GPT的整体结构:
编码器+解码器
T5
谷歌T5模型刷新GLUE榜单,110亿参数量,17项NLP任务新SOTA
谷歌最新T5模型17项NLP任务霸榜SuperGLUE,110亿参数量!
Exploring the limits of transfer learning with a unified text-to-text transformer
将所有NLP任务都建模成text-to-text的生成任务,
mT5(mt5: A massively multilingual pre-trained text-to-text transformer)是T5的变种,基于新的Common Crawl的数据集(包括101种语言)上预训练
MASS
MASS: Masked Sequence to Sequence Pre-training for Language Generation
bert只使用了Transformer的encoder部分,其下游任务也主要是适用于自然语言理解(NLU),对于类似文本摘要、机器翻译、对话应答生成等自然语言生成(NLG)任务显然是不太合适的。MASS 采用了编码器-解码器框架,并尝试在给定部分句子的情况下修复整个句子。MASS输入句子包含了一些连续的 Token,并且中间会带有一些连续的Mask,模型的任务是预测出被Mask掉的词是什么。相比 BERT 只有编码器,MASS 联合训练编码器与解码器,能获得更适合机器翻译的表征能力。
训练步骤主要分为两步:
Encoder: 输入为被随机mask掉连续部分token的句子,使用Transformer对其进行编码;这样处理的目的是可以使得encoder可以更好地捕获没有被mask掉词语信息用于后续decoder的预测;
Decoder: 输入为与encoder同样的句子,但是mask掉的正好和encoder相反,和翻译一样,使用attention机制去训练,但只预测encoder端被mask掉的词。该操作可以迫使decoder预测的时候更依赖于source端的输入而不是前面预测出的token,防止误差传递。
BART
多项NLP任务新SOTA,Facebook提出预训练模型BART
BART是一个适用于seq2seq模型的去噪自编码器。预训练包括两个阶段:
使用任意噪声函数破坏文本
用seq2seq模型来重建原始文本
LLM概述
PLM(pretrained language models),即bert等
LLM简史
2017年的Learning to generate reviews and discovering sentiment尝试用rnn来实现智能系统
2018年的gpt1:Improving language understanding by generative pre-training,生成式预训练(Generative pre-training, gpt),用transformer的decoder,参数量117m(0.1b),无监督预训练和有监督微调。确定对自然语言文本建模的基本原则为预测下一个单词。
2019年的gpt2:Language models are unsupervised multitask learners模型结构小改,增加数据,参数量变大为15亿(1.5b),无监督语言建模,无需使用标记数据进行显式微调。
提出“由于特定任务的有监督目标与无监督目标(语言建模)相同,只是在序列的子集上进行评估,因此,无监督目标的全局最小值也是有监督目标的全局最小值”,即每个NLP任务可以看作世界文本子集的单词预测问题,如果模型有足够能力来复原世界文本,无监督语言建模可以解决各种问题。
仅无监督与监督微调的SOTA相比效果还是不太行。虽然GPT2模型规模相对较小,但如对话等任务在其基础上做微调还是能拿到很好的效果的,例如DIALOGPT : Large-scale generative pre-training for conversational response generation、End-to-end neural pipeline for goal-oriented dialogue systems using GPT-2
2020年的gpt3:Language models are few-shot learners,175b(1750亿)参数,当参数量到达千亿时出现了『涌现』现象,发现可以in-context learning(这点在3.3亿的BERT和15亿的gpt2中看不到)。预训练和ICL有相同的语言建模范式:预训练预测给定上下文条件下的后续文本序列,ICL预测正确的任务解决方案,其可被格式化为给定任务描述和示范下的文本序列。
GPT-3的两种改进方法:
使用代码数据训练:GPT-3主要问题是缺乏对复杂任务的推理能力,2021年openai提出了Codex(Evaluating Large Language Models Trained on Code),在github代码上微调的GPT。A neural network solves and generates mathematics problems by program synthesis: Calculus, differential equations, linear algebra, and more发现Codex能解决非常困难的编程问题,还能在数学问题上有显著提升。Text and code embeddings by contrastive pre-training提出了训练文本和代码emb的对比学习,在线性探测分类、文本搜索、代码搜索等任务上有所提升。GPT-3.5就是在基于代码的GPT(code-davinci-002)的基础上开发的。
与人类对齐:2017年openai就在learning from human preference的博客中提出了应用强化学习来学习由人类标的偏好比较,此后2021年7月openai发表了PPO。2020年GPT-2用RL进行微调,Deep reinforcement learning from human preferences,Learning to summarize from human feedback也做了相似工作。2022年提出了RLHF的InstructGPT(Training language models to follow instructions with human feedback),其中的SFT就对应于常说的指令微调。在openai的博客Our approach to alignment research中提出了训练AI系统的3个有前途的方向:使用人类反馈、协助人类评估、做对齐研究。
2022年的ChatGPT:用类似InstructGPT的方式进行训练,专门对对话能力进行优化,将人类生成的对话(扮演用户和AI两个角色)与InstructGPT数据集结合起来以对话形式生成。
2023年的GPT-4:将文本输入扩展到多模态信号。此外,
提升安全性:在RLHF训练中加入额外的安全奖励信号,采用多种干预策略如Anthropic提出的Red teaming language models to reduce harms: Methods, scaling behaviors, and lessons learned提到的红队评估(read teaming)机制以减轻幻觉、隐私和过度依赖问题。
改进的优化方法:使用可预测扩展(predictable scaling)的机制,使用模型训练期间的一小部分计算量以预测最终性能。
迭代部署的工程方案:Lessons learned on language model safety and misuse,遵循5阶段的开发和部署生命周期来开发模型和产品。
LLM列表(持续更新中)
百亿:除了LLaMA(最大650亿)和NLLB(最大545亿),大多数在100亿-200亿之间,通常需要数百甚至上千个GPU或TPU。
千亿:OPT、OPT-IML、BLOOM和BLOOMZ与GPT-3(175B)大致相同,GLM有1300亿,Galactica有1200亿,通常需要数千个GPU或者TPU。
ckpt? | 模型 | 发布时间 | 大小 | 预训练数据规模 | 硬件 | 训练时间 |
---|---|---|---|---|---|---|
Y | 2019.10 | 11B | 1万亿tokens | 1024 TPU v3 | - | |
N | 2020.05 | 175B | 3000万亿tokens | - | - | |
N | 2020.06 | 600B | 1万亿tokens | 2048 TPU v3 | 4天 | |
Y | 2020.10 | 13B | 1万亿tokens | - | - | |
Y | 2021.04 | 13B | 1.1TB | 2048 Ascend 910 | - | |
Y | 2021.06 | 198B | 2.6TB | - | - | |
N | 2021.07 | 12B | 1000万亿tokens | - | - | |
N | 2021.07 | 10B | 3750亿tokens | 384 v100 | - | |
N | 2021.08 | 178B | 3000亿tokens | 800 GPU | - | |
N | 2021.09 | 82B | 3000亿tokens | 1024 A100 | 13.4天 | |
N | 2021.09 | 137B | - | 128 TPU v3 | 60小时 | |
N | 2021.10 | 245B | 1800亿tokens | 2128 GPU | - | |
Y | 2021.10 | 11B | - | 512 TPU v3 | 27小时 | |
N | 2021.12 | 52B | 4000亿tokens | - | - | |
N | 2021.12 | 175B | - | - | - | |
N | 2021.12 | 280B | 3000亿tokens | 4096 TPU v3 | 920小时 | |
N | 2021.12 | 260B | - | - | - | |
N | 2021.12 | 1200B | 2800亿tokens | 1024 TPU v4 | 574小时 | |
N | 2022.01 | 137B | 7680亿tokens | 1024 TPU v3 | 57.5天 | |
N | 2022.01 | 530B | 2700亿tokens | 4480 80G A100 | - | |
N | 2022.02 | 41B | 9670亿tokens | - | - | |
N | 2022.03 | 175B | - | - | - | |
N | 2022.03 | 70B | 1.4万亿tokens | - | - | |
Y | 2022.03 | 16B | 5770亿tokens | - | - | |
Y | 2022.04 | 20B | 825GB | 96 40G A100 | - | |
Y | 2022.04 | 11B | - | 256 TPU v3 | 4小时 | |
N | 2022.04 | 540B | 7800亿tokens | 6144 TPU v4 | - | |
Y | 2022.05 | 20B | 825GB | 96 40G A100 | - | |
Y | 2022.05 | 175B | 1800亿tokens | 992 80G A100 | - | |
Y | 2022.07 | 54.5B | - | - | - | |
N | 2022.08 | 20B | 1.3万亿tokens | 128 A100 | 120天 | |
N | 2022.09 | 70B | 64 TPU v3 | - | - | |
N | 2022.09 | 10B | 3000亿tokens | 128 A100 40G | 24天 | |
N | 2022.10 | 540B | - | 512 TPU v4 | 5天 | |
N | 2022.10 | 540B | - | 512 TPU v4 | 37小时 | |
N | 2022.10 | 540B | - | - | - | |
Y | 2022.10 | 130B | 4000亿tokens | 768 40G A100 | 60天 | |
Y | 2022.10 | 11B | - | - | - | |
Y | 2022.11 | 176B | 3660亿tokens | 384 80G A100 | 105天 | |
Y | 2022.11 | 13B | - | - | - | |
Y | 2022.11 | 120B | 1060亿tokens | - | - | |
Y | 2022.11 | 176B | - | - | - | |
Y | 2022.12 | 175B | - | 128 40G A100 | - | |
Y | 2023.02 | 65B | 1.4万亿tokens | 2048 80G A100 | 21天 | |
N | 2023.03 | - | - | - | - | |
Y | 2022.09 | 13B | 8500亿tokens | 1536 Ascend 910 | 60天 | |
N | 2023.03 | 1085B | 3290亿tokens | 512 Ascend 910 | 100天 | |
Y | 2023.04 | 12B | 3000亿tokens | 256 40G A100 | - |
可以直接把对应的md丢给gpt,叫它导出一个excel,然后就可以自定义排序或者画散点图看了
LLM数据集
llm中文数据集:https://juejin.cn/post/7238921093553438779
Books:
BookCorpus:超过11000本电子书,用于GPT和GPT-2。
Gutenberg:超过70000本文学作品,包括小说、散文、诗歌、戏剧、历史、科学、哲学和其他公共领域,用于MT-NLG和LLaMA。
Books1和Books2:比BookCorpus大得多,但未公开,用于GPT-3。
CommonCrawl:最大的开源网络爬虫数据库之一,百万亿字节,有大量噪音和低质信息,需要过滤,有如下4个子集:
C4:包括en(806G,训练T5、LaMDA、Gopher、UL2)、en.noclean(6T)、realnewslike(36G)、webtextlike(17G)、multilingual(38T,训练mT5)。
CC-Stories:31G,内容以故事的形式展示
CC-News:76G
RealNews:120G
Reddit Links:Reddit上的帖子,高赞通常比较有用,可以拿来创建高质量数据集。
WebText:由Reddit上的高赞链接组成,未公开,对应的开源版是OpenWebText。
Pushshift.io:实时更新的数据集,包括Reddit自创建以来的历史数据,有数据存储,也有实用工具,供用户搜索、总结和统计分析。
Wikipedia:大部分文章使用写作风格,并支持引用,英语版本用于大多数LLM,如GPT-3、LaMDA、LLaMA,还有多语言版。
Code:包括开源许可证的公共代码库(如github)和与代码相关的问答平台(如StackOverflow),Google公开了BigQuery数据集,CodeGen用的BIGQUERY是其的一个子集。
LLM开源库
transformers:huggingface的库
deepspeed:微软的库,与pytorch兼容,训练了MT-NLG、BLOOM等模型,包括各种分布式训练优化技术,如内存优化(ZeRO、梯度检查点等)和管道并行。
megatron-lm:英伟达的库,同样包括各种分布式训练技术,包括模型和数据并行、混合精度训练和FlashAttention。(Megatron-lm: Training multi-billion parameter language models using model parallelism、Efficient large-scale language model training on GPU clusters using megatron-lm和Reducing activation recomputation in large transformer models)
jax:google的库,允许用户在带有硬件加速(GPU或TPU)的情况下进行数组的高效运算,可以在各种设备高效计算,支持自动微分和即时编译等功能。
colossal-AI:HPC-AI Tech的库,基于pytorch,可以使用[PatrickStar](Patrickstar: Parallel training of pre-trained models via a chunk-based memory management)提出的方法优化异构内存管理,分布了基于LLaMA的ColossalChat
BMTrain:openBMB的库,强调代码简洁、低资源占用和高可用性
[FastMoE](Fastmoe: A fast mixture-of-expert training system):专门用于MoE模型的训练库,基于pytorch,简化了将transformer转换为MoE模型的过程
semantic-kernel:微软的开源库
一些开源的小模型:从零训练的 1B 以下小模型汇总
一些综述
人大的大模型综述:https://github.com/RUCAIBox/LLMSurvey,自己存了一份pdf,(!!!本文大部分内容按这个来组织!!!)
扩展法则(scaling law)
openai的扩展法则
2020年,openai的Scaling laws for neural language models通过拟合模型在不同数据大小(2000w到230亿个token)、不同的模型大小(7.68亿到15亿个非嵌入参数)的性能,提出了在计算预算的条件下,是用nats表示的交叉熵损失,模型性能与模型规模、数据集规模以及训练计算量间存在如下幂律关系: