PyTorch中bfloat16精度下epsilon减法未生效问题咨询
问题解答
你对epsilon的理解偏差在哪?
bfloat16的eps(即torch.finfo(torch.bfloat16).eps)的定义是1.0到下一个能被bfloat16表示的浮点数的差值,它不是所有数值的最小可分辨步长。
浮点数的存储分符号位、指数位和尾数位,数值越大,指数位对应的量级越高,相邻两个可表示浮点数之间的间隔(专业叫ULP,最后一位的单位)就越大。比如你用的2.8438是大于1的数,它的ULP比bfloat16的eps要大,所以直接减eps的话,这个变化量太小,无法被当前数的精度捕捉到,自然就出现test - delta == test的情况。
正确获取当前数的下一个更小值的方法
PyTorch里有专门的函数torch.nextafter(),可以直接获取某个数的下一个可表示的浮点数。要拿到比test小的下一个数,只需要这么写:
import torch test = torch.Tensor([2.8438]).to(torch.bfloat16) next_smaller = torch.nextafter(test, test - 1) print(next_smaller) print(next_smaller < test) # 输出tensor([True]),说明确实更小
这个函数会根据输入的目标方向(第二个参数),返回当前数在浮点数精度下最接近目标的那个相邻值,不管你的数是大是小,都能准确拿到符合精度要求的步长。
关于你的临时解决方法
你的代码虽然在当前案例下能用,但通用性很差——比如当某个数的ULP是eps的3倍时,减2eps可能还是无法改变数值;如果ULP刚好是eps的1.5倍,减2eps就跳过了中间的可表示数,不符合你“极窄参数范围扫描”的需求。用torch.nextafter()才是从根源上解决问题的方案。
内容的提问来源于stack exchange,提问作者XapaJIaMnu
相关产品推荐
相关产品推荐

