本文介绍 重磅!腾讯优图开源最新前端推理框架TNN!

重磅!腾讯优图开源最新前端推理框架TNN!

本文由林大佬原创,转载请注明出处,来自腾讯、阿里等一线AI算法工程师组成的QQ交流群欢迎你的加入: 1037662480

来了来了,终于来了。就在今天,腾讯优图团队开源了全新升级的轻量级深度学习前端推理框架TNN。

从昨天发布海报预热到现在,终于可以看到源码了。我们趁着这代码刚release,赶紧测试了一波。在这之前,我们还是预览一遍这个框架和ncnn,mnn等的不同,它的优点,架构上的改变,同时看看它是否能取代ncnn生成下一代高性能的移动端轻量级推理库。

首先,这个框架实际上是优图内部的Rapidnet和ncnn框架基础之上,一步一步的发展而来,在这个时间点发布,也恰好说明,深度学习落地又到了一个新的时间节点,后浪们得继续准备好发力了。

先跑开TNN和ncnn等的性能对比不谈,不如看看它的应用先。TNN目前已经在手机QQ,微视,P图等应用中大规模落地使用,主要的特点包括:

  • 计算优化
    • 针对不同架构在硬件指令发射、吞吐、延迟、缓存带宽、缓存延迟、寄存器数量等特点,深度优化底层算子,极致利用硬件算力
    • 主流硬件平台(CPU: ARMv7, ARMv8, GPU: Mali, Adreno, Apple) 深度调优
    • CNN 核心卷积运算通过 Winograd,Tile-GEMM, Direct Conv 等多种算法实现,保证不同参数、计算尺度下高效计算
    • Op 融合:离线分析网络计算图,多个小 Op(计算量小、功能较简单)融合运算,减少反复内存读取、kernel 启动等开销
  • 低精度优化
    • 支持 INT8, FP16 低精度计算,减少模型大小、内存消耗,同时利用硬件低精度计算指令加速计算
    • 支持 INT8 Winograd 算法,(输入6bit), 在精度满足要求的情况下,进一步降低模型计算复杂度
    • 支持单模型多种精度混合计算,加速计算同时保证模型精度
  • 内存优化
    • 高效”内存池”实现:通过 DAG 网络计算图分析,实现无计算依赖的节点间复用内存,降低 90% 内存资源消耗
    • 跨模型内存复用:支持外部实时指定用于网络内存,实现“多个模型,单份内存”。

TNN的性能benchmark

主流模型的性能表格:

  • 麒麟970:

    model cpu time(单线程,ms) gpu time(ms)
    Mobilenet_v1 88 12
    Mobilenet_v1_int8 55
    Mobilenet_v2 58 11
    Mobilenet_v2_int8 41
    squeezenet_v1.0 127 20
    squeezenet_v1.0_int8 82
  • 骁龙835:

    model cpu time(单线程,ms) gpu time(ms)
    Mobilenet_v1 94 16
    Mobilenet_v1_int8 62
    Mobilenet_v2 61 14
    Mobilenet_v2_int8 47
    squeezenet_v1.0 122 28
    squeezenet_v1.0_int8 93
  • 骁龙845:

    model cpu time(单线程,ms) gpu time(ms)
    Mobilenet_v1 60 10
    Mobilenet_v1_int8 37
    Mobilenet_v2 39 8
    Mobilenet_v2_int8 28
    squeezenet_v1.0 74 14
    squeezenet_v1.0_int8 56

TNN的结构如图:

可以看到:

  • TNN采用统一的ONNX模型作为中转,兼容各大框架,这也反映出业界对于ONNX模型的中转方式的认可和推动;
  • TNN支持FP16和int8的量化;
  • TNN支持计算图的优化,至于具体采用了何种优化模式进行优化,还需要进一步深入代码了解;
  • TNN通过抽象化的kernel接口使得算子可以跑在不同的硬件平台之上,支持ARM,GPU,NPU等计算。

另外,根据TNN官方的描述,它还具有优点:

  • 通过 ONNX 支持 TensorFlow, PyTorch, MXNet, Caffe 等多种训练框架,充分利用和融入不断完善的 ONNX 开源生态。当前支持 ONNX 算子55个,近期会完善到约80个,覆盖主流CNN网络
  • 支持主流安卓、iOS、Embedded Linux 操作系统,支持 ARM CPU, GPU 硬件平台(近期还会加入达芬奇 NPU 支持)
  • 模块化设计,将模型解析、计算图构建、优化、底层硬件适配、高性能 kernel 实现各部分抽象隔离,通过 Factory Mode 注册、构建设备,方便接入更多的底层硬件、加速方案。
  • Runtime 无任何第三方库依赖,CPU 动态库尺寸仅约 400KB,并提供基础图像变换操作,调用简单便捷。跨平台模型统一、调用接口统一,通过单个配置参数快速切换。

TNN支持的算子

TNN目前支持的算子还是很丰富的,基本上大多数能够支持ncnn的应用都可以无缝迁移到TNN:

目前 TNN 支持常用的 CNN 的网络:

  • Classical CNN: Vgg AlexNet GoogleNet(v1,v2,v3)
  • Practical CNN: ResNet DenseNet SENet
  • Light-weight CNN: SqueezeNet MobileNet(v1,v2,v3) ShuffleNet(v1,v2) MNasNet
  • Detection: Mtcnn-v2
  • Detection: Vgg-ssd SqueezeNet-ssd MobileNetv2-SSDLite …
  • Detection: Yolo-v2 MobileNet-YOLOV3 …
  • Segmentation: FCN PSPNet

目前支持的硬件:

device support
ARMv7 Yes
ARMv8 Yes
OpenCL Yes
Metal Yes

TNN上手

实际编译TNN下来,直接clone代码编译基本上没啥问题,这一点给TNN点赞:

[ 90%] Building CXX object CMakeFiles/TNN.dir/source/tnn/optimizer/net_optimizer_insert_reformat.cc.o
[ 90%] Building CXX object CMakeFiles/TNN.dir/source/tnn/optimizer/net_optimizer_manager.cc.o
[ 91%] Building CXX object CMakeFiles/TNN.dir/source/tnn/optimizer/net_optimizer_remove_layers.cc.o
[ 91%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/bbox_util.cc.o
[ 92%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/bfp16_utils.cc.o
[ 92%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/blob_converter.cc.o
[ 93%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/blob_converter_internal.cc.o
[ 93%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/blob_dump_utils.cc.o
[ 94%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/blob_memory_size_utils.cc.o
[ 94%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/blob_transfer_utils.cc.o
[ 95%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/cpu_utils.cc.o
[ 95%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/data_format_converter.cc.o
[ 95%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/data_type_utils.cc.o
[ 96%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/dims_vector_utils.cc.o
[ 96%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/half_utils.cc.o
[ 97%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/naive_compute.cc.o
[ 97%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/pribox_generator_utils.cc.o
[ 98%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/split_utils.cc.o
[ 98%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/string_format.cc.o
[ 99%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/string_utils.cc.o
[ 99%] Building CXX object CMakeFiles/TNN.dir/source/tnn/utils/wingorad_generater.cc.o
[100%] Linking CXX shared library libTNN.so
[100%] Built target TNN

代码鲁棒性还是很强的。

image-20200610162755135

生成的动态链接库只有1.7M。

尝试一下convert:

随便转一个fcos的onnx模型吧(这个模型在ncnn上转是没问题的):

❯ python3 converter.py onnx2tnn ~/Desktop/fcos.onnx
the onnx2tnn command:python3 onnx2tnn.py /home/dd/Desktop/fcos.onnx -version=v1.0 -optimize=0 -half=0 -o /home/dd/Desktop
0.----onnx version:1.6.0
algo_optimize 0
onnx_net_opt_path /home/dd/Desktop/fcos.onnx
2.----onnx2tnn: /home/dd/Desktop/fcos.onnx
3.----onnx2tnn status: -1

Traceback (most recent call last):
  File "onnx2tnn.py", line 107, in main
    status = onnx2tnn.convert(onnx_net_opt_path, output_dir, algo_version, file_time, 0 if model_half == '0' else 1)
AttributeError: module 'onnx2tnn' has no attribute 'convert'

onnx2tnn succeed!

报错,然而还给一个succeed的返回值,这一段代码没有测试过么?

我算是明白了,这个转换的python脚本不仅隐藏的很深,而且套中套:

image-20200610164230745

这个操作也太套娃了吧?

没有ncnn的C++工具来的简单啊,对于工具类的东西,比如模型转换工具,还真的不推荐用python去搞,虽然简单,但是用户感觉很不友好。

前面编译TNN的时候好像也没有把这个convertor一起编译了,也没有examples编译,总体来说… 不是很完善?

结论

结论除了速度快一点目前无法得出啥很好的结论了,总体而言,对于新手来说,上手没有ncnn那么直观。其实对于框架来讲,用户体验也很重要。

优图这次开源的东西API文档蛮多的,给个赞,但是,但是,但是,和许多其他优图开源的东西一样,我本来写这个开题的时候觉得这应该是个很牛逼的东西,但是,用起来可能是另外一回事。

最后,Github:

https://github.com/Tencent/TNN

感兴趣的朋友可以玩一玩。

End

如果你想学习人工智能,对前沿的AI技术比较感兴趣,可以加入我们的知识星球,获取第一时间资讯,前沿学术动态,业界新闻等等!你的支持将会鼓励我们更频繁的创作,我们也会帮助你开启更深入的深度学习之旅!

image-20200515153654923