本文导论部署 LLaMa 系列模型常用的几种方案,并作速度测试。包括 Huggingface 自带的 LLM.int8(),AutoGPTQ, GPTQ-for-LLaMa, exllama, llama.cpp。
总结来看,对 7B 级别的 LLaMa 系列模型,经过 GPTQ 量化后,在 4090 上可以达到 140+ tokens/s 的推理速度。在 3070 上可以达到 40 tokens/s 的推理速度。
LM.int8()
来自论文:LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale
https://arxiv.org/pdf/2208.07339.pdf
LM.int8() 时 Hugingface 集成的量化策略(https://huggingface.co/docs/transformers/main_classes/quantization)。能够通过在 .from_pretrain()
时候传递 load_in_8bit
来实现,针对几乎所有的 HF Transformers 模型都有效。大致方法是,在矩阵点积计算过程中, 将其中的 outliers 参数找出来(以行或列为单位),然后用类似 absolute maximum (absmax) quantization 的方法,根据行/列对 Regular 参数做量化处理,outlier 参数仍然做 fp16 计算,最后相加。根据 huggingface 的博客 (https://huggingface.co/blog/hf-bitsandbytes-integration), LLM.INT8() 能够再模型性能不影响很多的前提下,让我们能用更少的资源进行 LLM 推理。但 LLM.int8() 普遍的推理速度会比 fp16 慢。博客中指出,对于越小的模型, int8() 会导致更慢的速度。
结合论文中的实验结果,模型越大,int8() 加速越明显,个人猜测是由于非 outlier 数量变多了,更多的参数进行了 int8 计算,抵消了额外的量化转化时间开销?GPTQ
GPTQ: ACCURATE POST-TRAINING QUANTIZATION FOR GENERATIVE PRE-TRAINED TRANSFORMERS
使用 GPTQ 量化的模型具有很大的速度优势,与 LLM.int8() 不同,GPTQ 要求对模型进行 post-training quantization,来得到量化权重。GPTQ 主要参考了 Optimal Brain Quanization (OBQ),对OBQ 方法进行了提速改进。有网友在 文章 中对 GPTQ, OBQ, OBS 等量化策略进行了整理,这里就不多赘述了。
以下对几个 GPTQ 仓库进行介绍。以下所有测试均在 4090 上进行,模型推理速度采用 oobabooga/text-generation-webui (https://github.com/oobabooga/text-generation-webui) 提供的 UI。
GPTQ-for-LLaMa
专门针对 LLaMa 提供 GPTQ 量化方案的仓库,如果考虑 GPU 部署 LLaMa 模型的话,GPTQ-for-LLaMa 是十分指的参考的一个工具。像 http://huggingface.co 上的 Thebloke 很大部分模型都是采用 GPTQ-for-LLaMa 进行量化的。
Post Training Quantization:GPTQ-for-LLaMa 默认采用 C4 (https://huggingface.co/datasets/allenai/c4) 数据集进行量化训练(只采用了 C4 中英文数据的一部分进行量化,而非全部 9TB+的数据):
CUDA_VISIBLE_D