开源大模型部署及推理所需显卡成本必读之二

在前面的文章中,我们介绍了大模型占用显卡空间的一些分析情况,这次我们继续来看看具体量化角度上的结论。

因此,本文来来介绍一个偏具体数值量化的工作。

随着各厂商相继发布大型模型,排行榜变化频繁,新旧交替,呈现出一片繁荣景象。有些技术爱好者也开始心痒难耐,萌生了构建一个庞大模型并进行训练的想法。每天都能看到各个厂家推出内测版本,这让人不禁思考:为何不在本地环境尝试一番呢?然而,当前手头仅有一块性能有限的老破小GPU显卡,这就引发了一个问题:如何在这样的条件下成功运行模型?本文将引领读者探索一个切实可行的解决方案,并提出一个关键问题:如何通过模型参数量粗略估算所拥有的GPU显存是否足够?

一、了解大模型参数

1.1 模型参数单位

"10b"、"13b"、"70b"等术语通常指的是大型神经网络模型的参数数量。其中的 "b" 代表 "billion",也就是十亿。表示模型中的参数量,每个参数用来存储模型的权重和偏差等信息。例如:

  • "10b" 意味着模型有大约 100 亿个参数。
  • "13b" 意味着模型有大约 130 亿个参数。
  • "70b" 意味着模型有大约 700 亿个参数。

    例如:Meta 开发并公开发布的 Llama 2 系列大型语言模型 (LLM),这是一组经过预训练和微调的生成文本模型,参数规模从 70 亿(7b)到 700 亿(70b)不等。经过微调的LLMs(称为 Llama-2-Chat)针对对话场景进行了优化。

    • meta-llama/Llama-2-7b-hf
    • meta-llama/Llama-2-13b-hf
    • meta-llama/Llama-2-70b-hf
      输入:仅输入文本
      输出:仅生成文本
      模型架构:Llama 2 是一种使用优化的 Transformer 架构的自回归语言模型。调整后的版本使用监督微调(SFT)和带有人类反馈的强化学习(RLHF)来适应人类对有用性和安全性的偏好。

1.2 模型参数精度

模型参数的精度通常指的是参数的数据类型,它决定了模型在内存中存储和计算参数时所使用的位数。以下是一些常见的模型参数精度及其含义,以及它们在内存中所占用的字节数:

 

  1. 单精度浮点数 (32位) - float32:

    • 含义:单精度浮点数用于表示实数,具有较高的精度,适用于大多数深度学习应用。
    • 字节数:4字节(32位)
  2. 半精度浮点数 (16位) - float16:

    • 含义:半精度浮点数用于表示实数,但相对于单精度浮点数,它的位数较少,因此精度稍低。然而,它可以在某些情况下显著减少内存占用并加速计算。
    • 字节数:2字节(16位)
  3. 双精度浮点数 (64位) - float64:

    • 含义:双精度浮点数提供更高的精度,适用于需要更高数值精度的应用,但会占用更多的内存。
    • 字节数:8字节(64位)
  4. 整数 (通常为32位或64位) - int32, int64:

    • 含义:整数用于表示离散的数值,可以是有符号或无符号的。在某些情况下,例如分类问题中的标签,可以使用整数数据类型来表示类别。
    • 字节数:通常为4字节(32位)或8字节(64位)

注意: 模型参数精度的选择往往是一种权衡。使用更高精度的数据类型可以提供更高的数值精度,但会占用更多的内存并可能导致计算速度变慢。相反,使用较低精度的数据类型可以节省内存加速计算,但可能会导致数值精度损失。在实际应用中,选择模型参数的精度需要根据具体任务、硬件设备和性能要求进行权衡考虑。

实际上,通常情况下并没有标准的整数数据类型为int4或int8,因为这些整数数据类型不太常见,且在大多数计算机体系结构中没有直接支持。在计算机中,整数通常以字节为单位进行存储,所以int4表示一个4位的整数,int8表示一个8位的整数。

然而,近年来在深度学习领域中,出于模型压缩和加速的考虑,研究人员开始尝试使用较低位数的整数来表示模型参数。例如,一些研究工作中使用的int4int8等整数表示法是通过量化(quantization)技术来实现的。

在量化技术中,int4和int8分别表示4位和8位整数。这些整数用于表示模型参数,从而减少模型在存储和计算时所需的内存和计算资源。量化是一种模型压缩技术,通过将浮点数参数映射到较低位数的整数,从而在一定程度上降低了模型的计算和存储成本。以下是对这两种精度的解释以及它们在内存中占用的字节数:

  1. int4 (4位整数):

    • 含义:int4使用4位二进制来表示整数。在量化过程中,浮点数参数将被映射到一个有限的范围内的整数,然后使用4位来存储这些整数。
    • 字节数:由于一个字节是8位,具体占用位数而非字节数,通常使用位操作存储。
  2. int8 (8位整数):

    • 含义:int8使用8位二进制来表示整数。在量化过程中,浮点数参数将被映射到一个有限的范围内的整数,然后使用8位来存储这些整数。
    • 字节数:1字节(8位)

 

注意: 在量化过程中,模型参数的值被量化为最接近的可表示整数,这可能会导致一些信息损失。因此,在使用量化技术时,需要平衡压缩效果和模型性能之间的权衡,并根据具体任务的需求来选择合适的量化精度。

二、推理显存计算

模型推理(inference)是指在已经训练好的模型上对新的数据进行预测或分类。推理阶段通常比训练阶段要求更低的显存,因为不涉及梯度计算和参数更新等大量计算。以下是计算模型推理时所需显存的一些关键因素:

  1. 模型结构: 模型的结构包括层数、每层的神经元数量、卷积核大小等。较深的模型通常需要更多的显存,因为每一层都会产生中间计算结果。
  2. 输入数据: 推理时所需的显存与输入数据的尺寸有关。更大尺寸的输入数据会占用更多的显存。
  3. 批处理大小BatchSize: 批处理大小是指一次推理中处理的样本数量。较大的批处理大小可能会增加显存使用,因为需要同时存储多个样本的计算结果。
  4. 数据类型DType: 使用的数据类型(如单精度浮点数、半精度浮点数)也会影响显存需求。较低精度的数据类型通常会减少显存需求。
  5. 中间计算: 在模型的推理过程中,可能会产生一些中间计算结果,这些中间结果也会占用一定的显存。

要估算模型推理时所需的显存,可以按照以下步骤:

  1. 模型加载: 计算模型中所有参数的大小,包括权重和偏差。
  2. 确定输入数据尺寸: 根据模型结构和输入数据大小,计算推理过程中每个中间计算结果的大小。
  3. 选择批次大小: 考虑批处理大小和数据类型对显存的影响。
  4. 计算显存大小: 将模型参数大小、中间计算结果大小和额外内存需求相加,以得出总显存需求或者使用合适的库或工具计算出推理过程中所需的显存。

通常情况下,现代深度学习框架(如TensorFlow、PyTorch等)提供了用于推理的工具和函数,可以帮助您估算和管理模型推理时的显存需求。

以 Llama-2-7b-hf 为例

 

  • 因为全精度模型参数是float32类型, 占用4个字节,粗略计算:1b(10亿)个模型参数,约占用4G显存(实际大小:10^9 * 4 / 1024^3 \~= 3.725 GB),那么LLaMA的参数量为7b,那么加载模型参数需要的显存为:3.725 * 7 \~= 26.075 GB
  • 如果您的显存不足32GB,那么可以设置半精度的FP16/BF16来加载,每个参数只占2个字节,所需显存就直接减半,只需要约13GB。虽然模型效果会因精度损失而略微降低,但一般在可接受范围。
  • 如果您的显存不足16GB,那么可以采用int8量化后,显存再减半,只需要约6.5GB,但是模型效果会更差一些。
  • 如果您的显存不足8GB,那么只能采用int4量化,显存再减半,只需要约3.26GB。
    完美运行、成功上车

注意: 上述是加载模型到显存所需大小,在模型的推理过程中,可能会产生一些中间计算结果,这些中间结果也会占用一定的显存,所以显存大小不能刚好是参数量的大小,不然就会OOM。

自我实践1:使用 RTX A6000 显卡(50GB显存)进行 70B 的 int4 量化模型部署,可正常运行。

三、训练显存计算

模型训练(train)是指在给定训练数据集的基础上,通过优化算法调整模型的参数,使其能够更好地适应训练数据,并在未见过的数据上表现出良好的泛化能力。训练阶段通常比推理阶段要求更多的显存,因为涉及梯度计算和参数更新等大量计算。以下是计算模型推理时所需显存的一些关键因素:
1.模型权重
模型权重是模型参数中的一部分,通常是指神经网络中连接权重(weights)。这些权重决定了输入特征与网络层之间的连接强度,以及在前向传播过程中特征的传递方式。所以模型

2.梯度

在训练过程中,计算梯度用于更新模型参数。梯度与模型参数的维度相同。

3.优化器参数
一些优化算法(如带有动量的优化器)需要保存一些状态信息,以便在每次更新时进行调整。这些状态信息也会占用一定的显存。比如:

  • 采用 AdamW 优化器:每个参数占用8个字节,需要维护两个状态。意味着优化器所使用的显存量是模型权重的 2 倍;
  • 采用 经过 bitsandbytes 优化的 AdamW 优化器:每个参数占用2个字节,相当于权重的一半;
  • 采用 SGD 优化器:占用显存和模型权重一样。

4.输入数据和标签
训练模型需要将输入数据和相应的标签加载到显存中。这些数据的大小取决于每个批次的样本数量以及每个样本的维度。

5.中间计算
在前向传播和反向传播过程中,可能需要存储一些中间计算结果,例如激活函数的输出、损失值等。

6.临时缓冲区
在计算过程中,可能需要一些临时缓冲区来存储临时数据,例如中间梯度计算结果等。减少中间变量也可以节省显存,这就体现出函数式编程语言的优势了。

7.硬件和依赖库的开销
显卡或其他硬件设备以及使用的深度学习框架在进行计算时也会占用一些显存。

以 Llama-2-7b-hf 为例
  • 数据类型:Int8
  • 模型参数: 7B * 1 bytes = 7GB
  • 梯度:同上7GB
  • 优化器参数: AdamW 2倍模型参数 7GB * 2 = 14GB
  • LLaMA的架构(hidden\_size= 4096, intermediate\_size=11008, num\_hidden\_lavers= 32, context.length = 2048),所以每个样本大小:(4096 + 11008) * 2048 * 32 * 1byte = 990MB
  • A100 (80GB RAM)大概可以在int8精度下BatchSize设置为50
  • 综上总现存大小:7GB + 7GB + 14GB + 990M * 50 \~= 77GB

Llama-2-7b-hf模型Int8推理由上个章节可得出现存大小6.5GB, 由此可见,模型训练需要的显存是至少推理的十几倍

备注:模型训练所需GPU显存是本地笔记本所不能完成的,但是我们一般正常使用模型的预测推理服务还是没多大问题的

显存的总占用可以通过将上述各部分的大小相加来计算。在实际应用中,需要根据模型结构、数据批次大小、优化算法等因素来估计和管理显存的使用,以防止内存不足导致训练过程中断。使用一些工具和库(如TensorFlow、PyTorch等)可以帮助您监控和管理显存的使用情况。实际影响显存占用的因素还有很多,所以只能粗略估计个数量级。

监听显卡,每 1 秒刷新一次:watch -n -1 -d nvidia-smi

四、结论

模型推理服务部署GPU配置推荐如下:

 

了解了模型训练、模型推理时显存计算情况后,优化的思路方向也就有了,比如:使用当前比较主流的一些分布式计算框架 DeepSpeed、Megatron 等,都在降低显存方面做了很多优化工作,比如:量化、模型切分、混合精度计算、Memory Offload 等,后续再给大家分享,敬请期待~

五、版权说明

转载自智源社区老刘说NLP

更多技术文档请访问[365文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/144290.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码静态测试工具之cppcheck

cppcheck简介 Cppcheck is an analysis tool for C/C code. It provides unique code analysis to detect bugs and focuses on detecting undefined behaviour and dangerous coding constructs. The goal is to detect only real errors in the code, and generate as few f…

AIGC实战——变分自编码器(Variational Autoencoder, VAE)

AIGC实战——变分自编码器 0. 前言1. 变分自编码器1.1 基本原理1.2 编码器 2. 构建VAE编码器2.1 Sampling 层2.2 编码器2.3 损失函数2.4 训练变分自编码器 3. 变分自编码器分析小结系列链接 0. 前言 我们已经学习了如何实现自编码器,并了解了自编码器无法在潜空间中…

React-Router源码分析-History库

history源码 history 在 v5 之前使用单独的包, v6 之后再 router 包中单独实现。 history源码 Action 路由切换的动作类型,包含三种类型: POPREPLACEPUSH Action 枚举: export enum Action {Pop "POP",Push &quo…

OCR转换技巧:如何避免图片转Word时出现多余的换行?

在将图片中的文字识别转换为Word文档时,我们很多时候时会遇到识别内容的一个自然段还没结束就换行的问题,这些就是我们常说的多余换行的问题。为什么会产生这个问题呢?主要是由于OCR返回的识别结果是按图片上的文字换行而换行,而不…

高并发架构设计(三大利器:缓存、限流和降级)

引言 高并发背景 互联网行业迅速发展,用户量剧增,系统面临巨大的并发请求压力。 软件系统有三个追求:高性能、高并发、高可用,俗称三高。三者既有区别也有联系,门门道道很多,全面讨论需要三天三夜&#…

web3资讯及远程工作

各位如果想了解区块链相关的消息可以通过如下网址了解,里面还会有相关职位招聘(包括远程工作),还可以在里面进行发帖,进入即可获得1000积分,后期可以兑换一些礼品Cryptosquare

如何检查 Docker 和 Kubernetes 是否可以访问外部网络,特别是用于拉取镜像的仓库?

要检查 Docker 和 Kubernetes 是否可以访问外部网络,尤其是用于拉取容器镜像的仓库,您可以按照以下步骤进行: 1. 检查节点的网络连接 首先,您需要确保 Kubernetes 节点能够访问外部网络。这可以通过在节点上执行 ping 命令来测试…

2023 年 数维杯(B题)国际大学生数学建模挑战赛 |数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时,你是否曾经感到茫然无措?作为2021年美国大学生数学建模比赛的O奖得主,我为大家提供了一套优秀的解题思路,让你轻松应对各种难题。 让我们来看看数维杯(B题)! …

一文看懂Spark中Cache和CheckPoint的区别

目录 循循渐进理解使用Cache或者PersistCheckPoint缓存和CheckPoint的区别 循循渐进理解 wc.txt数据 hello java spark hadoop flume kafka hbase kafka flume hadoop看下面代码会打印多少条-------------------------(RDD2) import org.apache.spark.rdd.RDD import org.ap…

Jmeter- Beanshell语法和常用内置对象(网络整理)

在利用jmeter进行接口测试或者性能测试的时候,我们需要处理一些复杂的请求,此时就需要利用beanshell脚本了,BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法,所以它和java是可以无缝衔接的。beans…

RK3588平台开发系列讲解(摄像头篇)USB摄像头驱动分析

🚀返回专栏总目录 文章目录 一. USB摄像头基本知识1.1 内部逻辑结构1.2 描述符实例解析二. UVC驱动框架2.1、设备枚举过程2.2、数据传输过程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 USB摄像头驱动位于 drivers\media\usb\uvc\uvc_driver.c ,我们本篇重点看下…

移动机器人路径规划(二)--- 图搜索基础,Dijkstra,A*,JPS

目录 1 图搜索基础 1.1 机器人规划的配置空间 Configuration Space 1.2 图搜索算法的基本概念 1.3 启发式的搜索算法 Heuristic search 2 A* Dijkstra算法 2.1 Dijkstra算法 2.2 A*&&Weighted A*算法 2.3 A* 算法的工程实践中的应用 3 JPS 1 图搜索基础 1.1…

AD教程 (十六)常用PCB封装的直接调用

AD教程 (十六)常用PCB封装的直接调用 打开已经做好的PCB文件 点击设计,生成PCB库,会自动把PCB里所用到的所有封装,全部自动生成 CtrlA 将所有元器件的封装全部选中(或者只选中所需要的)&#x…

TikTok与心灵成长:娱乐与启发并重

社交媒体已成为我们生活的一部分,其中TikTok以其短视频内容和创新性而闻名。然而,TikTok不仅仅是一个娱乐平台,它还具有潜力成为心灵成长的有力工具。本文将探讨TikTok如何在娱乐与启发之间取得平衡,以促进心灵成长和积极影响。 娱…

IntelliJ IDEA启动一个普通的java web项目的配置

原创/朱季谦 这是我很久以前刚开始用IntelliJ IDEA时记录的笔记,应该是五年前的一篇笔记了。正好赶上最近离职了,可以有比较多的时间把以前的记录整理一下,可以让刚接触到IntelliJ IDEA的童鞋学习如何在IntelliJ IDEA引入一个单机版的jar形式…

蓝桥杯 冒泡排序

冒泡排序的思想 冒泡排序的思想是每次将最大的一下一下移动到最右边,然后将最右边这个确定下来。 再来确定第二大的,再确定第三大的… 对于数组a[n],具体来说,每次确定操作就是从左往右扫描,如果a[i]>a[i1],我们将…

Android问题笔记四十五:解决SeekBar操作thumb周围产生的圆形阴影/灰色阴影/白色圆圈的解决办法

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列点击跳转>ChatGPT和AIGC 👉关于作者 专…

如何在Ubuntu 23.10部署KVM并创建虚拟机?

正文共:1114 字 21 图,预估阅读时间:2 分钟 我们之前对OpenStack醉过一次简单介绍(什么是OpenStack?),OpenStack本身是一个云管理平台,它本身并不提供虚拟化功能,而是依赖…

第二证券:今日投资前瞻:小米汽车引关注 全球风光有望持续高速发展

昨日,两市股指盘中轰动上扬,深成指、创业板指一度涨超1%。到收盘,沪指涨0.55%报3072.83点,深成指涨0.72%报10077.96点,创业板指涨0.53%报2015.36点,北证50指数涨2.64%;两市算计成交9900亿元&…

JVM——类加载器(JDK8及之前,双亲委派机制)

目录 1.类加载器的分类1.实现方式分类1.虚拟机底层实现2.JDK中默认提供或者自定义 2.类加载器的分类-启动类加载器3.类加载器的分类-Java中的默认类加载器4.类加载器的分类-扩展类加载器5.类加载器的分类-类加载器的继承 2.类加载器的双亲委派机制 类加载器(ClassLo…