编者按:跟着大言语模型在自然言语处理中的广泛运用,怎么进步其在实践布置中的推理速度成为一个十分要害的问题。
本文具体介绍了当前提巨大言语模型推理速度的七大策略,包含运用低精度核算、模型量化、运用适配器微调、选用模型剪枝、批量推理、多 GPU 并行和选用其他推理优化东西等办法。这些办法各有利弊,作者通过具体的实例说明它们的运用作用,让读者比较清晰地了解当前这一范畴的技能发展状况。
本文内容丰富全面,对那些想要将大言语模型运用到实践产品中的工程师有很强的参考价值。读者能够通过本文找出适合自己场景的推理优化策略,也能够进一步深化了解这一范畴的最新进展。引荐对落地大言语模型运用感兴趣的读者阅览本文。
以下是译文,Enjoy!
作者| Sergei Savvov
编译 | 岳扬
Image generated with Stable Diffusion
各类公司,不论是小型创业公司仍是大型企业,都期望好好运用现代化的大言语模型,并将其融入到公司的产品和根底软件中。但是,这些公司一般都将遇到一个应战:这些大模型在布置(推理)时需求消耗很多的算力资源。
加快模型推理速度已经成为开发者们所面对的一项重要应战,这项应战涉及到怎么下降核算资源的费用以及怎么进步运用的响应速度。
“未来,大言语模型的推理速度每进步1%都将比拟谷歌搜索引擎推理速度进步1%的经济价值。”
—— NVIDIA资深AI科学家Jim Fan
LLM(大言语模型)的开发和相关根底软件正在以惊人的速度[1]不断演进。每周都会呈现模型紧缩或加快的新办法。在如此迅猛的技能发展状况下,要跟上潮流并了解哪些技能是真正有用的,而不仅仅停留在理论的层面,确实是一项应战。
我尝试去了解现在有哪些改进办法能够在具体项目中施行以及这些办法对LLM模型推理速度的加快作用。这样能够让我更好地掌握当前的技能动态,并为具体项目挑选最合适的优化计划。
01 “Short” Summary
各种大模型的推理时刻和内存消耗比较,A100 GPU 40GB
这篇文章有些长,以下是主要内容要点:
1.下降精度: 运用float16或bfloat16。这将使模型加快约20%,内存消耗减少2倍。
2.运用8位或4位量化: 运用8位或4位的模型量化办法能够将内存消耗减少2倍或3倍。这种办法对需求运转于内存受限的小型设备上的模型作用最好。需留意:量化会下降模型猜测的质量。
3.运用adapters(LoRA [2] 、QLoRA [3] )进行微调, 能够进步模型在特定数据上的猜测准确性和功用。与模型量化技能结合运用作用杰出。
4.运用张量并行技能(tensor parallelism) 能够加快大模型在多GPU上的推理。
5.假如或许,尽或许运用LLM推理和服务库,如Text Generation Inference、DeepSpeed[4]或vLLM[5]。这些库已经包含了各种优化技能:张量并行(tensor parallelism)、模型量化(quantization)、对接连到达的恳求进行批处理操作(continuous batching of incoming requests)、通过优化的CUDA核函数(optimized CUDA kernels)等等。
6.在将大模型投入生产环境之前进行一些初步测验。 我在运用某些库时花了很多时刻去修正Bugs。此外,并非一切LLM都有可行的推理加快解决计划。
7.不要忘掉评价终究的解决计划。 最好预备好数据集进行快速测验。
下面咱们将开始具体评论这些要点。
02 本文试验中的模型挑选
文本中提到的相关测验,我挑选了Falcon[6],这是由Technology Innovation Institute[7]发布的一款最新的开源大言语模型。它是一个仅具备解码器功用的自回归模型,拥有两个版本:一个是70亿参数的模型,另一个是400亿参数的模型。400B模型变体通过了在AWS上运用384个GPU进行为期两个月的练习。
Open LLM Leaderboard.
依据对该模型的了解[8],Falcon的架构与GPT-3和LLaMA十分相似,仅有的差异在于它运用了multiquery attention(Shazeer 2019[9])和挑选了RefinedWeb[10]语料库作为练习数据集(这或许是该模型获得成功的要害所在[11])。
Multiquery attention通过在不同的留意力头(attention heads)之间同享相同的键张量和值张量(key and value tensors)来进步效率,下面是多头留意力模块(multihead attention block)的示意图:
Multiquery attention. lightning.ai/pages/commu…
03 未优化的基准试验 Vanilla Usage
为了完结试验,我运用了 Lit-GPT 库[12]进行操作,其间包含了对最新开源 LLM 的可装备完结,并由 Lightning Fabric[13]供给支撑。至于硬件装备,我运用了一块显存容量为40GB的A100 GPU。
下面开始试验,第一步是下载模型权重并将其转换为lit-gpt格局。直接履行以下脚本即可,这一进程十分简单:
python scripts/download.py --repo_id tiiuae/falcon-7b
python scripts/convert_hf_checkpoint.py --checkpoint_dir checkpoints/tiiuae/falcon-7b
要履行模型,只需运转以下程序即可:
python generate/base.py \
--prompt "I am so fast that I can" \
--checkpoint_dir checkpoints/tiiuae/falcon-7b \
--max_new_tokens 50 \
--precision "32-true"
# Time for inference: 1.47 sec total, 33.92 tokens/sec
# Memory used: 28.95 GB
04 LLM 推理加快办法
3.1 运用 16 位精度
在运用GPU练习深度神经网络时,一般咱们会运用低于最高精度的32位浮点运算(实践上,PyTorch就是默认运用32位浮点数)。在浮点表明法中,数值由三个组成部分构成:符号(the sign)、指数(the exponent)和有用数字(the significand)(或称为尾数 mantissa)。
单精度浮点运算格局[14]
一般来说,位数越多,精度越高,然后下降了核算进程中过错累积的几率。 但是,假如咱们想要加快模型的练习速度,能够将精度下降到例如16位。这样做有以下几个好处:
1.减少显存占用:32 位精度所需的 GPU 显存是 16 位精度的两倍,而下降精度则能够更有用地运用GPU显存资源。
2.进步核算才能和核算速度:因为低精度张量(lower precision tensors)的操作所需的显存更少,因而GPU能够更快地进行核算处理,然后进步模型的练习速度。
Lit-GPT 运用 Fabric 库,只需几行代码就能改变精度。
python generate/base.py \
--prompt "I am so fast that I can" \
--checkpoint_dir checkpoints/tiiuae/falcon-7b \
--max_new_tokens 50 \
--precision "16-true"
# Time for inference: 1.19 sec total, 42.03 tokens/sec
# Memory used: 14.50 GB
3.2 混合精度练习 Mixed-precision training
混合精度练习(Mixed-precision training)是一项比较重要的技能,能够较大地进步在GPU上的练习速度。这种办法并不会将一切参数和操作都转换为16位浮点数,而是在练习进程中在32位和16位之间切换操作,因而被称为“混合“精度。
混合精度办法[15]
这种办法能够在保持神经网络的准确性和稳定性的一起,进行高效练习。
python generate/base.py \
--prompt "I am so fast that I can" \
--checkpoint_dir checkpoints/tiiuae/falcon-7b \
--max_new_tokens 50 \
--precision "16-mixed"
# Time for inference 1: 2.82 sec total, 17.70 tokens/sec
# Memory used: 42.84 GB
3.3 16位脑浮点(Brain Floating Point)
Bfloat16是由Google提出的一种浮点数格局,称号代表着“Brain Floating Point Format(脑浮点格局)”,其源自于Google旗下的Google Brain[16]人工智能研讨小组。能够在此[17]了解更多关于Bfloat16的相关内容。
Bfloat16 Arithmetic.
Google为机器学习和深度学习运用,特别是在Tensor Processing Units(TPUs)中开发了这种格局。虽然 bfloat16 最初是为 TPU 开发的,但现在一些英伟达(NVIDIA)GPU 也支撑这种浮点数格局。
python -c "import torch; print(torch.cuda.is_bf16_supported())"
假如您需求运用bfloat16,您能够运转以下指令:
python generate/base.py \
--prompt "I am so fast that I can" \
--checkpoint_dir checkpoints/tiiuae/falcon-7b \
--max_new_tokens 50 \
--precision "bf16-true"
# Time for inference: 1.18 sec total, 42.47 tokens/sec
# Memory used: 14.50 GB
下图汇总了上述成果:
比较不同精度类型的推理速度和内存消耗
05 模型量化
假如咱们想在推理时进一步进步模型功用,在运用较低的浮点精度之外,咱们还能够运用量化技能。量化技能将模型权重从浮点数转换为低位整数表明,例如 8 位整数(乃至是 4 位整数)。 对深度神经网络运用量化技能一般有两种常见办法:
1.练习后量化技能(PTQ) :首要对模型进行练习,使其收敛,然后在不继续进行练习的状况下将其权重转换为较低的精度。与模型练习比较,这一进程的完结成本一般很低。
2.量化感知练习技能(QAT) :在预练习或进一步微调时运用量化。QAT的功用或许更好,但一起也需求更多的核算资源和具有代表性的练习数据。当咱们想要加快现有模型的推理速度,咱们应该运用练习后量化技能(Post-Training Quantization)。你能够在这里[18]阅览有关练习后量化(Post-Training Quantization)不同技能的更多信息。
注:最近宣布的一篇研讨论文《SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models》[19]指出,并非一切的量化技能都适用于大言语模型(LLM)。 因而,在咱们挑选量化办法时需求慎重考虑。我个人主张您阅览这篇文章《SpQR: A Sparse-Quantized Representation for Near-Lossless LLM Weight Compression》[20],该文章探讨了LLAMA和Falcon运用的量化技能。
运用不同量化技能的模型准确率下降程度与参数数量的联系。 Source: SmoothQuant: 《Accurate and Efficient Post-Training Quantization for Large Language Models》
鉴于现在Falcon模型尚未完结4位和8位的整数精度,所以接下来将运用Lit-LLaMA展现一个LLaMA 7B的案例。
python generate.py \
--prompt "I am so fast that I can" \
--quantize llm.int8
# Time for inference: 2.01 sec total, 24.83 tokens/sec
# Memory used: 13.54 GB
06 运用Adapters进行微调
虽然微调(fine-tuning)或许并非是一种加快终究模型推理进程的直接办法,但有几种技巧能够用来优化其功用:
1.预练习和模型量化(Pre-training and Quantization) :首要在特定范畴的问题上对模型进行预练习,然后进行模型量化。模型量化一般会导致模型质量略有下降,但最初的预练习能够略微缓解这一问题。
2.小型适配器(Small Adapters) :另一种办法是为不同使命引入小型适配器。适配器的工作原理是在现有模型层中添加紧凑的额外层(compact additional layers),并仅针对它们进行练习。这些适配器层拥有轻量级参数(lightweight parameters),使得模型能够快速适应和学习。
通过结合运用这些办法,能够完结模型的作用增强。
依据适配器(adapter-based)的 LLM 知识注入架构[21]
在适配器范畴,呈现了几种变体,包含LLaMA-Adapter(v1[22]、v2[23])、LoRa和QLoRa。其间,低秩自适应技能(Low-Rank Adaptation,LoRA) [24]体现最为杰出。LoRA通过在LLM的每一层引入少数的可练习参数,即适配器,并一起冻住一切原始参数。这种办法简化了微调进程,只需更新适配器权重,大大下降了内存消耗。
QLoRA[25]办法是在LoRA的根底上增加了模型量化技能其他一些优化,彻底改变了咱们在Google Colab实例上对模型进行微调的办法![26]
Adapter架构[27]
微调LLM或许需求消耗很多的资源,包含时刻和算力。例如,假如运用8个A100 GPU对Falcon-7B进行微调,大约需求半小时左右,而假如只运用单个GPU,大约需求三个小时。 此外,为了获得最佳的微调成果,前期需求对数据集进行一些恰当的预备工作。虽然我并没有亲自履行过模型的微调进程,但假如您想要自己着手,能够通过运转以下指令来启动微调进程(在这里[28]能够阅览更多相关信息):
python finetune/adapter_v2.py \
--data_dir data/alpaca \
--checkpoint_dir checkpoints/tiiuae/falcon-7b \
--out_dir out/adapter/alpaca
如需深化了解更多细节和具体信息,我引荐阅览以下内容:
-
Understanding Parameter-Efficient Finetuning of Large Language Models: From Prefix Tuning to LLaMA-Adapters[29]
-
Making LLMs even more accessible with bitsandbytes, 4-bit quantization, and QLoRA[30]
-
Finetuning Falcon LLMs More Efficiently With LoRA and Adapters – Lightning AI[31]
-
Colab notebook to fine-tune Falcon-7B on Guanaco dataset using 4bit and PEFT[32]
07 模型剪枝(Pruning)
网络剪枝(Network pruning)通过去除不重要的模型权重或连接来减小模型巨细,且一起还保持着模型容量。
另一种新办法 LLM-Pruner[33]能够依据梯度信息(gradient information)挑选性地移除非要害的耦合结构(non-critical coupled structures),选用的是结构剪枝(structural pruning),最大程度地保留了大型言语模型的功用。作者展现紧缩后的模型在零样本分类和生成(zero-shot classification and generation)方面体现杰出。
(译者注:LLM-Pruner依据参数梯度判别重要性,通过移除不重要的模型结构部分来进行模型紧缩。挑选哪部分移除的依据是参数梯度的巨细。)
Illustration of LLM-Pruner
LLM-Pruner这篇论文的作者公开了相关代码,但仅支撑 LLaMA-7B[34]和 Vicuna-7B[35]这两个大言语模型。
还有另一个风趣的剪枝器(pruner)——Wanda[36](依据权重值和激活值剪枝)。该办法会依据每个输出的根底,运用权重与对应输入激活值相乘的成果来剪枝权重。
与仅依据权重巨细的幅值剪枝比较,Wanda的剪枝办法是依据每个输出的根底,通过权重巨细与输入激活值范数的乘积来移除权重[36]
值得留意的是,Wanda不需求重新练习或更新权重,剪枝后的LLM能够直接运用。此外,它答应咱们将LLM剪枝至本来巨细的50%。
08 批量推理 Batch Inference
GPU以其大规模并行核算架构而闻名,在A100[37]上,模型的核算速率乃至以每秒万亿次浮点运算(teraflops)计量,而在像H100[38]这样的GPU上,模型乃至可到达每秒千万亿次浮点运算(petaflops)的水平。虽然有着巨大的核算才能,但因为GPU芯片的一大部分显存带宽被用于加载模型参数,LLM在假如想要充分发挥潜力常常面对困难。
其间一种有用的解决办法是运用批处理技能。与为每个输入序列加载新的模型参数不同,批处理只需求加载一次模型参数,并运用它们处理多个输入序列。这种优化策略高效运用了芯片的显存带宽,然后进步了算力运用率,改进了吞吐量,并使LLM推理愈加经济高效。 通过选用批处理技能,能够明显提高LLM的全体功用。
还有一种最近提出的优化办法——接连批处理(continuous batching) 。Orca施行了iteration-level scheduling,而不再需求等候批处理(batch)中的每个序列都完结生成,而是依据每次迭代来确定批巨细(batch size)。这样做的成果是,一旦批中的一个序列完结生成,就能够刺进一个新的序列,然后完结比静态批处理更高的GPU运用率。
运用接连批处理完结7个序列。左边显现通过一次迭代后的批处理成果,右边显现通过多次迭代后的批处理成果。
你能够在以下几个结构中运用这种算法:
-
Text Generation Inference[39]— 用于文本生成推理的服务端;
-
vLLM[40]— LLM的推理和服务引擎。
通过细心评价,我挑选了vLLM作为首选。vLLM选用了PagedAttention,这是一种新的留意力算法,能够有用地办理留意力键(keys)和值(values):在无需进行任何模型架构更改的状况下,它的吞吐量比HuggingFace Transformers高出多达24倍。
vLLM 的吞吐量比 HuggingFace Transformers (HF) 高 14 – 24 倍,比 HuggingFace Text Generation Inference (TGI) 高 2.2 – 2.5 倍。来历:vllm.ai/
考虑到 vLLM 无法支撑 Falcon[41],我决议改用 LLaMA-7B。
from vllm import LLM, SamplingParams
prompts = [
"I am so fast that I can",
"The capital of France is",
"The future of AI is",
]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
llm = LLM(model="huggyllama/llama-7b")
outputs = llm.generate(prompts, sampling_params)
for output in outputs:
prompt = output.prompt
generated_text = output.outputs[0].text
print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
# I am so fast that I can travel around the world in two hours. My first stop: the Southeast
# The capital of France is one of the most beautiful cities in the world. And it is no secret that
# The future of AI is in a future\nThis might sound like a depressing conclusion, but it
它出色的运转速度给我留下了深刻的印象。此外,该结构能够无缝地设置API服务器,完结快速布置。要启动该服务,请履行以下指令:
python -m vllm.entrypoints.api_server --model huggyllama/llama-7b
然后,您就能够运用下面这段代码来检查其功用了:
time curl http://localhost:8000/generate \
-d '{
"prompt": "I am so fast that I can",
"temperature": 0,
"use_beam_search": true,
"n": 4,
}'
# real 0m0.277s
# I am so fast that I can take through a story three get back before I started.
# I am so fast that I can turn around a Earth in come back for lunch.
# I am so fast that I can finish on the earth, still be for lunch.\nI am so fast
# I am so fast that I can run around the world and grab my own feet start.
您能够在这里[42]找到关于批量推理更具体的评测和基准测验。
09 运用多GPU
还能够运用全分片数据并行(Fully-Sharded Data Parallel,FSDP)分布式策略来运用多个GPU设备履行推理。重要的是要明白,运用多个GPU设备并不会加快推理进程,但能够通过将模型分片到多个设备上运转,使得那些无法在单张显卡上运转的模型变得能够运转。
例如,falcon-40b模型在单个设备上运转需求约80GB的GPU显存。假如咱们在2张A6000(48GB)上运转它,依然运用Lit-GPT,并只需对参数进行一些小幅调整:
python generate/base.py \
--checkpoint_dir checkpoints/tiiuae/falcon-40b \
--strategy fsdp \
--devices 2 \
--prompt "I am so fast that I can"
# Time for inference: 83.40 sec total, 0.60 tokens/sec
# Memory used: 46.10 GB
这将占用46GB的内存并以0.60个token/秒的速度运转。
运用全分片数据并行技能前后的功用比较
或者,咱们能够运用 vLLM,仅通过将 tensor_parallel_size 设置为 2,就能够以更快的速度生成文本。
prompts = [
"I am so fast that I can",
"The capital of France is",
"The future of AI is",
]
llm = LLM(model="huggyllama/llama-30b", tensor_parallel_size=2)
output = llm.generate(prompts, sampling_params)
# It takes only 0.140 seconds!
# I am so fast that I can travel back in time and eat my breakfast before I eat my breakfast!
# The future of AI is up to you.
10 附加部分:布置LLM模型服务
因为 vLLM 不支撑 Falcon,我决议展现怎么运用Text Generation Inference[39]来轻松布置模型。
Text Generation Inference架构
为了遵从结构作者引荐的最佳结构运用办法,主张履行供给的指令,在 Docker 容器内运转运用程序。运转 docker 容器指令如下:
docker run --gpus all --shm-size 1g -p 8080:80 \
-v $PWD/data:/data ghcr.io/huggingface/text-generation-inference:0.8 \
--model-id tiiuae/falcon-40b --num-shard 1 --quantize bitsandbytes
请留意,Falcon-7B 不支撑张量并行[43]。因而,有必要将参数 num_shard 设置为 1,以确保功用正常。
依据我的经验,在这个进程中,大约需求花费两分钟来下载Docker镜像、需求消耗30秒来下载scales。随后,将scales从.bin格局转换为.safetensors格局大约需求20秒。终究,下载终究的模型需求大约一分钟的时刻。
您能够运用以下指令来检查API的运转状况:
time curl http://localhost:8080/generate \
-X POST \
-d '{"inputs":"I am so fast that I can","parameters":{"max_new_tokens":50}}' \
-H 'Content-Type: application/json'
# real 0m3.148s
# I am so fast that I can do two things at the same time.
LLM推理的其他备选库:
1.Accelerate[44]:该库答应将模型的部分工作负载搬运到CPU上。即便整个模型都适合在GPU上运转,依然能够通过将部分核算使命搬运,优化推理服务的吞吐量。
2.DeepSpeed Inference[45]:这个库能够在以下状况下更高效地为依据Transformer的模型供给服务:(a) 模型适合在GPU上运转,以及 (b) DeepSpeed库支撑模型内核。假如需求重点关注推迟问题,这个解决计划您能够挑选。
3.DeepSpeed MII[46]:这是一个能够快速设置GRPC终端节点用于模型推理的库,能够选用ZeRO-Inference或DeepSpeed Inference技能。
4.OpenLLM[47]:这是一个用于在生产环境中运转大言语模型(LLMs)的敞开渠道。能够轻松地微调、布置、服务和监控任何LLMs。
5.Aviary[48]:这是一个新的开源项目,能够有用地简化和启用多个LLM模型的自保管服务。
欲了解更多信息,请在这里[49]阅览更多材料。
11 总结
LLM推理加快范畴状况比较复杂,现在仍处于初级阶段。在预备本文时,我发现了许多最近被开发的办法,其间一些看起来十分有潜力(这些办法都呈现在最近1-2个月内)。
但是,需求留意的是,并非一切的推理加快办法都能稳妥地发挥作用。有些办法乃至或许会下降模型的质量。 因而,盲目接受和运用一切的推理加快主张是不明智的,有必要通过慎重考虑。 您有必要保持慎重,控制加快模型(the accelerated model)的质量。
理想状况下,在软件优化(software optimization)和模型架构(model architecture)之间获得平衡是完结LLM推理高效加快的要害。
END
参考材料
1.twitter.com/Yampeleg/st…
2.arxiv.org/abs/2106.09…
3.arxiv.org/abs/2305.14…
4.github.com/microsoft/D…
5.github.com/vllm-projec…
6.falconllm.tii.ae/
7.tii.ae/
8.huggingface.co/tiiuae/falc…
9.arxiv.org/abs/1911.02…
10.huggingface.co/datasets/ti…
11.arxiv.org/abs/2306.01…
12.github.com/Lightning-A…
13.lightning.ai/docs/fabric…
14.en.wikipedia.org/wiki/Single…
15.lightning.ai/pages/commu…
16.www.wikiwand.com/en/Google_B…
17.nhigham.com/2020/06/02/…
18.lilianweng.github.io/posts/2023-…
19.arxiv.org/abs/2211.10…
20.arxiv.org/abs/2306.03…
21.arxiv.org/abs/2212.08…
22.arxiv.org/abs/2303.16…
23.arxiv.org/abs/2304.15…
24.arxiv.org/abs/2106.09…
25.arxiv.org/abs/2305.14…
26.huggingface.co/blog/4bit-t…
27.towardsdatascience.com/qlora-fine-…
28.lightning.ai/pages/blog/…
29.lightning.ai/pages/commu…
30.huggingface.co/blog/4bit-t…
31.lightning.ai/pages/commu…
32.colab.research.google.com/drive/1BiQi…
33.arxiv.org/abs/2305.11…
34.huggingface.co/docs/transf…
35.arxiv.org/abs/2306.11…
36.github.com/locuslab/wa…
37.www.nvidia.com/content/dam…
38.resources.nvidia.com/en-us-tenso…
39.github.com/huggingface…
40.github.com/vllm-projec…
41.github.com/vllm-projec…
42.www.anyscale.com/blog/contin…
43.github.com/huggingface…
44.github.com/huggingface…
45.github.com/microsoft/D…
46.github.com/microsoft/D…
47.github.com/bentoml/Ope…
48.www.anyscale.com/blog/announ…
49.preemo.medium.com/squeeze-mor…
原文链接:
betterprogramming.pub/speed-up-ll…