1. 文章简介
这篇文章是今年1月份清华和智谱联合发表的一篇工作,目的在于说优化LLM的推理速度。
众所周知,LLM最近这两年疯狂出圈,其出色的效果基本已经有目共睹,但是隐藏在台面下的一直有一个大问题就是模型的尺寸和推理速度,LLM虽然效果好,但是架不住模型尺寸实在是太大了,而且decoder走的一直是token by token的迭代生成,这就导致模型部署的开销极大且生成速度一直堪忧。
因此,文中提出了一种名为APAR(auto-parallel auto-regressive)的并行算法,在不损伤模型生成质量的情况下提升模型的生成效率,获得了较好的效果表达。
下面,我们就来看一下这一方法的具体设计和文中给出的实验考察。
2. 方法介绍
1. 整体思路 & 框架
APAR方法的核心思路其实就是增加并行。
而具体增加并行的方法的话则是想办法将相似内容的生成并行化,典型的例子就是如果需要输出多个并列观点,那就将他们并行进行输出,如果能做到这点,那么自然而然就能够提升生成效率了。
文中给出样例说明如下:
然后的话,我们就需要考察一下要实现上述功能的话,需要如何对模型进行改造和生成。
2. 模型训练
要完成上述功能实现,文中主要是需要将数据按照树状结构进行拆分,然后重新构造并行数据进行模型的finetune,整体的结构框架如下:
其核心就在于将原文中并列的点拆分为多个点进行生成,并用特殊标识符进行区分,此时文中原始的文本就被拆分为了3条训练数据:
-
p
0
p_0
p0
[FORK]
[CHILD]
p 1 p_1 p1 -
p
0
p_0
p0
[FORK]
p 2 p_2 p2[FORK]
[CHILD]
p 3 p_3 p3 -
p
0
p_0
p0
[FORK]
p 2 p_2 p2[FORK]
p 4 p_4 p4
由此,在实际生成过程中,模型每次看到标志符[FORK]
,就进入了一个并行分支,同时进行下文并行内容和当前内容的同步生成。
同时,由于特殊字符[FORK]
事实上替换了整段的内容文本,因此在attention方面事实上也进行了优化,严重减少了计算的开销。
3. Decoding
同样的,根据上述原理,我们很容易就能够得到decoding的具体过程,具体可以用文中的下图进行说明:
文中同样给出了对应的伪代码如下:
有点长,不过大致上就是完成了上述部分所说的内容细节了。
4. 方法分析
最后的话,文中整理了一下上述APAR方法能够带来的主要的优点。
这部分其实在上述APAR的模型训练部分事实上已经提过一嘴了,这里稍微对其进行一下整理,主要就是以下三点内容:
- 通过并行的方式优化生成的速度;
- 通过标识符替换的方式减少attention所需的内存占用
- 通过标识符替换的方式减少attention所需的计算量
3. 实验考察 & 结论
下面,我们来看一下文中对于APAR的具体实验考察。
1. 数据处理
首先,我们来看一下APAR所需的模型预训练所需的具体数据的处理。
如前所述,远离而言,我们事实上就是要将原文进行拆分,将多个并行内容进行拆分,拆分为多条数据。
因此,这里有一个核心问题就是要如何对数据进行并行拆分,显然这要求这些内容相互独立才行,文中给出了三种处理方式:
- Ordered List
- 有序列关系的内容可以进行拆分
- Paragraph
- 对于一些概括类的段落可以进行拆分
- Unstructured data
- 对于其他文本,我们往往无法继续并行拆分,此时我们需要保留一些这类文本,确保模型不至于过拟合到全部输出并行文本。
而关于这部分内容的具体构造方式,文中附录B给出了具体的实现,基本就是通过正则规则进行处理的,有兴趣的读者可以自行看一下文中给出的构造方法,没啥兴趣的同学后续蹲一下他们的开源代码即可,文中作者宣称后续是会放出开源代码的。
2. 实验设置
然后,我们来看一下文中的实验设置,主要就是文中实验所用的模型,方法的实现以及测试使用的数据集。
具体来说,模型方面使用的是vicuna-v1.3的7B和13B两个模型。
实现方面除了vanilla transfromer之外,文中还使用了Medusa以及Batched-APAR两种方法。
最后,在测试数据集上,文中使用的包括:
- Vicuna Bench
- MT Bench
- APAR Test Set
3. 实验结果
下面,我们来看一下文中得到的具体实验结果。
1. 速度考察
首先,最直接的,在同样的内存限制条件下,考察模型的生成速度,得到结果如下:
可以看到:
- 在两个模型和各类任务当中,APAR都能带来显著的生成效率上的提升。
2. serving效果分析
然后,文中模拟了一下实际的服务部署情况,考察了一下不同内存使用率情况下各个模型的吞吐量以及压测情况下不同的请求量带来的延时情况的变化,得到结果如下:
可以看到:
- 上述结果是与上一小节当中的结论相一致的,APAR显然可以serving更大量的请求。
另外,文中还考察了一下实际生成过程中APAR对于attention当中token数目的影响,前面提到过,这部分会影响模型对于GPU内存的占用程度以及总的计算量。
文中得到实验结果如下:
可以看到:
- 确实生成中使用的总的token数减少了,使得在内存使用和计算量上面都能够获得优化。
3. 生成质量考察
最后,文中还考察了一下模型的生成质量,毕竟提升速度的前提是不损伤模型的生成效果。
对此,文中得到的结果如下:
可以看到:
- 模型效果略有下滑,但整体而言是可以忽略的程度。
4. 总结 & 思考
综上,文中提出了一个APAR的方法,通过将生成过程并发化的方式显著提升了模型的infer效率,不但节省内存且可以提升生成的速度,非常的有现实意义。
不过,APAR实际是通过重新finetune模型实现的,因此不能直接使用到现有的LLM上面,只能在开源模型的基础上面进行finetune然后重新发布,这在一定程度上限制了APAR的使用,至少像我们这样的小工程团队够呛可以用起来……
所以,后面看下吧,真心感觉是很好的工作啊,唉……