快站建站教程,自建站,合肥网站,江苏通力建设官方网站context阶段和generation阶段的不同
context阶段#xff08;又称 Encoder#xff09;主要对输入编码#xff0c;产生 CacheKV(CacheKV 实际上记录的是 Transformer 中 Attention 模块中 Key 和 Value 的值#xff09;#xff0c;在计算完 logits 之后会接一个Sampling 采…context阶段和generation阶段的不同
context阶段又称 Encoder主要对输入编码产生 CacheKV(CacheKV 实际上记录的是 Transformer 中 Attention 模块中 Key 和 Value 的值在计算完 logits 之后会接一个Sampling 采样模块采样出来第一个生成的 token并将这个 token 和 CacheKV 作为 generation阶段的输入
generation阶段又称 Decoder在一个 While 循环里读取 token 和 CacheKV 后通过自回归解码的方式每循环一次产生一个 token。generation阶段自己的输出作为自己的输入不断回归迭代就是「自回归」。在 While 处判断需要继续生成在 Attention 中计算出token对应的 CacheKV 信息存储下来并拼接上所有的历史 CacheKV 信息进行计算最后采样出来下一个 token。While 循环检测到「eos」生成结束就会退出循环本次生成推理过程结束。
在 DecoderSelfAttention 中查询的序列长度始终为 1因此使用自定义的 fused masked multi-head attention kernel 来处理。 另一方面ContextSelfAttention 中查询的序列长度是最大输入长度因此我们使用 cuBLAS 来利用tensor core。 context阶段sequence length等于input_length(并行可以类比训练的前向过程causal attention)generation阶段sequence length等于1一个token一个token循环进行decoder。 以 175B 的 GPT-3 模型输入 1000 个 token生成 250 个 token 为例那么 Context 阶段的激活 Shape 为 [B, 1000, 12288]其中 B 为 batch_size第二维为输入 token 数第三位为 hidden size。而对于 Generation 阶段由于每次输入输出都是固定的 1 个 token是通过循环多次来产生多个输出 token所以 Generation 阶段的激活 Shape [B, 1, 12288]的第二维始终为 1Generation 的激活显存占用是远小于 Context 阶段的。 再来看计算量这里可以看到挺多有趣的结论
---Context/Generation 的计算量均随 batch size 增大而正比增大这个很好理解因为 batch 内每个样本的计算量是一致的
---Context/Generation 的访存量随 batch size 增大却基本不变访存量可以分为权重访存和激活访存很显然激活的访存是随 batch size 增大而增大的但是权重访存却不会随 batch size 变化而变化而由于激活的访存量远小于权重的访存量就会出现总访存量几乎不随 batch size 变化而变化
Context 是计算密集型的任务compute bound而 Generation 是访存密集型的任务IO bound显存带宽指的是 GPU 计算单元与显存之间的数据传输速度。这是由于 Context 的计算量大 Generation 由于每次都只计算 1 个 token所以计算量远小于 Context但是两个阶段权重的访存量确实一致的因为Generation 要循环调用所以 Generation 阶段反而是访存密集型的任务。
量化的优缺点
量化通过使用较少的比特数来表示模型参数从而减小模型的内存占用。此外由于整数乘法要快于浮点数乘法量化通常可以提高推理速度。然而量化运算的一个缺点是会引入误差随着模型参数量的增加误差累积会变得更加明显。