tensorrt FP16 C++

  1. Why? 为什么我们需要使用FP16半精度进行Inference

    1. 低的数据精度代表占用更少的存储资源,例如:FP32即float占用的是4字节,FP16占用的2字节,FP16存储空间占用率只有float的一半
    2. 计算单元处理FP16比处理FP32的速度快
    3. Nvidia有大量的计算加速框架(cuDNN, cuBlas)以及加速硬件(Tensor Core, DLA)对FP16的数据有加速优化
  2. NVidia是如何处理float与FP16的转换的,和其他普通的框架处理精度问题之间的区别是什么?
    在IEEE-754的描述中单精度浮点数(Nvidia习惯称为FP32,C++标准中的float)是4个字节,包括1位符号、8位指数和23位尾数。\(value = sign × exponent × fraction\) 浮点数的实际值\(value\),等于符号位(sign bit)乘以指数偏移值(exponent bias)再乘以分数值(fraction)。
    NVidia在2002年提出了半精度浮点数FP16,只使用2个字节16位,包括1位符号、5位指数和10位尾数,动态范围是 \( 2^{-30}\sim 2^{31} \)也就是 \(10^{-9}\sim 10^9 \),精度是 \( \rm lg2^{11} \),大约3个十进制有效数字。NVidia的方案已经被IEEE-754采纳。Google的TensorFlow则比较简单粗暴,把单精度的后16位砍掉,也就是1位符号、8位指数和7位尾数。动态范围和单精度相同,精度只有 \( \rm lg 2^8 \),2个有效数字。

    1. NVidia的float与FP16的转换方法:
      float –> FP16

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      
      typedef unsigned short half;
      half nvFloat2Half(float m)
      {
          unsigned long m2 = *(unsigned long*)(&m);    
          // 强制把float转为unsigned long
          // 截取后23位尾数,右移13位,剩余10位;符号位直接右移16位;
          // 指数位麻烦一些,截取指数的8位先右移13位(左边多出3位不管了)
          // 之前是0~255表示-127~128, 调整之后变成0~31表示-15~16
          // 因此要减去127-15=112(在左移10位的位置).
          unsigned short t = ((m2 & 0x007fffff) >> 13) | ((m2 & 0x80000000) >> 16) 
              | (((m2 & 0x7f800000) >> 13) - (112 << 10));           
          if(m2 & 0x1000) 
              t++;                       // 四舍五入(尾数被截掉部分的最高位为1, 则尾数剩余部分+1)
          half h = *(half*)(&t);     // 强制转为half
          return h ;
      }
      

      FP16 –> float

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      
      float nvHalf2Float(half n)
      {
          unsigned short frac = (n & 0x3ff) | 0x400;
          int exp = ((n & 0x7c00) >> 10) - 25;
          float m;
          if(frac == 0 && exp == 0x1f)
              m = INFINITY;
          else if (frac || exp)
              m = frac * pow(2, exp);
          else
              m = 0;
          return (n & 0x8000) ? -m : m;
      }

       

from :http://cache.baiducontent.com/c?m=c08zUnFu_8lDzMxb6VC78O-1jAVGPmwivIEf7FCLJTBYW62OnzatXPDxM1TaE4_xbh3LO_yCw9BMX6NiahLMhoXl3i5uxe_IHTfFoKpe0yhbRd2ufnRITS1MniXf8ij5pQ2yGW7-QUTGYMwhaoCfiTgkP0Gu9N1C9A3Vwa-G0MfNAYDKBGK5F_es9FTaTmnzN-V5l_WboU5M1w1RoEypm9psHBriPZllpI4nNhSliOS&p=933ec85b86cc46a91af5c7710f08&newp=882a9243959a19fc57efc237540a92695d0fc20e3ad6d001298ffe0cc4241a1a1a3aecbf2d27160ed9c57a6707aa4d5be1f13d763d0034f1f689df08d2ecce7e6cd17f&s=cfcd208495d565ef&user=baidu&fm=sc&query=tensorrt+%B0%EB%BE%AB%B6%C8&qid=88f878df0001c372&p1=1

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值