一文讲清楚大模型涉及到的精度:FP32、TF32、FP16、BF16、FP8、FP4、NF4、INT8

来自:苍牙的AI世界

大模型的训练和推理,经常涉及到精度的概念,种类很多,而且同等精度级别下,还分不同格式,网上没看到一篇能够介绍全面的,这里梳理总结一份全面的介绍。

整体介绍

浮点数精度:双精度(FP64)、单精度(FP32、TF32)、半精度(FP16、BF16)、8位精度(FP8)、4位精度(FP4、NF4)

量化精度:INT8、INT4 (也有INT3/INT5/INT6的)

另外,实际使用场景中,还有多精度和混合精度的概念

什么是精度

假设你每秒钟赚到的钱是1块钱,那一个月的收入是1*60*60*24*30=216000,如果每秒钟赚到1块1呢,那一个月的收入是237600,就一个1毛钱的小数点,让你月收入少了1万多,这就是精度不同导致的差异。

另外一个典型的例子是π,常用3.14表示,但是如果要更高精度,小数点后面可以有无数位。

当然,这些都是数学里面的精度概念,在计算机里面,浮点数的精度,跟存储方式有关,占用的bit越多,精度越高。

为什么要有这么多精度

因为成本和准确度。

都知道精度高肯定更准确,但是也会带来更高的计算和存储成本。较低的精度会降低计算精度,但可以提高计算效率和性能。所以多种不同精度,可以让你在不同情况下选择最适合的一种。

双精度比单精度表达的更精确,但是存储占用多一倍,计算耗时也更高,如果单精度足够,就没必要双精度。

不同的浮点数精度

在计算机中,浮点数存储方式,由由符号位(sign)、指数位(exponent)和小数位(fraction)三部分组成。符号位都是1位,指数位影响浮点数范围,小数位影响精度。

[FP精度]

Floating Point,是最原始的,IEEE定义的标准浮点数类型。由符号位(sign)、指数位(exponent)和小数位(fraction)三部分组成。

FP64,是64位浮点数,由1位符号位,11位指数位和52位小数位组成。

0d46940c2d3a58707b475969a05332f0.png

FP32、FP16、FP8、FP4都是类似组成,只是指数位和小数位不一样。

但是FP8和FP4不是IEEE的标准格式。

FP8是2022年9月由多家芯片厂商定义的,论文地址:https://arxiv.org/abs/2209.05433

FP4是2023年10月由某学术机构定义,论文地址:https://arxiv.org/abs/2310.16836

FP8格式有两种变体,E4M3(4位指数和3位尾数)和E5M2(5位指数和2位尾数)

符号位、指数位、小数位的位数如下表所示:

格式符号位指数位小数位总位数
FP641115264
FP32182332
FP16151016
FP8 E4M31438
FP8 E5M21528
FP41214

[特殊精度]

TF32,Tensor Float 32,英伟达针对机器学习设计的一种特殊的数值类型,用于替代FP32。首次在A100 GPU中支持。

由1个符号位,8位指数位(对齐FP32)和10位小数位(对齐FP16)组成,实际只有19位。在性能、范围和精度上实现了平衡。

3a0604cd49bb903b770f1f5852cbc27f.png

python中查看是否支持:

import torch
//是否支持tf32
torch.backends.cuda.matmul.allow_tf32
//是否允许tf32,在PyTorch1.12及更高版本中默认为False
torch.backends.cudnn.allow_tf32‍
BF16,Brain Float 16,由Google Brain提出,也是为了机器学习而设计。由1个符号位,8位指数位(和FP32一致)和7位小数位(低于FP16)组成。所以精度低于FP16,但是表示范围和FP32一致,和FP32之间很容易转换。

9cb6610d0c6f7f5c40e963772df7268a.png

在 NVIDIA GPU 上,只有 Ampere 架构以及之后的GPU 才支持。

python中查看是否支持:

import transformers
transformers.utils.import_utils.is_torch_bf16_gpu_available()
NF4,4-bit NormalFloat,一种用于量化的特殊格式,于23年5月由华盛顿大学在QLoRA量化论文中提出,论文地址:https://arxiv.org/abs/2305.14314

NF4是建立在分位数量化技术的基础之上的一种信息理论上最优的数据类型。把4位的数字归一化到均值为 0,标准差为 [-1,1] 的正态分布的固定期望值上,知道量化原理的应该就会理解。

FP精度和特殊精度加上,位数总结如下表

格式符号位指数位小数位总位数
FP641115264
FP32182332
TF32181019
BF1618716
FP16151016
FP8 E4M31438
FP8 E5M21528
FP41214

多精度和混合精度

多精度计算,是指用不同精度进行计算,在需要使用高精度计算的部分使用双精度,其他部分使用半精度或单精度计算。

混合精度计算,是在单个操作中使用不同的精度级别,从而在不牺牲精度的情况下实现计算效率,减少运行所需的内存、时间和功耗

量化精度

一般情况下,精度越低,模型尺寸和推理内存占用越少,为了尽可能的减少资源占用,量化算法被发明。FP32占用4个字节,量化为8位,只需要1个字节。

常用的是INT8和INT4,也有其他量化格式(6位、5位甚至3位)。虽然资源占用减少,但是推理结果差不了多少。

af106bc3146b8f9d2755d6c5beb8bc4a.png

量化算法这里不详细展开。


备注:昵称-学校/公司-方向/会议(eg.ACL),进入技术/投稿群

2d46fb9c4b8b9286ea0b15c66e3b5b39.png

id:DLNLPer,记得备注呦

### 不同数值精度类型的定义 #### 单精度浮点数 (FP32) 单精度浮点数(FP32),即 Single-Precision Floating-Point,是一种使用32位表示的浮点数格式。它由1位符号位、8位指数位和23位小数位构成[^3]。 ```cpp // C++ 示例:声明一个 FP32 类型变量 float fp32_var = 3.14f; ``` #### TensorFloat-32 是一种专为加速人工智能工作负载设计的数据类型,在某些硬件上可以提供更高的性能而不需要更改软件。相比 FP32, TF32 减少了尾数长度从而提高了吞吐量并减少了内存带宽需求[^1]。 #### 半精度浮点数 (FP16) 半精度浮点数(FP16)采用16位来表示浮点数,具体分配为1位符号位、5位指数位以及10位小数位。这种较低的比特率使得数据传输更快更高效,尤其适合于图形处理单元(GPU)上的矩阵运算等场景[^2]。 ```python import numpy as np fp16_var = np.float16(3.14) print(fp16_var) ``` #### Brain Float-16 (BF16) Brain Float-16 或者简称 BF16 是另一种形式的低精度浮点数表达方式,同样占用16个二进制位;不过相比于标准 FP16 它拥有更大的动态范围因为采用了更多位给指数部分而不是分数部分。 #### 浮点数8 (FP8), 浮点数4 (FP4),NVIDIA 自定义四舍五入到最接近整数(NF4) 这些是非常规或实验性的短字节宽度浮点编码方案,主要用于特定领域如神经网络推理优化等领域内探索极致效率下的近似计算能力。目前它们的应用还比较有限,并且主要存在于研究阶段或是专用设备支持下。 #### 整数量化 (INT8INT4) 当涉及到量化技术时,则会进一步减少所需存储空间及功耗开销。例如 INT8 就是指利用八个二进制位去逼近原生实数值的过程——这通常发生在模型压缩之后用于部署至边缘侧终端节点之上。同样的道理适用于更加激进版本比如 INT4 ——仅需四个bit即可完成一次转换操作。 ### 应用场景概述 对于大多数机器学习任务而言,默认情况下会选择较高精度FP32 来确保准确性不受损失。然而随着对速度/能耗敏感度增加,人们开始尝试更低级别的替代品: - **训练过程** 中为了加快收敛速度可能会考虑切换成 FP16/BF16; - **推断环节** 则可能倾向于采用 INT8 进行快速评估而不显著牺牲预测质量; - 特殊场合下甚至会出现针对某一类算法定制化的极窄幅值域表现形式像上述提到过的 FP8/Fp4/NF4 等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值