繁体   English   中英

Python numpy float16数据类型操作,还是float8?

[英]Python numpy float16 datatype operations, and float8?

当对float16 Numpy数字执行数学运算时,结果也是float16类型数。 我的问题是如何计算结果? 假设我乘以/添加两个float16数字,python是否在float32中生成结果然后将结果截断/舍入为float16? 或者计算是否在“16位多路复用器/加法器硬件”中执行?

另一个问题 - 是否有float8类型? 我找不到这个......如果没有,那么为什么? 谢谢你们!

对于第一个问题:在典型的处理器上(至少在GPU之外)没有对float16的硬件支持。 NumPy完全按照你的建议:将float16操作数转换为float32 ,对float32值执行标量操作,然后将float32结果舍入为float16 可以证明结果仍然是正确舍入的: float32的精度足够大(相对于float16 ),这里双舍入不是问题,至少对于四个基本算术运算和平方根。

在当前的NumPy源代码中,这就是float16标量运算的四种基本算术运算的定义。

#define half_ctype_add(a, b, outp) *(outp) = \
        npy_float_to_half(npy_half_to_float(a) + npy_half_to_float(b))
#define half_ctype_subtract(a, b, outp) *(outp) = \
        npy_float_to_half(npy_half_to_float(a) - npy_half_to_float(b))
#define half_ctype_multiply(a, b, outp) *(outp) = \
        npy_float_to_half(npy_half_to_float(a) * npy_half_to_float(b))
#define half_ctype_divide(a, b, outp) *(outp) = \
        npy_float_to_half(npy_half_to_float(a) / npy_half_to_float(b))

上面的代码取自NumPy源代码中的scalarmath.c.src 您还可以查看loops.c.src以获取数组ufuncs的相应代码。 支持npy_half_to_floatnpy_float_to_half函数在halffloat.c中定义,以及float16类型的各种其他支持函数。

对于第二个问题:不,NumPy中没有float8类型。 float16是一种标准化类型(在IEEE 754标准中描述),在某些情况下(特别是GPU)已广泛使用。 没有IEEE 754 float8类型,并且似乎没有明显的“标准” float8类型的候选者。 我还猜测在NumPy中对float8支持的需求并不多。

这个答案建立在问题的float8方面。 接受的答案很好地涵盖了其余部分。除了缺乏标准之外,没有广泛接受的float8类型的一个主要原因是它实际上不是非常有用。

浮点入门

在标准表示法中, float[n]数据类型使用内存中的n位存储。 这意味着最多只能表示2^n唯一值。 在IEEE 754中,少数这些可能的值,如nan ,不是偶数。 这意味着所有浮点表示(即使你去float256 )在它们能够表示的有理数集合中有间隙,如果你试图在这个间隙中得到一个数字的表示,它们会舍入到最接近的值。 通常, n越高,这些间隙越小。

如果使用struct包来获取某些float32数字的二进制表示,则可以看到操作中的差距。 最初遇到它有点令人吃惊但是在整数空间中只有32的差距:

import struct

billion_as_float32 = struct.pack('f', 1000000000 + i)
for i in range(32):
    billion_as_float32 == struct.pack('f', 1000000001 + i) // True

通常,浮点最好只跟踪最重要的位,这样如果您的数字具有相同的比例,则保留重要的差异。 浮点标准通常仅在它们在基数和指数之间分配可用位的方式上有所不同。 例如,IEEE 754 float32使用24位作为基数,8位作为指数。

回到float8

通过上面的逻辑, float8值只能占用256个不同的值,无论你在基数和指数之间分割比特有多聪明。 除非你热衷于将数字四舍五入到接近零的256个任意数字之一,否则它可能更有效地跟踪int8的256种可能性。

例如,如果您想要以粗略的精度跟踪非常小的范围,您可以将所需的范围划分为256个点,然后存储您的数字最接近的256个点中的哪一个。 如果你想得到真正的幻想,你可以有一个非线性的值分布,无论是聚集在中心还是边缘,取决于你最重要的事情。

任何其他人(甚至自己以后)需要这种精确方案的可能性非常小,而且大多数情况下,使用float16float32作为惩罚的额外字节或3支付的代价太小而无法产生有意义的差异。 因此......几乎没有人想要写一个float8实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM