00:00
不做快餐教程,只讲知识本质大家好,我是会写代码你会唱歌的蛋先生开局一个小知识点大模型训练完,参数基本都存成VF16格式BF不是bra frame哦,它指的是brain float浮点数的一种存储设计。为什么是brain?因为它由Google brain团队设计,也许这就是开发者最单纯的自豪感了。它是为深度学习量身定做的,之所以会出现,就是因为当时的FP16太不给力了。搞懂了FP16,自然也就理解了VF16 FP16是怎么纯数记的,就是把16个bit分成三部分,1个符号位、5个指数位和10个尾数位。符号位很好理解,因为要表示正负,尾号位也很好理解,就是小数点后面的数字,但这指数位是干嘛的?
01:00
为什么不直接搞个整数位?像3.14那样,整数部分和小数部分分开存,这个直观的思路叫定点数。整数位和小数位各自固定,但它的致命3就是鱼与熊掌不可兼得,你很难同时表达一个极大的数值和无限趋近于0的极小数值。假如15位全给整数部分,最大值也就32767,但这样小数就一个都表示不了了。反过来,全给小数位,连个大于1的数都表示不了。所以这种试剂要么只能数星星,要么只能数细菌,太极端了。于是聪明的人类发明的浮点通过指数未来移动,小数点左移缩小,右移放大,相当于给数字加了一个缩放因子,浮点这个名字就是这么来的。小数点可以。
02:00
浮动具体怎么表示呢?公式长这样,S是符号位,决定正负,S为0时值为1 S为1时只为-1 1是指数位,M是尾数位。有没有同学有疑问,为什么指数是1-15?这个15是哪里冒出来的?因为我们既需要正的指数来放大数字,也需要负的指数来缩小数字。简单理解就是指数多少就将小数点移动多少。比如1.01×2的一次方就是把小数点为又1亿格变成1 0.1。如果直接存正负符号,机器还得额外处理符号,又制腾又浪费空间,那咋整?指数位是5 5个bit有多少个组合?没错,2的五次方也就是32个数表示0~30。
03:00
1取个中间值15作为偏移量,比如存13,实际指数就是13-15等于负二,存17,实际指数就是17-15=2,按I1175是规约数,规范1的取值是1~30 0和30 1为保留值有其他用处,所以真实指数范围是-14到+15。有没有觉得这个小小的设计挺巧妙的,这样的设计还能让指数直接按无符号整数比较大小,大幅简化了浮点数比较的硬件电路试剂。接下来是尾数位,有没有同学对一点N中的一号奇的,这是最妙的地方。这个1叫影视前导位,按I1175式规范,规约数永远在前面有个一,比如1.10101。
04:00
但它不用权,机器自动认,这样就凭空省了一个bit,有没有眼睛的同学发现这样好像没法表示零值了,我们来算一下,最小的正值约等于0.000061035,确切的说是无法表示靠近0的直角数值。实际应用中如果遇到非规约数,会有各种各样的解决方案,这里就不展开了。大家有没有疑问,此数位为什么偏偏是无位?这是拍脑袋决定的吗?还是精心世纪的指数位越多,数值范围越大,但尾数位就少了,精度就下降了。反过来也一样,五位的取值是根据当时的应用场景权衡出来的结果,所以如果应用场景变了,指数位数也可能需要调整。我们。
05:00
但讲了大半天的FP16,那BF16到底怎么回事?就是因为应用场景变了,FP16不满足了呗。问题出在训练上,模型训练用的是LP三二三十二位的浮点数,指数位有8位,而FP16才5位,保存时如果用FP16,那肯定各种溢出,就好比十分像一样,B f16就是1位符号加8位指数加7位尾数,指数位和FP32完全一致,所以BF16的数值范围跟FP32是一模一样的。从FP32转成BF16,几乎是零成本,代价是尾数位少了,精度降了。但深度学习对精度不敏感,对范围更敏感,从定点到浮点,从FP16到BF16,无不体现着人类的智慧。
06:00
呀,终于结束了,拜拜。
我来说两句