动手点关注
干货不迷路
本文旨在让无大模型开发背景的工程师或者技术爱好者无痛理解大语言模型应用开发的理论和主流工具,因此会先从与LLM应用开发相关的基础概念谈起,并不刻意追求极致的严谨和完备,而是从直觉和本质入手,结合笔者调研整理及消化理解,帮助大家能够更容易的理解LLM技术全貌,大家可以基于本文衍生展开,结合自己感兴趣的领域深入研究。若有不准确或者错误的地方也希望大家能够留言指正。
本文体系完整,内容丰富,由于内容比较多,分多次连载 。
第一部分 基础概念
1.机器学习场景类别
2.机器学习类型(LLM相关)
3.深度学习的兴起
4.基础模型
第二部分 应用挑战
1.问题定义与基本思路
2.基本流程与相关技术
1)Tokenization与Embbeding
2)向量数据库
3)finetune(微调)
4)模型部署与推理
5)prompt
6)编排与集成
7)预训练
第三部分 场景案例
常用参考
2.基本流程与相关技术
4)模型部署与推理
模型服务层相关工具和框架
前文对模型服务层做了简单的分类,基于封装程度不同,有大量的框架和工具,笔者结合目前趋势,在每个类别中挑选了几个常见的项目和大家分享,它们各有特点,将从内向外一一介绍,最后给出一些选型建议以供参考。
Text Generation Inference (TGI)
如果说huggingface transformers pipeline是以统一模型推理流程,简化使用,作为设计目标的话,那么Text Generation Inference(TGI)就是为了大模型高性能文本生成任务推理而生,它支持当下流行的开源 LLM(包括 Llama2、Falcon、StarCoder、BLOOM、GPT-NeoX 和 T5)。
受限于设计目标,HF pipelines虽然对于模型推理有一定的优化,但是,对于大模型及文本生成这样的垂直场景缺乏针对性深度优化,举一个例子,比如HF pipeline的批处理是静态批处理(static batch),其随之而来的内存浪费甚至OOM都是难以解决的问题,而我们在前面提到过动态批处理能够很好的解决这类问题,能够进一步提升吞吐,降低延迟。为了这样一个目标,当然也考虑到竞争对手triton server在对Huggingface 模型支持及时性和易用性上的原因,Huggingface设计开发了Text Generation Inference,它是一个使用Rust、Python语言及gRPC技术开发的专门用于大模型文本生成的推理服务,支持张量并行和动态批处理技术。通过架构图也可以看出,请求会被缓冲构造成batch再执行推理。
随着大模型推理技术的不断发展,TGI第一时间集成了当前主流的推理优化技术,包含量化(GPT-Q,bitsandbytes),flashAttention V2(23/7/18),pagedAttention(23/7/1)等技术,还增加了很多体验增强及生产运维层面的功能,可谓是非常的全面。
在使用层面huggingface保持一贯的简单友好的特点,使用比较简单。
1.创建TGI推理服务,可以用通过源码部署,官方建议通过容器化方式启动,注意需要 CUDA 版本>=1.8,并且安装NVIDIA Container Toolkit(https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html)自动配置容器,以确保能够获得GPU加速。
docker run --gpus all --shm-size 1g -p 8080:80 \
-v $volume:/data \
ghcr.io/huggingface/text-generation-inference:latest \
--model-id $model --num-shard $num_shard \
--quantize $quantize
2.可以直接使用curl或者TGI Client访问推理服务。
TGI提供推理API:
/ — [POST] — Generate tokens if stream == false or a stream of token if stream == true
/info — [GET] — Text Generation Inference endpoint info
/metrics — [GET] — Prometheus metrics scrape endpoint
/generate — [POST] — Generate tokens
/generate_stream — [POST] — Generate a stream of token using Server-Sent Events
其请求体parameters属性可选配置比较多,常见的如下:
- temperature:控制模型的随机性。数值越小,模型的确定性越强,数值越大,模型的随机性越强。默认值为 1.0。
- max_new_tokens:生成token的最大数量。默认值为 20,最大值为 512。
- repetition_penalty(重复惩罚):控制重复的可能性,默认值为空。
- seed(种子随机生成时使用的种子,默认为空。
- stop(停止用于停止生成的标记列表。当其中一个token生成后,生成将停止。
- top_k:要保留用于 top-k 过滤的最高概率词汇的数量。默认值为空,表示禁用 top-k 过滤。
- top_p:要保留用于核采样的参数最高概率词汇的累积概率,默认值为空
- do_sample:是否使用采样;否则使用贪婪解码。默认值为 false。
- best_of:生成 best_of 序列并返回 logprobs 最高的序列,默认值为空。
- details:详细信息:是否返回生成序列的详细信息。默认值为 false。
- return_full_text(返回全文是否返回全文或仅返回生成的部分。默认值为 false。
- truncate(截断是否将输入截断为模型的最大长度。默认值为 true。
- typ_p:标记的典型概率。默认值为空。
- watermark:水印:用于生成的水印。默认值为 false。
详细参考swagger:https://huggingface.github.io/text-generation-inference/
使用curl访问的例子
curl 127.0.0.1:8080/generate \
-X POST \
-d '{"inputs":"What is Deep Learning?","parameters":{"max_new_tokens":20}}' \
-H 'Content-Type: application/json'
除此之外,TGI还和langchain等编排框架友好集成,开发者可以方便地使用本地或者云端的TGI提供的推理服务。
# Wrapper to TGI client with langchain
from langchain.llms import HuggingFaceTextGenInference
inference_server_url_local = "http://127.0.0.1:8080"
llm_local = HuggingFaceTextGenInference(
inference_server_url=inference_server_url_local,
max_new_tokens=400,
top_k=10,
top_p=0.95,
typical_p=0.95,
temperature=0.7,
repetition_penalty=1.03,
)
from langchain import PromptTemplate, LLMChain
template = """Question: {question}
Answer: Let's think step by step."""
prompt = PromptTemplate(
template=template,
input_variables= ["question"]
)
llm_chain_local = LLMChain(prompt=prompt, llm=llm_local)
llm_chain_local("your question")
相比于HF pipelines一般会被作为其它推理框架的对比基线使用,不直接应用在大规模的生产服务中,TGI现在已经被广泛使用, AWS SageMaker等机器学习平台集成了它,IBM, Grammarly等客户也在使用TGI构建自己的推理服务,还包含后面我们将提到的RayLLM,HuggingChat也都会使用。
VLLM
vLLM是由加州大学伯克利分校推出的利用PagedAttention和动态批处理技术开发的推理执行引擎。该项目最初是产生的场景是在今年4月lmsys上线了可切换模型的ChatBot-FastChat及评测对话模型效果擂台服务,用户可以在不知道背后模型是谁的情况下,评价模型的好坏,现在已经发展成为全球模型评价的权威榜单之一,很多新的榜单评价模型的方法也是从这里借鉴而来。
该项目上线后,用户热情很高,峰值流量飙升了数倍,使原来的HuggingFace的transformers Pipeline 模型推理后端成为瓶颈,为了解决这一问题,团队自研了vLLM,将其作为FastChat的新后端,在早期内部微基准测试中,vLLM 服务后端比最初的HuggingFace后端吞吐量高出 30 倍。4月至5月期间,FastChat 将vLLM集成在聊天机器人擂台中提供的请求。事实上,超过一半的聊天机器人擂台请求使用vLLM作为推理后端。vLLM也显著降低了运营成本。使用vLLM,LMSYS能够将用于服务上述流量的GPU数量减少50%。vLLM平均每天处理30K个请求,峰值为60K,这清楚地证明了vLLM的稳健性。
当下,vLLM已经成长为最受业内欢迎的推理执行引擎之一,它提出的pagedAttention可以说是其杀手锏,在LLaMA-7B 使用英伟达A10G GPU,LLaMA-13B 使用英伟达A100 GPU(40GB)。从 ShareGPT 数据集中对请求的输入/输出长度进行了采样。实验结果,vLLM 的吞吐量比 HF 高出 24 倍,比 TGI 高出 3.5 倍。
由于该结果是论文发布(6月20日)时公布的测试对比,而TGI在7月1日也已经支持pagedAttention和动态批处理,最新版本两者差距如何尚不清楚。
不仅如此,vLLM也具有比较强的易用性,支持当前流行的模型,能够和HuggingFace上的模型无缝集成,具有各种解码算法的高吞吐量服务,包括 parallel sampling、beam search等分布式推理的张量并行性,支持流输出,其接口格式兼容OpenAI的API。
基本使用
vLLM默认形态是一个Lib,可以手工配套FastAPI使用,变成一个推理服务,后来为了方便开发者使用,项目默认提供了集成方案,开发者直接部署即可。
1)批量推理
$ pip install vllm
from vllm import LLM, SamplingParams
prompts = [
"Hello, my name is",
"The president of the United States is",
"The capital of France is",
"The future of AI is",
]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
llm = LLM(model="facebook/opt-125m")
outputs = llm.generate(prompts, sampling_params)
# Print the outputs.
for output in outputs:
prompt = output.prompt
generated_text = output.outputs[0].text
print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
2)作为服务部署
python -m vllm.entrypoints.api\_server
该接口符合OpenAI的风格,直接使用openai的client lib就能无缝访问。
curl http://localhost:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{
"model": "facebook/opt-125m",
"prompt": "San Francisco is a",
"max_tokens": 7,
"temperature": 0
}'
openai client方式访问:
import openai
# Modify OpenAI's API key and API base to use vLLM's API server.
openai.api_key = "EMPTY"
openai.api_base = "http://localhost:8000/v1"
completion = openai.Completion.create(model="facebook/opt-125m",
prompt="San Francisco is a")
print("Completion result:", completion)
与Ray和Triton Server集成
vLLM 支持分布式张量并行推理和服务,使用 Ray 管理分布式运行时。 要使用 LLM 类运行多 GPU 推理,可将 tensor_parallel_size 参数设置为要使用的 GPU 数量。例如,在 4 个 GPU 上运行推理:
from vllm import LLM
llm = LLM("facebook/opt-13b", tensor_parallel_size=4)
output = llm.generate("San Franciso is a")
要运行多 GPU 服务,请在启动服务器时输入 --tensor-parallel-size 参数。例如,在 4 个 GPU 上运行 API 服务器:
python -m vllm.entrypoints.api_server \
--model facebook/opt-13b \
--tensor-parallel-size 4
要将 vLLM 扩展到单台机器之外,运行 vLLM 之前通过 CLI 启动 Ray 运行时:
# On head node
ray start --head
# On worker nodes
ray start --address=<ray-head-address>
之后,通过将 tensor_parallel_size 设置为 GPU 数量(即所有机器上 GPU 的总数),在头部节点上启动 vLLM 进程,即可在多台机器上运行推理和服务,再将ray通过kubeRay运行在K8S上,一个生产就绪的部署方案呼之欲出。
另外,不用担心,vLLM和Ray为了简化开发者使用,联合开发了RayLLM项目,在后面部分会介绍到,它整合了这些功能,开发者能够很轻松在分布式环境下进行推理部署。
不仅如此,vLLM还可以运行在Triton Server上,这也进一步体现了其强大的生态适配能力。具体可参考:https://github.com/triton-inference-server/tutorials/blob/main/Quick\_Deploy/vLLM/README.md
TensorRT-LLM
英伟达作为AI领域超一线的公司,很早就押注深度学习,在2016年11月就推出了TensorRT(原名GPU Inference Engine (GIE)),它是一个深度学习模型优化器和运行时库,它可以将深度学习模型转换为优化的格式,从而在英伟达GPU上实现更快的推断速度。其早期在嵌入式场景有比较广泛的应用。
可以看到,TensorRT本质上是一种Intermediate representation (IR),通过它可以将面向提升开发者开发效率的语言转换为面向提升目标平台执行效率的语言,LLVM就是其代表之一。
TensorRT可以直接解析某些框架(如PyTorch、TF)的模型或通过 ONNX 格式导入模型,然后通过一系列优化操作来提升模型推理速度。比如,通过自动识别可以合并的连续层,并将它们融合成一个操作。这减少了在 GPU 上的操作数量,从而提高了执行速度。同时,还可以做到与机器学习框架解耦。
另一方面,随着transformer架构的模型越来越流行,英伟达为了提升transformer模型推理的性能,开发了FasterTransformer,并于2019年开源,它包含Transformer块的高度优化版本的实现,其中包含编码器和解码器部分。使用此模块,您可以运行编码器-解码器架构模型(如:T5)、仅编码器架构模型(如:BERT)和仅解码器架构模型(如:GPT)的推理。FT框架是用C++/CUDA编写的,依赖于高度优化的 cuBLAS、cuBLASLt 和 cuSPARSELt 库,可以在 GPU 上进行快速的 Transformer 推理。
但不可否认,虽然英伟达手握推理全栈TensorRT,FasterTransformer,Triton Server,但在新的AI 2.0时代,过去优势并不能持续保持,甚至有被赶超之势,比如HuggingFace的TGI,一方面英伟达拉拢huggingface,并将其集成在自己的开发平台。
Hugging Face作为开源AI领域的独角兽,在LLM开发工具链和模型生态领域持续领跑。就在前几天英伟达新品发布会上,Hugging Face作为英伟达新产品AI workbench的重要部件被集成,从某种意义上,这是绿色巨人对这家独角兽公司的认可,也反映了Hugging Face在模型开发领域的独到理解。
ully,公众号:AI工程化Hugging Face偷偷放大招了,Rust版本的ML框架Candle曝光
另一方面,也在不断完善自己在大模型层面的技术,特别是大模型推理。最近9月,英伟达将TensorRT的深度学习编译器、FasterTransformer的优化内核、预处理和后处理以及多 GPU/多节点通信,封装在一个简单的开源Python API中并且搭配硬件(GPU H100等)进行了一体优化,形成了产品级的大模型推理的方案TensorRT-LLM。TensorRT-LLM提供了一个易用、开源和模块化的Python应用编程接口,不需要深入的C++或CUDA专业知识,能够部署、运行、调试各种大语言模型,还能获得顶尖性能表现,以及快速定制化的功能,其在GPT-J 6B的推理性能较A100提升了8倍。在LLaMA2上提升了4.6倍。不得不说,软硬一体优化是英伟达独有的优势。
官方给出了如下特点介绍:
- 专为 LLM 设计:与标准的 TensorRT 不同,TensorRT-LLM 针对大型语言模型的特定需求和挑战进行了优化。
- 集成优化:NVIDIA 与多家领先公司合作,将这些优化集成到了 TensorRT-LLM 中,以确保 LLM 在 NVIDIA GPU 上的最佳性能。
- 模块化 Python API:TensorRT-LLM 提供了一个开源的模块化 Python API,使开发者能够轻松定义、优化和执行新的 LLM 架构和增强功能。
- 飞行批处理(In-flight batching):这是一种优化的调度技术,可以更有效地处理动态负载。它允许 TensorRT-LLM 在其他请求仍在进行时开始执行新请求,从而提高 GPU 利用率。
- 支持新的 FP8 数据格式:在 H100 GPU 上,TensorRT-LLM 支持新的 FP8 数据格式,这可以大大减少内存消耗,同时保持模型的准确性。
- 广泛的模型支持:TensorRT-LLM 包括了许多在今天生产中广泛使用的 LLM 的完全优化、即用版本,如 Meta Llama 2、OpenAI GPT-2 和 GPT-3 等。
- 并行化和分布式推断:TensorRT-LLM 利用张量并行性进行模型并行化,这使得模型可以在多个 GPU 之间并行运行,从而实现大型模型的高效推断。
- 优化的内核和操作:TensorRT-LLM 包括了针对 LLM 的优化内核和操作,如 FlashAttention 和遮蔽多头注意力等。
- 简化的开发流程:TensorRT-LLM 旨在简化 LLM 的开发和部署过程,使开发者无需深入了解底层的技术细节。
从上面可以看到,英伟达将最近的一些优化思路都应用到了TensorRT-LLM中,其获得如此高的性能优化也不能解释。
遗憾的是,目前该工具还处于早期试用阶段,并且需要组织身份才能注册获取资格。按照官方计划,该工具将会被集成到英伟达的 NeMo框架中(一款供开发者构建和训练对话式 AI 模型的开源框架,被集成在NVIDIA的企业级AI平台),普通开发者还需要再等一段时间,未来可通过NGC(英伟达的GPU云服务)上的NeMo框架或github使用到TensorRT LLM。
DeepSpeed-MII
该项目背靠AI领域另一个超一流玩家微软,是鼎鼎大名的DeepSpeed的一部分,核心目标便是优化大模型推理性能,降低推理成本和使用门槛。
DeepSpeed是一个由微软开发的开源深度学习优化库,旨在提高大规模模型训练的效率和可扩展性。它通过多种技术手段来加速训练,包括模型并行化、梯度累积、动态精度缩放、本地模式混合精度等。DeepSpeed还提供了一些辅助工具,如分布式训练管理、内存优化和模型压缩等,以帮助开发者更好地管理和优化大规模深度学习训练任务。此外,deepspeed基于pytorch构建,只需要简单修改即可迁移。DeepSpeed已经在许多大规模深度学习项目中得到了应用,包括语言模型、图像分类、目标检测等等。
据官方介绍中, MII提供了对数千种广泛使用的DL模型的高度优化实现的访问。与模型原始实现相比,MII支持的模型实现了显著更低的延迟和成本。例如,MII将Big Science Bloom 176B模型的延迟降低了5.7倍,同时将成本降低了40倍以上。同样,它将部署Stable Diffusion的延迟和成本降低了1.9倍。在推理优化技术上,为MII利用了DeepSpeed推理的一系列优化,如transformer的深度融合、多GPU推理的自动张量切片、ZeroQuant的动态量化等技术。MII 支持简单快速的本地部署或者Azure云部署。
DeepSpeed-Inference是DeepSpeed框架在推理方面的扩展。合并了张量、流水线并行以及自定义优化cuda核等并行化技术。DeepSpeed提供了无缝推理模式来兼容DeepSpeed、Megatron和HuggingFace训练的Transformer模型。集成了模型并行技术,从而使得可以在多个GPU上进行大模型的推理。注意:DeepSpeed的代码不能使用 python来执行,需要通过deepspeed命令执行,如:
deepspeed --num_gpus 4 --master_port 60000 inference.py
在架构层面,MII 由 DeepSpeed-Inference 支持。根据模型类型、模型大小、批量大小和可用硬件资源,MII 会自动应用来自 DeepSpeed-Inference 的推理优化策略,以最大限度地减少延迟和提高吞吐量。它通过使用许多预先指定的模型注入策略之一来实现这一目标,这些策略允许 MII 和 DeepSpeed-Inference 识别 PyTorch 模型的基础架构,并将其替换为优化后的实现。这样,MII 就能自动地利用DeepSpeed-Inference 中的大量优化策略优化数千种流行模型 。
MII 架构,显示 MII 如何在使用 GRPC 部署到企业内部或使用 AML Inference 部署到 Microsoft Azure 之前,使用 DS-nference 自动优化OSS模型。
在模型支持上,MII 目前已支持 50,000 多个模型,涵盖文本生成、问题解答、文本分类等一系列任务。由 MII 加速的模型可通过多个开源模型库获得,如 Hugging Face、FairSeq、EluetherAI 等。支持基于 Bert、Roberta 或 GPT 架构的密集模型,规模从数亿参数到数百亿参数不等。未来将支持大规模的千亿参数密集模型和稀疏模型。但遗憾的是,目前尚不支持llama2等流行的模型。
在部署上,MII 有两种不同的推理服务形式。第一种称为ds-public,项目包含大部分DeepSpeed-Inference优化功能,也可通过DeepSpeed库使用。第二种称为ds-azure,与Azure的集成更紧密,通过MII提供给所有微软Azure客户。与开源的 PyTorch 基线相比,两种变体都能显著降低延迟和成本,而后者还能为基于生成的工作负载提供额外的性能优势。
GPT 模型的延迟比较。MII-Azure 比基线快达 3 倍
简单使用例子:
1) 部署运行
# DON'T INSTALL USING pip install deepspeed-mii
# git clone https://github.com/microsoft/DeepSpeed-MII.git
# git reset --hard 60a85dc3da5bac3bcefa8824175f8646a0f12203
# cd DeepSpeed-MII && pip install .
# pip3 install -U deepspeed
# ... and make sure that you have same CUDA versions:
# python -c "import torch;print(torch.version.cuda)" == nvcc --version
import mii
mii_configs = {
"dtype": "fp16",
'max_tokens': 200,
'tensor_parallel': 1,
"enable_load_balancing": False
}
mii.deploy(task="text-generation",
model="huggyllama/llama-13b",
deployment_name="llama_13b_deployment",
mii_config=mii_configs)
2)查询实例
import mii
generator = mii.mii_query_handle("llama_13b_deployment")
result = generator.query(
{"query": ["Funniest joke ever:"]},
do_sample=True,
max_new_tokens=200
)
print(result)
未完待续。。。
鉴于篇幅原因,在下一篇中将继续面向端侧设备的推理引擎。
合集目录:
3)微调
4)模型部署与推理
一文探秘LLM应用开发(8)-模型部署与推理(DEMO验证)
一文探秘LLM应用开发(9)-模型部署与推理(模型适配优化之GPU面面观-1)
一文探秘LLM应用开发(10)-模型部署与推理(模型适配优化之GPU面面观-2)
一文探秘LLM应用开发(11)-模型部署与推理(模型大小与推理性能的关系)