深度学习中的数据类型介绍:FP32, FP16, TF32, BF16, Int16, Int8 ...

文章目录

    • 0. 前言
    • 1. 数据的存储方式
    • 2. 不同数据类型介绍
      • 2.1 深度学习中常用的数据类型
      • 2.2 BF16 类型的优势
      • 2.3 不同数据类型的使用场景

0. 前言

相比于 CPU,GPU 在架构设计时将更多的晶体管用于数据处理,而不是数据缓存和流量控制,因此可以高度实现并行计算。具体可以参考 GPU 并行计算入门

由于深度学习是基于大量矩阵运算实现的,因此我们往往使用 GPU 训练深度学习网络。GPU 的计算能力和显存大小决定了计算速度和可运行的网络的大小,但除了 GPU 本身的性能外,网络训练/推理的性能还与我们使用的数据类型有关。在大模型时代,低精度和混合精度的使用非常常见。

1. 数据的存储方式

float 和 double 类型的数据在内存中以二进制方式存储,由三部分组成:

  • 符号位 S(Sign): 0 代表正数,1 代表负数
  • 指数位 E(Exponent): 用于存储科学计数法中的指数部分,决定了数据的范围
  • 尾数位 M(Mantissa): 用于存储尾数(小数)部分,决定了数据的精度

int 类型只包括符号位和指数位,没有尾数位。

如 float 9.125 在计算机中分别按照整数和尾数的二进制进行存储,9 的二进制为 1001,0.125 的二进制为 0.001;所以 9.125 表示为 1001.001,其二进制的科学计数法表示为 1.001001 × 2 3 1.001001 \times 2^3 1.001001×23

在计算机中,任何一个数都可以表示为 1. x x x × 2 n 1.xxx \times 2^n 1.xxx×2n 的形式,其中 n n n 是指数位, x x x xxx xxx 是尾数位。

指数位决定了该数据类型的数值动态范围:指数位越多,可表示的数值范围越大。
尾数位决定了该数据类型的数值精度:尾数位越多,可表示的数值精度越高。

下面是 FP16 和 FP32 (float) 的存储示例图:
        

        

以 FP16为例,其指数位 E 为 5 bits,由于 00000 和 11111 是特殊数据,所以 E 的范围为 00001~11110,即 1~30;尾数位 M 为 10 bits,范围为 0~1023

(1)计算 FP16 可以表示的数据范围

FP16 可以表示的数据大小为: ( − 1 ) S ∗ 2 E − 15 ∗ ( 1 + M 2 1024 ) (-1)^S*2^{E-15}*(1+\frac{M}{2^{1024}}) (1)S2E15(1+21024M)

因此 FP16 可以表示的最大的正数为: 0   11110   1111111111 = ( − 1 ) 0 ∗ 2 30 − 15 ∗ ( 1 + 1023 1024 ) = 65504 0 \ 11110 \ 1111111111=(-1)^0*2^{30-15}*(1+\frac{1023}{1024})=65504 0 11110 1111111111=(1)023015(1+10241023)=65504

可以表示的最小的负数为: 1   11110   1111111111 = ( − 1 ) 1 ∗ 2 30 − 15 ∗ ( 1 + 1023 1024 ) = − 65504 1 \ 11110 \ 1111111111=(-1)^1*2^{30-15}*(1+\frac{1023}{1024})=-65504 1 11110 1111111111=(1)123015(1+10241023)=65504

所以 FP16 可以表示的数据范围为 [ − 65504 , 65504 ] [-65504,65504] [65504,65504]

与 FP16 相比,FP16 可以表示的数据范围为 [ − 3.4 × 1 0 38 , 3.4 × 1 0 38 ] [-3.4\times10^{38},3.4\times10^{38}] [3.4×1038,3.4×1038]

(2)特殊情况分析

在指数位 E 为 00000 或 11111 时:

  • E = 00000 E=00000 E=00000时,FP16 可以表示的数据大小为: ( − 1 ) S ∗ 2 1 − 15 ∗ ( 0 + M 2 1024 ) (-1)^S*2^{1-15}*(0+\frac{M}{2^{1024}}) (1)S2115(0+21024M)
  • E = 11111 E=11111 E=11111时,若 M 全为 0,表示 ± inf;若 M 不全为 0,表示 NAN

(3)分析 FP16 的数值精度

由于尾数位的限制,任何数据类型表示的数都是有精度的,即 FP16 并不是可以表示 [ − 65504 , 65504 ] [-65504,65504] [65504,65504] 内的任意数字。

FP16 可以表示的最小的正数为: 0   00001   0000000000 = ( − 1 ) 0 ∗ 2 1 − 15 ∗ ( 1 + 0 1024 ) = 6.10 × 1 0 − 5 0 \ 00001 \ 0000000000 =(-1)^0*2^{1-15}*(1+\frac{0}{1024})=6.10\times10^{-5} 0 00001 0000000000=(1)02115(1+10240)=6.10×105

FP16 的数值精度为 0.001,即两个不同 FP16 数值的最小间隔为 0.001,这是由于十进制和二进制之间的数值转换决定的,具体分析可见 LLM大模型之精度问题(FP16,FP32,BF16)详解与实践

用 PyTorch 验证一下:

import torch
print(torch.finfo(torch.float16))
# finfo(resolution=0.001, min=-65504, max=65504, eps=0.000976562, smallest_normal=6.10352e-05, tiny=6.10352e-05, dtype=float16)

本节参考:

float在内存中的存储

LLM大模型之精度问题(FP16,FP32,BF16)详解与实践

彻底搞懂float16与float32的计算方式

2. 不同数据类型介绍

最早的 GPU 默认使用 FP32 类型进行运算,但随着模型越来越大,FP32 类型占内存/显存资源大且运算速度慢的问题逐渐暴露了出来。为了降低模型的大小使得在固定显存的 GPU 上可以运行更大(参数量更多)的模型,且提升模型的训练和推理速度,各种低精度的数据类型被提出。

2.1 深度学习中常用的数据类型

深度学习中常用的数据类型如下:

数据类型bits符号位 S指数位 E尾数位 M数值范围数值精度设计原理说明
FP32321823 − 3.4 × 1 0 38 -3.4\times10^{38} 3.4×1038 ~ 3.4 × 1 0 38 3.4\times10^{38} 3.4×1038 1 0 − 6 10^{-6} 106大部分CPU/GPU/深度学习框架中默认使用FP32,FP32可以作为精度 baseline
FP16161510 − 65504 -65504 65504 ~ 65504 65504 65504 1 0 − 3 10^{-3} 103
TF32191810 − 3.4 × 1 0 38 -3.4\times10^{38} 3.4×1038 ~ 3.4 × 1 0 38 3.4\times10^{38} 3.4×1038 1 0 − 3 10^{-3} 103TF32 的 E 与 FP32 相同,具有与 FP32 相同的数值范围;M 与 FP16 相同,具有与 FP16 相同的数值精度。TF32 (TensorFloat) 是 Nvidia 在 Ampere 架构的 GPU 上推出的用于 TensorCore 的数据格式,在 A100 上使用 TF32 的运算速度是在 V100 上使用 FP32 CUDA Core 运算速度的 8 倍。
BF1616187 − 3.39 × 1 0 38 -3.39\times10^{38} 3.39×1038 ~ 3.39 × 1 0 38 3.39\times10^{38} 3.39×1038 1 0 − 2 10^{-2} 102BF16 以 16bits 存储,但其 E 与 FP32 一致,因此其数值范围与 FP32 一致;即其数值范围大于 FP32,但精度低于 FP16BF16 (bfloat16, brain floating point 16)是由Google Brain开发的,是一种最适合大模型训练的数据类型,但目前只适配于 Ampere 架构的 GPU(如A100)。
Int3232131 − 2.15 × 1 0 9 -2.15\times10^{9} 2.15×109 ~ 2.15 × 1 0 9 2.15\times10^{9} 2.15×109 1 1 1
Int1616115 − 32768 -32768 32768 ~ 32767 32767 32767 1 1 1
Int8817 − 128 -128 128 ~ 127 127 127 1 1 1

PyTorch验证:

import torch
print(torch.finfo(torch.float32))
# finfo(resolution=1e-06, min=-3.40282e+38, max=3.40282e+38, eps=1.19209e-07, smallest_normal=1.17549e-38, tiny=1.17549e-38, dtype=float32)
print(torch.finfo(torch.float16))
# finfo(resolution=0.001, min=-65504, max=65504, eps=0.000976562, smallest_normal=6.10352e-05, tiny=6.10352e-05, dtype=float16)
print(torch.finfo(torch.bfloat16))
# finfo(resolution=0.001, min=-65504, max=65504, eps=0.000976562, smallest_normal=6.10352e-05, tiny=6.10352e-05, dtype=float16)
print(torch.iinfo(torch.int32))
# iinfo(min=-2.14748e+09, max=2.14748e+09, dtype=int32)
print(torch.iinfo(torch.int16))
# iinfo(min=-32768, max=32767, dtype=int16)
print(torch.iinfo(torch.int8))
# iinfo(min=-128, max=127, dtype=int8)

2.2 BF16 类型的优势

BF16 类型的优势:

  • BF16 只有 2bytes 的内存,但其数值范围与 4bytes 的 FP32 相同。
    在深度学习领域,数值范围的作用远高于数值精度;即数据类型的指数位的作用大于尾数位的作用。采用梯度下降法的网络权重的更新方式为: w n e w = w o l d − l r ⋅ g r a d w_{new}=w_{old}-lr \cdot grad wnew=woldlrgrad 由于梯度 g r a d grad grad 和学习率 l r lr lr 通常较小,往往会出现很小的数值,因此必须使用能够表达较大范围的数据类型。使用 FP16时往往会出现 underflow(下溢)的情况,即小于 − 6.55 × 1 0 4 -6.55\times10^{4} 6.55×104 的数值被截断为 0 ,导致梯度无法更新。所以 BF16 具有比 FP16 更优异的性能。
  • BF16 与 FP32 的转换很容易。
    使用混合精度计算时,需要频繁得对 BF16/FP32 和 FP32 进行转换。BF16 基本上可以看作成一个“截断”版的 FP32, 两者之间的转换是非常直接,其实现电路也会非常简单。相比于 FP16,BF16的使用能有效的降低电路的面积。

2.3 不同数据类型的使用场景

对于不同的任务和使用场景,最适用的数据类型也是不同的。

(1)不用任务使用不同的数据类型

  • 例1:相比于目标检测,分类任务对于数据类型就没有那么敏感了,可能使用 FP16 和 Int8 获得的精度并没有差多少,但使用 Int8 能够显著提升训练和推理性能。
  • 例2:由于图像往往是 Int8 格式,因此在 CV 的推理任务中以 Int8 为主;但在 NLP任务中应以 FP16 为主。

(2)训练和推理的不同

  • FP32 往往只是作为精度基线 (baseline),比如要求使用 FP16 获得的精度达到 FP32 baseline 的 99% 以上。但通常不会使用 FP32 进行训练,尤其对于大模型来说。
  • 训练往往使用 FP16, BF16 和 TF32,以降低内存占用,缩写训练时间,降低训练资源(较少耗电)。
  • 推理 CV 任务以 Int8 为主,NLP任务以 FP16 为主,大模型可以使用 Int8/FP16 混合推理。

本节参考:int8/fp16/bf16/tf32在AI芯片中什么作用?【AI芯片】AI计算体系06

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于网站安全的一些讨论

互联网的普及和发展为企业和个人提供了巨大的机会,但同时也伴随着网络安全威胁的增加。网站被攻击是一个常见的问题,可能导致数据泄露、服务中断和声誉受损。在本文中,我们将探讨与网络安全紧密相关的因素,分析为什么网站容易受到…

基础课18——智能客服系统架构

1.基础设施层 基础设施主要包括以下几点: 1. 硬件设施:包括服务器、存储设备、网络设备等,这是整个系统运行的物理基础。 2. 软件设施:包括操作系统、数据库管理系统、自然语言处理(NLP)工具和机器学习算法等,这些是…

SSM之Spring注解式缓存Redis以及redies中的击穿,雪崩,穿的三种现象

⭐⭐ Redis专栏:Redis专栏 ⭐⭐ 个人主页:个人主页 目录 一.SSM整合Redis 1.2配制Spring-redis.xml文件 1.3 applicationContext.xml 1.4 配置redis的key生成策略 二.redis的注解式开发 2.1 redis的注解式是什么及其好处 2.2 redi…

Spring IoCDI入门

一:Spring IoC&DI概念 (1)Spring概念 💗Spring是包含了众多工具方法的IoC容器,是一个开源框架,让我们的开发更加简单 🌟Spring的两大核心和特点:IoC和AOP (2)IoC的介绍 1.概念 💗IoC: Inv…

EOCR-3E420,3EZ,3DE电机保护器与变频器配合使用的方法

上海韩施电气自动化设备有限公司提供 在工业现场中,电动机的起动与运行很多时候需要变频器参与其中,以达到降低电机维护成本、增加电机寿命的目的。采用变频器运转时,随着电机的加速相应提高频率和电压,起动电流被限制在 150%额定…

Android Studio 常见问题

一、Android Studio 创建项目后Gradle(构建)项目很慢问题解决 在使用Android Studio创建项目时,会自动从网上下载相关依赖。由于是访问国外服务器,会出现构建项目时下载依赖很慢的问题。为了解决该问题,需要在settings.gradle(或者settings.…

YOLOv8优化:block系列篇 | Neck系列篇 |可重参化EfficientRepBiPAN优化Neck

🚀🚀🚀本文改进: 可重参化EfficientRepBiPAN优化Neck 如何在YOLOv8下使用:1)结合neck; 🚀🚀🚀EfficientRepBiPAN在各个领域都有ying 🚀🚀🚀YOLOv8改进专栏:http://t.csdnimg.cn/hGhVK 学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定科研; 1.原理…

Linux 学习(CentOS 7)

CentOS 7 学习 Linux系统内核作者: Linux内核版本 内核(kernel)是系统的心脏,是运行程序和管理像磁盘和打印机等硬件设备的核心程序,它提供了一个在裸设备与应用程序间的抽象层。 Linux内核版本又分为稳定版和开发版,两种版本是相互关联&am…

EPLAN-P8软件技术分享文章

EPLAN公司成立于1984年德国。EPLAN最初的产品是基于DOS平台,然后经历了Windows3.1、Windows95、Windows98、Windows2000、Windows Vista等、Windows7、Windows8等平台发展历史。EPLAN是以电气设计为基础的跨专业的设计平台,包括电气设计、流体设计、仪表…

ubuntu20.04 安装cudnn

中文地址是.cn:cuDNN 历史版本 | NVIDIA 开发者 英文地址是.com:cuDNN 历史版本 | NVIDIA 开发者 1、下载cudnn:cudnn-local-repo-ubuntu2004-8.8.1.3_1.0-1_amd64.deb 解压并安装:sudo dpkg -i cudnn-local-repo-ubuntu2004-8.8…

【JMeter】定时器分类以及场景介绍

1. 定时器分类 固定定时器 作用:请求之间设置等待时间应用场景:查询商品列表后,去查看列表商品详情页。针对商品列表数据量比较大的,响应时间会比较长,就需要设置等待时间然后去查看商详 2.定时器的作用域&#xff1…

Qt QTableView排序

1.简介 在开发过程中,我们需要通过点击表头来对QTableView或QTreeView等一系列高级视图进行排序操作,以下是进行排序的步骤。 步骤: 首先创建了一个QStandardItemModel对象或者继承QAbstractTableModel类作为数据模型,并设置了…

6、Python控制流:if语句、for循环、while循环、循环控制语句

文章目录 Python控制流:if语句、for循环、while循环、循环控制语句if语句示例:for循环示例:while循环示例:循环控制语句示例:最佳实践Python控制流:if语句、for循环、while循环、循环控制语句 控制流是编程中的基础概念,它允许我们根据不同的条件执行不同的代码块,或者…

【软件工程】程序流程图之绘图工具和教程推荐

2023年11月6日,周一晚上 目录 绘图工具推荐教程推荐 绘图工具推荐 我推荐使用开源免费的draw.io要绘制程序流程图 draw.io网页版地址:Flowchart Maker & Online Diagram Software draw.io桌面版下载地址:GitHub - jgraph/drawio-desk…

Nodejs的安装以及配置(node-v12.16.1-x64.msi)

Nodejs的安装以及配置 1、安装 node-v12.16.1-x64.msi点击安装,注意以下步骤 本文设置nodejs的安装的路径:D:\soft\nodejs 继续点击next,选中Add to PATH ,旁边的英文告诉我们会把 环境变量 给我们配置好 当然也可以只选择 Nod…

[Kettle] Excel输入

Excel文件采用表格的形式,数据显示直观,操作方便 Excel文件采用工作表存储数据,一个文件有多张不同名称的工作表,分别存放相同字段或不同字段的数据 数据源 物理成绩(Kettle数据集2).xls https://download.csdn.net/download/H…

JQ完成模拟QQ好友分组案例(介绍JQ实现原理)

当我们写这个案例之前&#xff0c;需要引入好JQ文件&#xff0c;以防没有效果 这个案例的需求请看以下效果图 不能重复点击&#xff0c;只有删除掉之后才可以继续点击 效果图&#xff1a; 代码介绍&#xff1a; <!DOCTYPE html> <html lang"en"><h…

leetcode:2926. 平衡子序列的最大和 【树状数组维护最大前缀和】

题目链接 lc2926 题目描述 题目思路 定义b[i] nums[i] - i 目标是从b中找到一个非降子序列使得元素和最大 # b[i] nums[i] - i # 找到b的一个非降子序列使得元素和最大 # f[i]: 子序列最后一个数下标是i&#xff0c;对应的最大子序列 # f[i] max (max f[j], 0) nums[i] …

Qt利用VCPKG和CMake和OpenCV和Tesseract实现中英文OCR

文章目录 1. 开发平台2. 下载文件2.1 下载安装 OpenCV 库2.2 下载安装 Tesseract-OCR库2.3 下载训练好的语言包 3. CMakeLists.txt 内容4. Main.cpp4.1 中英文混合OCR 5. 在Qt Creator 中设置 CMake vcpkg5.1 在初始化配置文件里修改5.2 在构建配置里修改 说明&#xff1a;在Q…

FineReport----报表模板入门

FineReport----报表模板入门教程1 FineReport就一款类Excel操作界面的报表工具&#xff0c;通过拖拖拽拽简单实现报表制作&#xff0c;实现数据展示、数据查询、数据录入功能&#xff0c;并且支持图形多样化展示。 一、入门小例子 1. 打开设计器 启动FineReport设计器&…