大大大大大语言模型部署方案抛砖引玉

点击下方卡片,关注“自动驾驶之心”公众号

戳我-> 领取自动驾驶近15个方向学习路线

>>点击进入→自动驾驶之心模型部署技术交流群

作者 | 沧海云帆

编辑 | 自动驾驶之心

0 写在前面

随着AI的不断发展,LLM逐渐从单一的自然语言处理任务扩展到处理多种媒体数据的多模态模型,同时模型参数量越来越大。像 GPT-4 和 LLaMA 这样的大型语言模型(LLM)已成为在各个层面为各种注入人工智能的应用提供服务的主要工作负载。从一般聊天模型到文档摘要,从自动驾驶到软件栈各层的协同机器人,大规模部署和服务这些模型的需求急剧上升。此外,模型规模越大,在实际应用中模型推理速度更更慢。因此研究LLM推理过程并提出优化方法以降低所需显存、降低功耗和提高模型推理速度,具有重要的意义。

关于LLM推理优化及加速,我们计划分几部分展开。首先,我们带大家了解LLM模型推理过程中存在的瓶颈及常见优化方法。

1 LLM推理

LLM推理主要分为两步骤:

1)encoding/prefill:预填充,并行处理输入的所有 tokens

2)decoding:解码,逐个生成下一个 token

重复这两个步骤直到生成 EOS token 或达到用户设定的停止条件(stop token 或最大 token 数)。

ec35af383415f167eef816b9f1b6b3e6.png
图1 LLM推理过程

以 Llama2-7B(序列长度4096,精度float16,输入prompt长度350token)在A10GPU上推理为例,计算 batch_size = 1的理想推理速度。

prefill

预填充所需要的时间 = token数量*(模型总参数所占字节数 / 计算带宽)= 350 * (2 * 7B) FLOP / 125 TFLOP/s = 39 ms。这个阶段性能瓶颈主要是算力

decoding

解码阶段每个token所需的生成时间  time/token = 模型总参数所占字节数 / 内存带宽 = (2 * 7B) bytes / (600 GB/s) = 23 ms/token,即每生成一个token理想情况下需要23ms。在此阶段,主要性能瓶颈是带宽。然而实际上由于带宽利用率较低,推理速度与理想时间相差较大。

2 LLM推理评价指标

主要有以下四个核心评价指标:

  • Time To First Token (TTFT): 首Token 延迟,即从输入到输出第一个 token的延迟。在线的流式应用中,TTFT 是最重要的指标,它决定了用户体验。

  • Time Per Output Token (TPOT):每个输出token 的延迟(不含首个Token)。在离线的批处理应用中,TPOT 是最重要的指标,它决定了整个推理的时间。

  • Latency:延迟,即从输入到输出最后一个 token 的延迟。Latency = (TTFT) + (TPOT) * (the number of tokens to be generated). Latency 可以转换为 Tokens Per Second (TPS):TPS = (the number of tokens to be generated) / Latency。

  • Throughput:吞吐量,即每秒针对所有请求生成的 token 数。以上三个指标都针对单个请求,而吞吐量是针对所有并发请求的。

其中在线的流式应用可以理解为存在多客户同时向LLM发出多请求的场景,离线的批处理应用可以理解为LLM部署在私域或本地服务器,这样不存在高并发请求的现象。对于线流式应用,为了给用户提供更好的使用体验,因此对 TTFT、TPOT、Latency 非常敏感,需要尽可能快的生成 token。对于离线批量应用,对 Throughput 敏感,需要在单位时间内尽可能多的生成 token。

3 LLM推理性能卡点分析

3.1 KV-Cache

由于LLM推理是一个自回归的过程,即在生成第i+1次token时,会将前i次生成的token送入模型,经过推理拿到第i+1次的输出token。

在这个过程中Transformer会执行自注意力操作,为此需要给当前序列中的每个token提取键值(kv)向量。这些向量存储在一个矩阵中,通常被称为kv cache。kv cache是为了避免每次采样token时重新计算键值向量。

举例:

对最大长度是 4096 的 LLaMa2-7B fp16 模型,服务端每创建 1 个并发,都需要大约 2GB 显存保存 kv_cache,即便是 A100 80G,能并发服务的用户非常有限。

所以KV-Cache 的减少以及优化是提高 LLM 推理性能的关键。

3.2 带宽瓶颈导致 TPOT 受限

随着GPU的发展迭代,计算能力一般不是推理瓶颈,而带宽才是瓶颈。衡量指标主要是模型带宽利用率 MBU。

MBU 计算方式:

MBU = 实际内存带宽 / 峰值内存带宽,

实际内存带宽 = (总模型参数大小 + KV 缓存大小) / TPOT

例子:

假如 7B fp16 模型的 TPOT 是 14ms,那么它就需要在 14ms 内把 14GB 参数从显存加载到计算单元,也就是 1TB/s 的带宽使用量。假设显卡的峰值带宽为 2TB/s,那么 MBU = 0.5,即显存带宽利用率是 50%。注:这里忽略了KV 缓存。

c4dbae7419c978cda34cb8b649cac457.png
图2 LLM推理过程不同阶段的性能瓶颈分析

4 LLM推理优化方法

下面介绍目前业界在生产环境下常用的优化技术

4.1 Operator Fusion 算子融合

通过转换工具,将神经网络中的部分层进行融合,从而降低计算量和数据量,提高推理性能。

常见的两个框架是 FasterTransformer(TensorRT) 和 Deepseed Inference,都可以通过转换的方式,融合 Transformer 的特定层。

ba9542c0980448607219d7ebd28435ef.png
图3 Deepspeed 层融合示意图

4.2 Quatization 量化

量化除了降低模型需要的显存外,最直接的收益就是降低了带宽使用率,所以从理论上来说,量化后的模型性能应该是成比例提升的,这个提升不仅体现在吞吐量上,也会体现在 Latency 上。量化分类:

  1. 量化感知训练(QAT):在训练(一般是 sft 中)过程中,通过量化感知训练,让模型适应低精度的计算,从而保护模型的效果不受量化影响。少数模型提供了相关权重。

  2. 动态离线量化(PTQ Dynamic):缩放因子(Scale)和零点(Zero Point)是在推理时计算的,特定用于每次激活。不需要样本数据训练,但是性能和效果都略低。

  3. 静态离线量化(PTQ Static):需要少量无标签样本进行校准,计算出缩放因子和零点,然后在推理时使用。性能和效果都比动态离线量化好。目前一般使用这种量化方式。

4.3 FlashAttention

FlashAttention 就是通过利用 GPU 硬件中的特殊设计,针对全局内存和共享存储的 I/O 速 度的不同,尽可能的避免 HBM(全局内存)中读取或写入注意力矩阵。FlashAttention 目标是尽可能高效地使 用 SRAM (共享内存)来加快计算速度,避免从全局内存中读取和写入注意力矩阵。

179c7e411378fd9dd3e0d8e132579937.png
图4 GPU内存架构图

4.4 PageAttention

随着序列长度和并发数的增加,KV-Cache 的大小等比例提升,成为核心瓶颈。目前主要采用PageAttention优化方法:

KV Cache 的大小取决于序列长度,这是高度可变和不可预测的。实际上因为显存碎片和过度预留,浪费了 60% - 80% 的显存。PageAttention 参考虚拟内存和内存分页的思想,解决显存碎片化的问题,提高显存利用率,从而提升推理性能。同时 PageAttention 具备 Copy-on-Write 的特性,可以对相同的 Prompt 共享 KV Cache,从而节省显存。

PagedAttention 是 vLLM 的核心技术,在生产环境中一般都有 4x 以上的性能提升。

与传统的注意力算法不同,PagedAttention 允许在不连续的内存空间中存储连续的键和值。具体来说,PagedAttention 将每个序列的 KV 缓存划分为多个块,每个块包含固定数量的令牌的键和值。在注意力计算过程中,PagedAttention 内核会有效地识别和获取这些块。由于块不需要在内存中是连续的,因此我们可以像在操作系统的虚拟内存中一样以更灵活的方式管理键和值:可以将块视为页面,将 token 视为字节,将序列视为进程。序列的连续逻辑块通过块表映射到非连续的物理块。随着新 token 的生成,物理区块会按需分配。

4.5 并行化

并行化可以有效利用多个设备进行推理,从而提升吞吐,降低延迟。

1b4ca5142bef299800d17dfc35f081ef.png
表1 多设备并行推理性能比较
980072c1bdf29717c002b556ca03bbb3.png

4.6 批处理

  • 静态批处理 (Static Batching):在推理前,将多个请求合并为一个大的请求,然后一次性推理。这种方式可以提高吞吐量,但是需要所有请求都完成后才能返回结果,所以一般不会应用。

  • 动态/持续批处理(Continuous Batching):持续批处理是一种特殊的动态批处理,它可以在序列结束后,继续接受新的序列。从而在保证延迟的情况下,提高吞吐量。

投稿作者为『自动驾驶之心知识星球』特邀嘉宾,欢迎加入交流!

① 全网独家视频课程

BEV感知、毫米波雷达视觉融合多传感器标定多传感器融合多模态3D目标检测车道线检测轨迹预测在线高精地图世界模型点云3D目标检测目标跟踪Occupancy、cuda与TensorRT模型部署大模型与自动驾驶Nerf语义分割自动驾驶仿真、传感器部署、决策规划、轨迹预测等多个方向学习视频(扫码即可学习

d83bf2fe08b2c55ff07d6f406922c8ea.png 网页端官网:www.zdjszx.com

② 国内首个自动驾驶学习社区

国内最大最专业,近3000人的交流社区,已得到大多数自动驾驶公司的认可!涉及30+自动驾驶技术栈学习路线,从0到一带你入门自动驾驶感知2D/3D检测、语义分割、车道线、BEV感知、Occupancy、多传感器融合、多传感器标定、目标跟踪)、自动驾驶定位建图SLAM、高精地图、局部在线地图)、自动驾驶规划控制/轨迹预测等领域技术方案大模型、端到端等,更有行业动态和岗位发布!欢迎扫描下方二维码,加入自动驾驶之心知识星球,这是一个真正有干货的地方,与领域大佬交流入门、学习、工作、跳槽上的各类难题,日常分享论文+代码+视频

3f46dbbe155a2c4910cb9df2fcacf365.png

③【自动驾驶之心】技术交流群

自动驾驶之心是首个自动驾驶开发者社区,聚焦感知、定位、融合、规控、标定、端到端、仿真、产品经理、自动驾驶开发、自动标注与数据闭环多个方向,目前近60+技术交流群,欢迎加入!

自动驾驶感知:目标检测、语义分割、BEV感知、毫米波雷达视觉融合、激光视觉融合、车道线检测、目标跟踪、Occupancy、深度估计、transformer、大模型、在线地图、点云处理、模型部署、CUDA加速等技术交流群;

多传感器标定:相机在线/离线标定、Lidar-Camera标定、Camera-Radar标定、Camera-IMU标定、多传感器时空同步等技术交流群;

多传感器融合:多传感器后融合技术交流群;

规划控制与预测:规划控制、轨迹预测、避障等技术交流群;

定位建图:视觉SLAM、激光SLAM、多传感器融合SLAM等技术交流群;

三维视觉:三维重建、NeRF、3D Gaussian Splatting技术交流群;

自动驾驶仿真:Carla仿真、Autoware仿真等技术交流群;

自动驾驶开发:自动驾驶开发、ROS等技术交流群;

其它方向:自动标注与数据闭环、产品经理、硬件选型、求职面试、自动驾驶测试等技术交流群;

扫码添加汽车人助理微信邀请入群,备注:学校/公司+方向+昵称(快速入群方式)

c19f6c3e8327973be5502f06e3dba18a.jpeg

④【自动驾驶之心】平台矩阵,欢迎联系我们!

728aee1389d5d6ddb03846bc8b4b48c7.jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很好,我理解您的问题。为了完成这个任务,您可以使用OpenCV和Pillow这两个库来完成图片的抠图、修改背景颜色和图片大小的操作。以下是一个简单的Python代码示例,供您参考: ``` import cv2 from PIL import Image # 读取图片 img = cv2.imread("photo.jpg") # 将图片转成灰度图并进行二值化处理 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # 进行腐蚀和膨胀操作,消除噪点 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) erosion = cv2.erode(thresh, kernel, iterations=1) dilation = cv2.dilate(erosion, kernel, iterations=1) # 进行轮廓检测 contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 找到最大轮廓 max_contour = max(contours, key=cv2.contourArea) # 生成掩模图像 mask = cv2.drawContours(np.zeros_like(img), [max_contour], 0, (255, 255, 255), -1) # 抠出图片并保存 result = cv2.bitwise_and(img, mask) cv2.imwrite("foreground.jpg", result) # 修改背景颜色 im = Image.open("foreground.jpg") im = im.convert("RGBA") datas = im.getdata() new_data = [] for item in datas: if item[3] == 0: new_data.append((255, 255, 255, 0)) else: new_data.append((255, 0, 0, item[3])) im.putdata(new_data) im.save("background.jpg") # 修改图片大小 img = cv2.imread("background.jpg") resized_img = cv2.resize(img, (256, 256)) cv2.imwrite("resized.jpg", resized_img) ``` 这个代码示例仅仅是抛砖引玉,您可以根据自己的需求进行更加具体的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值