人工智能算力FP32、FP16、TF32、BF16、混合精度解读

2024-08-29 13:12

本文主要是介绍人工智能算力FP32、FP16、TF32、BF16、混合精度解读,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

de94325234483a4035ca41ff58655cf0.jpeg 

彻底理解系列之:FP32、FP16、TF32、BF16、混合精度

   

随着大模型的涌现,训练和推理速度成为关键。为提升速度,需减小数据长度以降低存储和带宽消耗。为此,我专注学习并整理了各种精度细节,确保深入理解而非浅尝辄止。

1 从FP32说起

计算机处理数字类型包括整数类型和浮点类型,IEEE 754号标准定义了浮点类型数据的存储结构。一个浮点数由三部分组成:符号位、指数位和尾数位。其中,以最常见的FP32(Float Point 32)为例,其符号位占1位,指数位占8位,尾数位占23位 。

809215fe7bd4dc462be163a349bca6b9.jpeg

图1. FP32位数分配,来源[2]

  • Sign:最高位用1位表示符号位,1表示负数,0表示正数,记为S
  • Exponent:中间8位表示指数位,记为E
  • Mantissa:低位23位表示小数部分,记为M

我们以十进制数9.625为例,看看十进制和FP32二进制之间如何转换:

十进制--》二进制

先分为整数部分9和小数部分0.625。

将9转换为二进制1001,然后通过乘以2并取整数部分的方式得到0.625。接着,将剩余的小数部分0.625再乘以2并取整数部分,如此循环,最终得到0.101。将这两个结果相加,即1001.101,转换为二进制指数形式为1.001101 * 2^3。

根据IEEE 754标准,FP32的指数部分需要加上127以进行偏移,调整为3+127=130。对应的二进制表示为10000010,小数部分补齐至23位后,符号位为0。将这三部分组合起来,便得到了FP32的表示。

0 10000010 00110100000000000000000。

1a183ef532c880952d2b125992522465.jpeg

图2. FP32转换工具,来源[3]

二进制--》十进制

将二进制分为S、E、M三部分,将FP32转换为十进制的方法如下:

$S=B_2+B_1+...+B_0$

$E=G_2+G_1+...+G_0$

$M=P_2+P_1+...+P_0$

51d18df27372cf0a3749eb34374c8a6e.jpeg

文章内容经过优化后如下:
"其中,1.M表示小数部分的二进制表示。以S=0,E二进制10000010转为十进制为130为例,M为00110100000000000000000。去掉小数部分后面的无用零后,得到1.M实际上是二进制的1.001101,转换为十进制就是:×"

5a44f071dcb3fbbea50ad272c5f646d2.jpeg

顺利还原回了十进制数。

FP32搞清楚了,FP16、FP64类似,只是指数位和小数位的长度不一样:


2 模型训练中不同精度的问

降低存储负担:提高训练显存利用率至FP32,实现一半存储占用,从而在有限的GPU资源下训练更大模型或提高batch_size。

FP16和FP32都是深度学习中常用的数值表示方式。FP16是16位浮点数表示法,即半精度浮点数,用一个16位的数值来表示实数,包括1位符号位、5位指数位和10位尾数位。FP16的精度比FP32低,但计算速度快,内存占用小,因此在深度学习中常用于加速训练和推理。FP32是32位浮点数表示法,即单精度浮点数,用一个32位的数值来表示实数,包括1位符号位、8位指数位和23位尾数位。FP32是深度学习中最常用的数值表示方式之一,因为它提供了足够的精度和计算速度,同时也相对容易实现。

但是,是否意味着我们都使用FP16就行了呢?当然不是。主要原因是位数少同时有两个劣势:(1)精度较低;(2)存储空间较大。

  1. 位数少时精度比位数多时低,可能导致准确度不够;
  2. 位数少时表示的范围比位数多时要小,可能导致数据溢出,装不下了。

先看看精度问题,以下是用FP64、FP32、FP16表示1/3时不同的精度:

5b9e51110330d61a88183b8c5fbc71ad.jpeg

提高精度,确保数据表示和计算的准确性,使模型训练拟合出的参数更精确。这取决于我们对模型精度的具体要求。

186251574ad67f11825cbcf299d8c248.jpeg

我们用一个大数10^6看看二者能否表示:

77d15f0debcce87f6987dc66035d3a6c.jpeg

3混合精度

c325ac273d2f270636496b464420fe54.jpeg

图3. 混合精度使用流程,来源[1]

  1. 把神经网络权重参数由初始化的FP32转为FP16;
  2. 用FP16进行前向和后向计算,并进行梯度计算;
  3. 把FP16的梯度转为FP32;
  4. 使用FP32的梯度和学习率learning rate相乘;
  5. 使用FP32更新网络权重,得到FP32的更新后的权重。

使用FP32更新权重的时候,梯度乘上学习率后一般数值都比较小,因此使用FP32能防止精度不够。

在混合精度训练中,采用"损失缩放"技术以防止数值过小导致精度损失。首先,将损失扩大一倍,使其位于FP16可表示范围内;然后进行反向计算;最后,将梯度缩小相同的倍数,以确保最终数值的准确性。

DistilBERT模型在电影情感分类任务上进行了微调,通过比较FP32、FP16和混合使用性能及准确率,展示了其优越性。

0e3ec639240e06cf538857166c86ae2e.jpeg

图4. FP32、FP16和混合精度训练对比,来源[1]

如图4所示,混合精度训练时间与FP16相当,约为FP32的1/3,且使用的存储空间介于二者之间。尽管预测准确率与FP32相近,甚至更高,但作者认为这可能是因为正则化的影响。相较之下,FP16的预测准确率较低,可能是由于训练过程中数据溢出导致模型失准。

4BF16、TF32

FP16的指数和尾数限制了其可表示的数据范围,因此谷歌为深度学习引入了BF16格式。BF16与FP16共享相同的16位总长度,但将指数位从5位扩展至8位,小数位数则缩短至7位,从而扩大了整数表示范围。

英伟达为满足GPU需求,推出了TF32数据类型,具有8位指数、10位小数(与FP16相同),相较于BF16多出3位小数。

061f7c2d977f62be915e71b6a18411b6.jpeg

图5. BF16、TF32位数,来源:英伟达白皮书

d794807a5124cc2c7c5bfdbf0105bf81.jpeg

图6. 各种精度综合对比


BF16是一种高效的数据格式,具有较短的计算时间(与FP16相当)和较少的存储需求(小数位数较少)。同时,它在准确性方面表现出色,达到了92%,与其他同类格式相当。这些优势使得BF16成为一种值得关注的技术选择。


到此结束,我们搞清楚了各种浮点类型的定义、转换、模型训练时如何使用,以及性能对比。

-对此,您有什么看法见解?-

-欢迎在评论区留言探讨和分享。-

这篇关于人工智能算力FP32、FP16、TF32、BF16、混合精度解读的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

java之Objects.nonNull用法代码解读

《java之Objects.nonNull用法代码解读》:本文主要介绍java之Objects.nonNull用法代码,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录Java之Objects.nonwww.chinasem.cnNull用法代码Objects.nonN

SpringCloud负载均衡spring-cloud-starter-loadbalancer解读

《SpringCloud负载均衡spring-cloud-starter-loadbalancer解读》:本文主要介绍SpringCloud负载均衡spring-cloud-starter-loa... 目录简述主要特点使用负载均衡算法1. 轮询负载均衡策略(Round Robin)2. 随机负载均衡策略(

解读spring.factories文件配置详情

《解读spring.factories文件配置详情》:本文主要介绍解读spring.factories文件配置详情,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录使用场景作用内部原理机制SPI机制Spring Factories 实现原理用法及配置spring.f

Spring MVC使用视图解析的问题解读

《SpringMVC使用视图解析的问题解读》:本文主要介绍SpringMVC使用视图解析的问题解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC使用视图解析1. 会使用视图解析的情况2. 不会使用视图解析的情况总结Spring MVC使用视图

Linux中的进程间通信之匿名管道解读

《Linux中的进程间通信之匿名管道解读》:本文主要介绍Linux中的进程间通信之匿名管道解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、基本概念二、管道1、温故知新2、实现方式3、匿名管道(一)管道中的四种情况(二)管道的特性总结一、基本概念我们知道多

Linux系统之authconfig命令的使用解读

《Linux系统之authconfig命令的使用解读》authconfig是一个用于配置Linux系统身份验证和账户管理设置的命令行工具,主要用于RedHat系列的Linux发行版,它提供了一系列选项... 目录linux authconfig命令的使用基本语法常用选项示例总结Linux authconfi

Python中如何控制小数点精度与对齐方式

《Python中如何控制小数点精度与对齐方式》在Python编程中,数据输出格式化是一个常见的需求,尤其是在涉及到小数点精度和对齐方式时,下面小编就来为大家介绍一下如何在Python中实现这些功能吧... 目录一、控制小数点精度1. 使用 round() 函数2. 使用字符串格式化二、控制对齐方式1. 使用

解读docker运行时-itd参数是什么意思

《解读docker运行时-itd参数是什么意思》在Docker中,-itd参数组合用于在后台运行一个交互式容器,同时保持标准输入和分配伪终端,这种方式适合需要在后台运行容器并保持交互能力的场景... 目录docker运行时-itd参数是什么意思1. -i(或 --interactive)2. -t(或 --

解读为什么@Autowired在属性上被警告,在setter方法上不被警告问题

《解读为什么@Autowired在属性上被警告,在setter方法上不被警告问题》在Spring开发中,@Autowired注解常用于实现依赖注入,它可以应用于类的属性、构造器或setter方法上,然... 目录1. 为什么 @Autowired 在属性上被警告?1.1 隐式依赖注入1.2 IDE 的警告:

Rust中的注释使用解读

《Rust中的注释使用解读》本文介绍了Rust中的行注释、块注释和文档注释的使用方法,通过示例展示了如何在实际代码中应用这些注释,以提高代码的可读性和可维护性... 目录Rust 中的注释使用指南1. 行注释示例:行注释2. 块注释示例:块注释3. 文档注释示例:文档注释4. 综合示例总结Rust 中的注释