sift计算效率优化_Transformer家族3 -- 计算效率优化(Adaptive-Span、Reformer)

2023-10-28 15:30

本文主要是介绍sift计算效率优化_Transformer家族3 -- 计算效率优化(Adaptive-Span、Reformer),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

5ccd4ddcb9312044dee1b2d95f1726b3.png

Transformer家族3 -- 计算效率优化(Adaptive-Span、Reformer、Lite-Transformer)

1 背景

上文我们从编码长度优化的角度,分析了如何对Transformer进行优化。Transformer-XL、LongFormer等模型,通过片段递归和attention稀疏化等方法,将长文本编码能力提升到了很高的高度。基本已经克服了Transformer长文本捕获能力偏弱的问题,使得下游任务模型performance得到了较大提升,特别是文本较长(大于512)的任务上。

但Transformer计算量和内存消耗过大的问题,还亟待解决。事实上,Transformer-XL、LongFormer已经大大降低了内存和算力消耗。毕竟Transformer之所以长距离编码能力偏弱,就是因为其计算量是序列长度的平方关系,对算力需求过大,导致当前GPU/TPU不能满足需求。编码长度优化和计算量优化,二者是相辅相成的。但着眼于论文的出发点,我们还是分为两个不同的章节进行分析。毕竟总不能所有模型都放在一个章节吧(_)。

本文我们带来Adaptive-Span Transformer、Reformer、Lite-Transformer等几篇文章

2 Adaptive-Span Transformer

581efc5530d53f4d1763a57089dbc011.png

论文信息:2019年5月,FaceBook,ACL2019

论文地址

https://arxiv.org/pdf/1905.07799.pdf​arxiv.org

代码和模型地址

https://github.com/facebookresearch/adaptive-span​github.com

2.1 为什么需要Adaptive-Span

之前Transformer-XL将长文本编码能力提升到了较高高度,但是否每个layer的每个head,都需要这么长的attention呢?尽管使用了多种优化手段,长距离attention毕竟还是需要较大的内存和算力。研究发现,大部分head只需要50左右的attention长度,只有少部分head需要较长的attention。这个是make sense的,大部分token只和它附近的token有关联。如下图

e75d31da65c889a75ad1f1095d2d626f.png

我们是否可以实现attention span长度的自适应呢?让不同的layer的不同的head,自己去学习自己的attention span长度呢?Adaptive-Span Transformer给出了肯定答案。

2.2 实现方案

文章设定每个attention head内的token计算,都使用同一个span长度。我们就可以利用attention mask来实现自适应span。对每个head都添加一个attention mask,mask为0的位置不进行attention计算。文章设计的mask函数如下

48330a75c118d0c1ee716e0c86f8271d.png

R为超参,控制曲线平滑度。其为单调递减函数,如下图。

765307676f563beb7fcc659930db96e5.png

2.3 实验结果

507370a51ca6567513a3b5e7d669e45c.png

和Transformer家族其他很多模型一样,Adaptive-span也在字符级别的语言模型上进行了验证,数据集为text8。如上,Transformer注意力长度固定为512,结论如下

  1. Transformer-XL长程编码能力确实很强,平均span可达3800。
  2. 注意力长度确实不需要总那么长,Adaptive-Span大模型上,平均长度只有245
  3. Adaptive-Span在算力需求很小(只有XL的1/3)的情况下,效果可以达到SOTA。

5523afe0ed83c7d560e326b255ec8edb.png

上面是在enwik8上的结果。Adaptive-Span又一次在算力很小的情况下,达到了最优效果。值得注意的是,64层的Transformer居然需要120G的计算量,又一次证明了原版Transformer是多么的吃计算资源。另外Transformer-XL在节省计算资源上,其实也算可圈可点。

3 Reformer

2e6afedcfad4460f54fb2f8668467c6c.png

论文信息:2020年1月,谷歌,ICLR2020

论文地址

Reformer: The Efficient Transformer​arxiv.org

代码和模型地址

google/trax​github.com
8c6be342592207f0ed26fe398b97da7f.png

3.1 为什么需要Reformer

Transformer内存和计算量消耗大的问题,一直以来广为诟病,并导致其一直不能在长文本上进行应用。(BERT、RoBERTa均设置最大长度为512)。Reformer认为Transformer有三大问题

  1. attention层计算量和序列长度为平方关系,导致无法进行长距离编码
  2. 内存占用和模型层数呈N倍关系,导致加深Transformer层数,消耗的内存特别大
  3. feed-forward的dff比隐层dmodel一般大很多,导致FF层占用的内存特别大

针对这几个问题,Reformer创新性的提出了三点改进方案

  1. LOCALITY-SENSITIVE HASHING 局部敏感hash,使得计算量从 O(L^2)降低为O(L log L) ,L为序列长度
  2. Reversible Transformer 可逆Transformer,使得N层layers内存消耗变为只需要一层,从而使得模型加深不会受内存限制。
  3. Feed-forward Chunking 分块全连接,大大降低了feed-forward层的内存消耗。

Reformer是Transformer家族中最为关键的几个模型之一(去掉之一貌似都可以,顶多Transformer-XL不答应),其创新新也特别新颖,很多思想值得我们深入思考和借鉴。其效果也是特别明显,大大提高了内存和计算资源效率,编码长度可达64k。下面针对它的三点改进方案进行分析,有点难懂哦。

3.2 实现方案

3.2.1 LOCALITY-SENSITIVE HASHING 局部敏感hash

局部敏感hash有点难懂,Reformer针对Transformer结构进行了深度灵魂拷问

Query和Key必须用两套吗

Transformer主体结构为attention,原版attention计算方法如下

9cf101b42e462ce186c918e9621f4ea0.png

每个token,利用其query向量,和其他token的key向量进行点乘,从而代表两个token之间的相关性。归一化后,利用得到的相关性权重,对每个token的value向量进行加权求和。首先一个问题就是,query和key向量可以是同一套吗?我们可否利用key向量去和其他token的key计算相关性呢? 为此文章进行实验分析,证明是可行的。个人认为这一点也是make sense的。

13fc3264df97908d149cac7436210606.png

在文本和图像上,Q=K的attention,和普通attention,效果差别不大。

必须和每个token计算相关性吗

原版attention中,一个token必须和序列中其他所有token计算相关性,导致计算量随序列长度呈平方关系增长,大大制约了可编码最大长度。那必须和每个token计算相关性吗?其实之前Adaptive-Span Transformer也深度拷问过这个话题。它得出的结论是,对于大部分layer的multi-head,长度50范围内进行attention就已经足够了。不过Adaptive-Span采取的方法还是简单粗暴了一点,它约定每个head的attention span长度是固定的,并且attention span为当前token附近的其他token。 Adaptive-Span Transformer的这种方法显然还是没有抓住Attention计算冗余的痛点。Attention本质是加权求和,权重为两个token间的相关性。最终结果取决于较大的topk权重,其他权值较小的基本就是炮灰。并且softmax归一化更是加剧了这一点。小者更小,大者更大。为了减少计算冗余,我们可以只对相关性大的其他token的key向量计算Attention。

怎么找到相关性大的向量呢

我们现在要从序列中找到与本token相关性最大的token,也就是当前key向量与哪些key向量相关性大。极端例子,如果两个向量完全相同,他们的相关性是最高的。确定两个高维向量的相关性确实比较困难,好在我们可以利用向量Hash来计算。 Reformer采用了局部敏感hash。我们让两个key向量在随机向量上投影,将它们划分到投影区间内。

a998db804123f007cb913299ec68a104.png

如图所示,划分了四个区间(4个桶bucket),进行了三次Hash。第一次Hash,使得上面两个向量分别归入bucket0和bucket3中,下面两个向量都归入bucket0。第二次Hash,上面两个向量和下面两个,均归入到bucket2中了。我们可以发现

  1. 相似的向量,也就是相关性大的,容易归入到一个bucket中
  2. 局部敏感Hash还是有一定的错误率的,我们可以利用多轮Hash来缓解。这也是Reformer的做法,它采取了4轮和8轮的Hash。

整个流程

经过局部敏感Hash后,我们可以将相关性大的key归入同一个bucket中。这样只用在bucket内进行普通Attention即可,大大降低了计算冗余度。为了实现并行计算,考虑到每个bucket包含的向量数目可能不同,实际处理中需要多看一个bucket。整个流程如下

d2d0dc43d55ab8cc04d777d6e3385355.png
  1. 让query等于key
  2. 局部敏感Hash(LSH)分桶。上图同一颜色的为同一个桶,共4个桶
  3. 桶排序,将相同的桶放在一起
  4. 为了实现并行计算,将所有桶分块(chunk),每个chunk大小相同
  5. 桶内计算Attention,由于之前做了分块操作,所以需要多看一个块。

多轮LSH

为了减少分桶错误率,文章采用了多次分桶,计算LSH Attention,Multi-round LSH attention。可以提升整体准确率。如下表。

d4a5a0216f2c627ac73ada27ee9bb548.png

3.2.2 REVERSIBLE TRANSFORMER 可逆Transformer

LSH局部敏感Hash确实比较难理解,可逆Transformer相对好懂一些。这个方案是为了解决Transformer内存占用量,随layers层数线性增长的问题。为什么会线性增长呢?原因是反向传播中,梯度会从top layer向bottom layer传播,所以必须保存住每一层的Q K V向量,也就导致N层就需要N套Q K V。 那有没有办法不保存每一层的Q K V呢?可逆Transformer正是这个思路。它利用时间换空间的思想,只保留一层的向量,反向传播时,实时计算出之前层的向量。所以叫做Reversible。Reformer每一层分为两部分,x1和x2。输出也两部分,y1和y2。计算如下

8ae8374291e6c5ae662377fbea32cd47.png

由y1和y2,可以反向计算出x1和x2,

9f6be599f73ff5f75564b9671fc45957.png

实操中,F为Attention,G为FeedForward,如下

98dcb58ed6a68d9d415e97b948ab3383.png

采用可逆残差连接后,模型效果基本没有下降。这也是make sense的,毕竟可逆是从计算角度来解决问题的,对模型本身没有改变。

a5c830e06b4eb1b325cfdfb08d23a02f.png

3.2.3 Feed-Forward chunking FF层分块

针对fead-forward层内存消耗过大的问题,Reformer也给出了解决方案,就是FF层分块。如下

5b71998e62c7ea65a527399ef41b1215.png

3.3 实验结果

内存和时间复杂度

Reformer三个创新点,大大降低了内存和时间复杂度,消融分析如下

fba6c16e981584c446abe71ccbfba60c.png

模型效果

如下为在机器翻译上的效果。Reformer减少了算力消耗,同时也大大增加了长文本编码能力,故模型效果也得到了提升。如下。

7920cf3fddba54dd2f213e005d2f26f5.png

4 Lite Transformer

55276fa7eabd01e1263724f4aa1422d9.png

论文信息:2020年4月,MIT & 上海交大,ICLR2020

论文地址

https://arxiv.org/abs/2004.11886​arxiv.org

代码和模型地址

https://github.com/mit-han-lab/lite-transformer​github.com

4.1 为什么要做Lite Transformer

主要出发点仍然是Transformer计算量太大,计算冗余过多的问题。跟Adaptive-Span Transformer和Reformer想法一样,Lite Transformer也觉得没必要做Full Attention,很多Attention连接是冗余的。不一样的是,它通过压缩Attention通道的方式实现,将多头减少了一半。与Base Transformer相比,计算量减少了2.5倍。并且文章使用了量化和剪枝技术,使得模型体积减小了18.2倍。

4.2 实现方案

实现方案很简单,仍然采用了原版Transformer的seq2seq结构,创新点为

  1. multiHead self-attention变为了两路并行,分别为一半的通道数(多头)。如下图a所示。其中左半部分为正常的fully attention,它用来捕获全局信息。右半部分为CNN卷积,用来捕获布局信息。最终二者通过FFN层融合。这个架构称为LONG-SHORT RANGE ATTENTION (LSRA),长短期Attention。
  2. 为了进一步降低计算量,作者将CNN转变为了一个depth wise卷积和一个线性全连接。dw卷积在mobileNet中有讲过,不清楚可自行谷歌。

46503f95e9f18fb788d213e36f1c9d2a.png

4.3 实验结果

计算复杂度

5b92b0d3c13d66ff5e27acbf1737b875.png

如上图,在文本摘要任务上,Lite Transformer计算量相比Base Transformer,减少了2.5倍。同时Rouge指标基本没变。

模型体积

ee19508b987acba4d4c2637d0906752d.png

Lite Transformer模型体积只有Transformer的2.5分之一,通过8bit量化和剪枝,最终模型体积下降了18.2倍。

5 其他

其他几篇文章,也建议拜读下

  1. Generating Long Sequences with Sparse Transformers (OpenAI, 2019.04)
  2. Adaptively Sparse Transformers (EMNLP2019, 2019.09)
  3. Compressive Transformers for Long-Range Sequence Modelling (2019.11)
  4. Transformer on a Diet (2020.02)

系列文章,请多关注

谢杨易:Transformer家族1 -- Transformer详解和源码分析​zhuanlan.zhihu.com
73a5b70a752efdcfd0b21ea142063ab3.png
谢杨易:Transformer家族2 -- 编码长度优化Transformer-XL、Longformer​zhuanlan.zhihu.com
7f57a6c7310e0b3be13d4e8709133f46.png
谢杨易:Transformer家族3 -- 计算效率优化(Adaptive-Span、Reformer)​zhuanlan.zhihu.com
fd5c26d2dbbaebdf2ea898abff1b36d4.png
谢杨易:Transformer家族4 -- 通用性优化(Universal-Transformer)​zhuanlan.zhihu.com
7bf48aa3793800b9124e59a828f60ee2.png
谢杨易:Transformer家族5 -- 推理加速(Faster-Transformer、Turbo)​zhuanlan.zhihu.com
918c6fc6c38e6debb11a73c9e25fd015.png
谢杨易:NLP预训练模型1 -- 综述​zhuanlan.zhihu.com
ff5c107f302ebf27d0642f15f63f2578.png

这篇关于sift计算效率优化_Transformer家族3 -- 计算效率优化(Adaptive-Span、Reformer)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/294154

相关文章

MySQL中like模糊查询的优化方案

《MySQL中like模糊查询的优化方案》在MySQL中,like模糊查询是一种常用的查询方式,但在某些情况下可能会导致性能问题,本文将介绍八种优化MySQL中like模糊查询的方法,需要的朋友可以参... 目录1. 避免以通配符开头的查询2. 使用全文索引(Full-text Index)3. 使用前缀索

C#实现高性能Excel百万数据导出优化实战指南

《C#实现高性能Excel百万数据导出优化实战指南》在日常工作中,Excel数据导出是一个常见的需求,然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈,下面我们看看C#如何结合EPPl... 目录一、技术方案核心对比二、各方案选型建议三、性能对比数据四、核心代码实现1. MiniExcel

windows和Linux使用命令行计算文件的MD5值

《windows和Linux使用命令行计算文件的MD5值》在Windows和Linux系统中,您可以使用命令行(终端或命令提示符)来计算文件的MD5值,文章介绍了在Windows和Linux/macO... 目录在Windows上:在linux或MACOS上:总结在Windows上:可以使用certuti

MySQL索引的优化之LIKE模糊查询功能实现

《MySQL索引的优化之LIKE模糊查询功能实现》:本文主要介绍MySQL索引的优化之LIKE模糊查询功能实现,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前缀匹配优化二、后缀匹配优化三、中间匹配优化四、覆盖索引优化五、减少查询范围六、避免通配符开头七、使用外部搜索引擎八、分

Python Transformer 库安装配置及使用方法

《PythonTransformer库安装配置及使用方法》HuggingFaceTransformers是自然语言处理(NLP)领域最流行的开源库之一,支持基于Transformer架构的预训练模... 目录python 中的 Transformer 库及使用方法一、库的概述二、安装与配置三、基础使用:Pi

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S