网站需要做实名认证如何做,erp系统登录平台,电子商城采购平台官网,云端设计高端网站建设文章目录 0. 前言1. 数据的存储方式2. 不同数据类型介绍2.1 深度学习中常用的数据类型2.2 BF16 类型的优势2.3 不同数据类型的使用场景 0. 前言
相比于 CPU#xff0c;GPU 在架构设计时将更多的晶体管用于数据处理#xff0c;而不是数据缓存和流量控制#xff0c;因此可以高… 文章目录 0. 前言1. 数据的存储方式2. 不同数据类型介绍2.1 深度学习中常用的数据类型2.2 BF16 类型的优势2.3 不同数据类型的使用场景 0. 前言
相比于 CPUGPU 在架构设计时将更多的晶体管用于数据处理而不是数据缓存和流量控制因此可以高度实现并行计算。具体可以参考 GPU 并行计算入门
由于深度学习是基于大量矩阵运算实现的因此我们往往使用 GPU 训练深度学习网络。GPU 的计算能力和显存大小决定了计算速度和可运行的网络的大小但除了 GPU 本身的性能外网络训练/推理的性能还与我们使用的数据类型有关。在大模型时代低精度和混合精度的使用非常常见。
1. 数据的存储方式
float 和 double 类型的数据在内存中以二进制方式存储由三部分组成
符号位 SSign: 0 代表正数1 代表负数指数位 EExponent: 用于存储科学计数法中的指数部分决定了数据的范围尾数位 MMantissa: 用于存储尾数小数部分决定了数据的精度
int 类型只包括符号位和指数位没有尾数位。
如 float 9.125 在计算机中分别按照整数和尾数的二进制进行存储9 的二进制为 10010.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)S∗2E−15∗(121024M)
因此 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)0∗230−15∗(110241023)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)1∗230−15∗(110241023)−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 E00000 E00000时FP16 可以表示的数据大小为 ( − 1 ) S ∗ 2 1 − 15 ∗ ( 0 M 2 1024 ) (-1)^S*2^{1-15}*(0\frac{M}{2^{1024}}) (−1)S∗21−15∗(021024M) E 11111 E11111 E11111时若 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)0∗21−15∗(110240)6.10×10−5
FP16 的数值精度为 0.001即两个不同 FP16 数值的最小间隔为 0.001这是由于十进制和二进制之间的数值转换决定的具体分析可见 LLM大模型之精度问题FP16FP32BF16详解与实践
用 PyTorch 验证一下
import torch
print(torch.finfo(torch.float16))
# finfo(resolution0.001, min-65504, max65504, eps0.000976562, smallest_normal6.10352e-05, tiny6.10352e-05, dtypefloat16)本节参考
float在内存中的存储
LLM大模型之精度问题FP16FP32BF16详解与实践
彻底搞懂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} 10−6大部分CPU/GPU/深度学习框架中默认使用FP32FP32可以作为精度 baselineFP16161510 − 65504 -65504 −65504 ~ 65504 65504 65504 1 0 − 3 10^{-3} 10−3TF32191810 − 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} 10−3TF32 的 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} 10−2BF16 以 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 1Int1616115 − 32768 -32768 −32768 ~ 32767 32767 32767 1 1 1Int8817 − 128 -128 −128 ~ 127 127 127 1 1 1
PyTorch验证
import torch
print(torch.finfo(torch.float32))
# finfo(resolution1e-06, min-3.40282e38, max3.40282e38, eps1.19209e-07, smallest_normal1.17549e-38, tiny1.17549e-38, dtypefloat32)
print(torch.finfo(torch.float16))
# finfo(resolution0.001, min-65504, max65504, eps0.000976562, smallest_normal6.10352e-05, tiny6.10352e-05, dtypefloat16)
print(torch.finfo(torch.bfloat16))
# finfo(resolution0.001, min-65504, max65504, eps0.000976562, smallest_normal6.10352e-05, tiny6.10352e-05, dtypefloat16)
print(torch.iinfo(torch.int32))
# iinfo(min-2.14748e09, max2.14748e09, dtypeint32)
print(torch.iinfo(torch.int16))
# iinfo(min-32768, max32767, dtypeint16)
print(torch.iinfo(torch.int8))
# iinfo(min-128, max127, dtypeint8)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 wnewwold−lr⋅grad 由于梯度 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, 两者之间的转换是非常直接其实现电路也会非常简单。相比于 FP16BF16的使用能有效的降低电路的面积。
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