当前位置: 首页 > news >正文

混合精度训练原理之float16和float32数据之间的互相转换

混合精度训练原理之float16和float32数据之间的互相转换

本篇文章参考:全网最全-混合精度训练原理

  • 上述文章已经讲解的比较详细,本文只是从数值角度分析:
    1. float32转入float16的精度误差
    2. 在深度学习的混精度训练当中,当参数值(float32)获取到计算得到的梯度值(float16)后的更新过程。

问题一:float32转入float16的精度误差

首先,我们还是回顾一下float16和float32在计算机当中的存储格式:

在这里插入图片描述
有了上述内容之后,我们通过一个实际的例子来观察,float32到float16的舍入误差:(我们使用python的numpy作为例子演示,当用到具体框架如pytorch将其转化为Tensor再进行转化是一样的)

  • 当我们创建了一个十进制数据[1.12156456132],并通过float32进行存储。
big_value32 = np.array([1.12156456132], np.float32)
print(f"big_value32:{big_value32[0]:.23f}")//result:
big_value32:1.12156450748443603515625

不考虑计算机存储,我们使用十进制转二进制得到【1.12156456132 】的二进制表示为【1.000111110001111011011010111001110011100011010100001…】,它是一个不能在有限精度内存储的数据,根据上述float32的存储空间表示,我们知道它只能保存23位有效数字(不包含首位的1),截取后,他在计算机中的表示为【1.00011111000111101101101】(截取时查看后一位,为1时进一位,为0时不进位),故其十进制表示为【1.12156450748443603515625】(所以在存取数字时是有损失的),舍入为float16时,计算的存储表示为【1.0001111100】,表示为十进制为 【1.12109375】 ,这个时候便产生了舍入误差

问题二:在深度学习的混精度训练当中,当参数值(float32)获取到计算得到的梯度值(float16)后的更新过程。

  • 在混精度训练中,为什么一定要保存一份float32的权重副本用于和计算得出的float16数据做更新?因为如果用float16和float16做计算(加法),相对于float32,会造成精度的损失,甚至导致无法更新
  1. 我们仍然举一个例子来说明这个问题,我们考虑一个十进制的原始数据(权重),假设为【1.125】,利用float16二进制存储为【0 01111 0010000000】,float32二进制存储为【0 01111111 00100000000000000000000】。
  2. 同时考虑一个计算得出的float16梯度,假设为【0.12457275190625】,二进制float16表示为【0 01011 1111111001】。
  3. 我们使用float16的原始权重去做更新:即【0 01111 0010000000】+【0 01011 1111111001】,由于他们的指数部分不相同,我们需要将指数较小的数据的小数点向左移,以保证他们的指数部分对齐,【0 01011 1111111001】将指数部分对齐【0 01111 0010000000】后,小数点需要向左移4位,在左边补0,移位之后的结果为【0 01111 0001111111】。
  4. 将两者的有效位部分相加,即【0010000000】(0)+【0001111111】(1),括号里面表示第11位有效位数值,用于进位,根据二进制加法,我们综合符号位和指数为,得到最后结果为:【0 01111 0100000000】,转换为十进制为【1.250】。
  1. 跟上个例子一样,但我们考虑使用float32去和新计算出来的float16数据做计算,在计算过程中,float16会被转换为更高精度的float32参与计算。
  2. 二进制float16【0 01011 1111111001】转换为float32为【0 01111011 11111110010000000000000】(指数位+122,有效位数后面补0)。
  3. 进行加法计算【0 01111111 00100000000000000000000】+【0 01111011 11111110010000000000000】,算得最后结果为【0 01111111 00111111111001000000000】,转换为十进制为【1.24957275390625】。从中我们可以看到精度的损失,这也是为什么要保存权重的高精度副本用于更新。
  • 如果还有理解不到位的地方,可以配合这两个工具食用:
    • 在线IEEE浮点二进制计算器
    • 在线进制转换

附:1.更新失效例子(mindspore代码):

import numpy as np
import mindspore as ms
from mindspore import Tensor
import structdef float_to_bin(num):return format(struct.unpack('!I', struct.pack('!f', num))[0], '032b')def float16_to_bin(num):float16 = np.float16(num)int_bits = np.frombuffer(float16.tobytes(), dtype=np.uint16)[0]bin_str = format(int_bits, '016b')return bin_strbig_value32 = np.array([1.125], np.float32)
big_value16 = big_value32.astype(np.float16)  # 转换为float16print(f"weight_float16:{big_value16[0]:.23f}")
print(f"weight_float32:{big_value32[0]:.23f}")
print(float16_to_bin(big_value16[0]))
print(float_to_bin(big_value32[0]))small_value_float16 = np.array([0.00041999], np.float16) print(f"grad_float16:{small_value_float16[0]:.23f}")
print(float16_to_bin(small_value_float16[0]))
print(float_to_bin(small_value_float16[0]))# 在MindSpore中进行计算
small_tensor_float16 = Tensor(small_value_float16, ms.float16)
big_tensor16 = Tensor(big_value16, ms.float16)
big_tensor32 = Tensor(big_value32, ms.float32)# float32与float16相加
print(f"------epoch 0--------")
result1 = big_tensor32 + small_tensor_float16
print(f"float32 + float16: {result1.asnumpy()[0]:.23f}",result1.dtype)
result2 = big_tensor16 + small_tensor_float16
print(f"float16 + float16: {result2.asnumpy()[0]:.23f}",result2.dtype)
for i in range(100):print(f"------epoch {i+1}--------")result1 += small_tensor_float16print(f"float32 + float16: {result1.asnumpy()[0]:.23f}",result1.dtype)result2 += small_tensor_float16print(f"float16 + float16: {result2.asnumpy()[0]:.23f}",result2.dtype)print("float32 + float16:", result1.asnumpy(),result1.dtype)
print("float16 + float16:", result2.asnumpy(),result2.dtype)if not np.isclose(result1.asnumpy(), result2.asnumpy()):print("The results are different!")
else:print("The results are the same!")

在这里插入图片描述

2.误差累积例子:将上述small_value_float16改为0.12457275190625,即可得到问题2,例子2中观察:

在这里插入图片描述

相关文章:

混合精度训练原理之float16和float32数据之间的互相转换

混合精度训练原理之float16和float32数据之间的互相转换 本篇文章参考:全网最全-混合精度训练原理 上述文章已经讲解的比较详细,本文只是从数值角度分析: 1. float32转入float16的精度误差 2. 在深度学习的混精度训练当中,当参数…...

网络协议--ICMP:Internet控制报文协议

6.1 引言 ICMP经常被认为是IP层的一个组成部分。它传递差错报文以及其他需要注意的信息。ICMP报文通常被IP层或更高层协议(TCP或UDP)使用。一些ICMP报文把差错报文返回给用户进程。 ICMP报文是在IP数据报内部被传输的,如图6-1所示。 ICMP…...

《红蓝攻防对抗实战》三.内网探测协议出网之HTTP/HTTPS协议探测出网

目录 一. 在 Windows 操作系统中探测 HTTP/HTTPS 出网 1. Bitsadmin 命令 2.Certuil 命令 2.Linux系统探测HTTP/HTTPS出网 1.Curl命令 2.Wget命令 对目标服务器探测 HTTP/HTTPS 是否出网时,要根据目标系统类型执行命令,不同类型的操作系统使用的探…...

【Win11】系统重装教程(最新最详细)

目录 一.简介 二.用U盘制作PE系统 三、安装系统 软件:Windows 11版本:21H2语言:简体中文大小:5.14G安装环境:PE系统,至少7代处理器硬件要求:CPU2.0GHz 内存4G(或更高)下载通道①丨…...

如何构建一个外卖微信小程序

随着外卖行业的不断发展,越来越多的商家开始关注外卖微信小程序的开发。微信小程序具有使用方便、快速上线、用户覆盖广等优势,成为了商家们的首选。 那么,如何快速开发一个外卖微信小程序呢?下面就让我们来看看吧! 首…...

小知识(5) el-table行样式失效问题

一、实现效果 子级呈现不同颜色去区分 二、最初代码 tips: 我这里使用的vue3 elementplus <el-table :row-class-name"tableRowClassName" >... </el-table>function tableRowClassName({ row, rowIndex }) {if (row.children.length 0) {return …...

【Docker】Docker数据的存储

默认情况下&#xff0c;在运行中的容器里创建的文件&#xff0c;被保存在一个可写的容器层里&#xff0c;如果容器被删除了&#xff0c;则对应的数据也随之删除了。 这个可写的容器层是和特定的容器绑定的&#xff0c;也就是这些数据无法方便的和其它容器共享。 Docker主要提…...

hive字段关键字问题处理

最近在xxl_job部署shell调度任务时,发现在编写Hql时&#xff0c;对一些使用关键字命名的字段无法解析&#xff0c;按开发规范&#xff0c;字段命名不应该有关键字,但是数据来源是第三方,无法修改,需要通过flume对从kafka的数据到hdfs上&#xff0c;数据是json格式,所以需要对关…...

指定顺序输出

系列文章目录 进阶的卡莎C++_睡觉觉觉得的博客-CSDN博客数1的个数_睡觉觉觉得的博客-CSDN博客双精度浮点数的输入输出_睡觉觉觉得的博客-CSDN博客足球联赛积分_睡觉觉觉得的博客-CSDN博客大减价(一级)_睡觉觉觉得的博客-CSDN博客小写字母的判断_睡觉觉觉得的博客-CSDN博客纸币(…...

(Java)中的数据类型和变量

文章目录 一、字面常量二、数据类型三、变量1.变量的概念2.语法的格式3.整型变量4.长整型变量5.短整型变量6.字节型变量 四、浮点型变量1.双精度浮点数2.单精度浮点数 五、字符型常量六、布尔型变量七、类型转换1.自动类型转换&#xff08;隐式&#xff09;2.强制类型转换(显式…...

SHELL脚本编程基础,bilibili王晓春老师课程个人笔记(写比较简单,仅供参考)

文章目录 一、第一天&#xff08;Shell脚本编程基础&#xff09;作者视频ppt部分作者视频操作编写一个hello.sh可执行文件使hello.sh可以到处运行没有执行权限的执行方式下载httpd&#xff08;web服务器&#xff09;curl字符界面浏览器 命令列表凌乱笔记 作业重点&#xff1a; …...

VS code运行vue项目

要在VS Code中启动Vue项目&#xff0c;您可以按照以下步骤进行操作&#xff1a; 1.打开VS Code&#xff0c;并确保已安装Vue.js插件&#xff08;如Vetur&#xff09;。 2.在VS Code的侧边栏中&#xff0c;选择您的Vue项目文件夹&#xff0c;或者使用菜单中的“文件”->“打…...

matlab中narginchk函数用法及其举例

matlab中narginchk函数用法及其举例 narginchk在编写子函数程序时候&#xff0c;在验证输入参数数目方面具有重要作用&#xff0c;本博文讲一讲该函数的用法。 一、narginchk功能 narginchk的作用是验证输入参数数目。 二、语法 narginchk(minArgs,maxArgs)narginchk(minA…...

k8s集群镜像下载加gradana监控加elk日志收集加devops加秒杀项目

展示 1.配套资料2.devops 3.elk日志收集 4.grafana监控 5.dashboard![在这里插入图片描述](https://img-blog.csdnimg.cn/bf294f9fd98e4c038858a6bf5c34dbdc.png 目的 学习k8s来来回回折腾很久了&#xff0c;光搭个环境就能折腾几天。这次工作需要终于静下心来好好学习了一…...

waf绕过

1.市场Waf分类 硬件Waf&#xff1a;绿盟、安恒、启明、知道创宇等 需要选择模式 透明模式 反向代理分为反向代理&#xff08;代理模式&#xff09;与反向代理&#xff08;牵引模式&#xff09; 反向代理又分为两种模式&#xff0c;反向代理…...

在 MyBatis-Plus 中,如果你想通过其他字段进行修改操作,可以使用条件构造器(Wrapper)来指定修改的条件。

在 MyBatis-Plus 中&#xff0c;如果你想通过其他字段进行修改操作&#xff0c;可以使用条件构造器&#xff08;Wrapper&#xff09;来指定修改的条件。 对不起&#xff0c;我在之前的回答中犯了一个错误。在条件构造器中&#xff0c;eq 方法的第一个参数应该是数据库表中的列…...

Python Opencv实践 - 入门使用Tesseract识别图片中的文字

做车牌识别项目前试一试tesseract识别中文。tesseract的安装使用请参考&#xff1a; Python OCR工具pytesseract详解 - 知乎pytesseract是基于Python的OCR工具&#xff0c; 底层使用的是Google的Tesseract-OCR 引擎&#xff0c;支持识别图片中的文字&#xff0c;支持jpeg, png…...

TCP通信实战案例-即时通信

即时通信是什么含义&#xff0c;要实现怎么样的设计&#xff1f; 即时通信&#xff0c;是指一个客户端的消息发出去&#xff0c;其他客户端可以接收到。 即时通信需要进行端口转发的设计思想。 服务端需要把在线的Socket管道存储起来。 一旦收到一个消息要推送给其他管道。…...

【数据结构初阶】算法的时间复杂度和空间复杂度

算法的时间复杂度和空间复杂度 1.算法效率1.1 如何衡量一个算法的好坏1.2 算法的复杂度 2.时间复杂度2.1 时间复杂度的概念2.2 大O的渐进表示法2.3常见时间复杂度计算举例 3.空间复杂度4. 常见复杂度对比 1.算法效率 1.1 如何衡量一个算法的好坏 如何衡量一个算法的好坏呢&am…...

git log 命令详解

测试仓库 asdf 常用参数 查询指定目录 git -C /Users/yanlp/workspace/asdf log 限制显示提交数量 git log -n 3 限制提交人|邮箱 git log --authorEdwin Kofler | git log --authoredwinkofler.dev 限制一个月内的提交git log --since1.month.ago | git log --since2023-0…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...