Skip to content

Latest commit

 

History

History
129 lines (76 loc) · 4.22 KB

2022_06_07_11_WNNX从零实现一个AI推理引擎(六).md

File metadata and controls

129 lines (76 loc) · 4.22 KB
title date category
2022_06_07_11_WNNX从零实现一个AI推理引擎(六)
2022-06-07 16:58:58 -0700
默认分类

本文介绍 2022_06_07_11_WNNX从零实现一个AI推理引擎(六)

2022_06_07_11_WNNX从零实现一个AI推理引擎(六)

本文由在当地较为英俊的男子金天大神原创,版权所有,欢迎转载,本文首发地址 https://jinfagang.github.io 。但请保留这段版权信息,多谢合作,有任何疑问欢迎通过微信联系我交流:jintianiloveu

手写一个前推框架的系列博客已经更新到第六篇了,从一开始的一个替代onnx算子碎片化、直接从torchscript到推理引擎的想法,到建造我们自己的IR,并完成了可视化,最后到逐渐构建自己的推理引擎,基本上我们已经打通了大部分的链条,继续向下一个目标进发。

上一次,我们推理了几个简单的FC模型,例如一个带有layernorm的FC模型,单输入输出,多入多出都可以推理。

上面的结果可以推理。两个输入的问题不大,下面这种才是真的杂乱:

4个输入也没问题,而且下面这个模型的layernorm是动态权重的。

到目前为止我没有看到哪个框架真正支持动态layernorm权重,可能是需求比较小。

上面那个结构,其实是简化之后的,这就是wnnx为什么有用,我们来看看onnx 的结构:

两个模型一模一样,但是onnx要复杂很多,因为引入了太多的胶水算子。

这就是wnnx的 用途。

万物初始VGG

我们一开始的规划并不满足于简单的FC推理,我们最起码要跑卷积。那么VGG就是第一不了,如果VGG都推理不了,那基本上就没啥用。

来看vgg的推理代码:

#include "core/utils/log.h"
#include "wnn/forward.h"
#include "wnn/tensor.h"
#include <cstddef>
#include <cstdio>
#include <string>
#include <vector>

int main(int argc, char **argv) {
  std::string model_f = argv[1];

  auto wnn_model = wnn::NNForward();
  if (!wnn_model.load_from_file(model_f)) {
    LOG(INFO) << "model might load failed.";
    return -1;
  }

  auto input_tensor = wnn::from_numpy_bin("in.bin", {1, 3, 224, 224});
  vector<wnn::Tensor> inputs;
  inputs.push_back(input_tensor);

  LOG(INFO) << "my input tensor: ";
  std::cout << input_tensor;

  std::vector<size_t> out_shape = {1, 1000};
  wnn::Tensor output_tensor =
      wnn::Tensor(out_shape, wnn::DeviceType::DeviceType_kCPU);
  vector<wnn::Tensor> outputs;
  outputs.push_back(output_tensor);

  auto res2 = wnn_model.infer(inputs, outputs);

  LOG(INFO) << "result: ";
  std::cout << output_tensor;

  auto gt = wnn::from_numpy_bin("data.bin", out_shape);
  gt.allclose(output_tensor);
  return 0;
}

可以看到,整个推理非常精简,你甚至可以直接从numpy读数据,这对于调试很有用,你可以保持和pyotorch测的数据完全一致,并且可以很方便的对比输出结果。

这里就不得不说wnnx框架的优势:

  • 你甚至感觉不到这是在C++里面推理,Tensor的操作跟pytorch几乎一模一样;
  • 所有的Tensor结果都可以打印。

一个典型的CNN的wnnx网络结构:

直接开始推理!

PyTorch下的输出结果:

wnnx下的推理结果:

可以看到,那个输出的Tensor是可以直接打印的:

std::cout << out_tensor;

你就可以看到每个数值和维度,非常方便。

最终结果,完全对齐,误差不超过10e-5。

总结

从0打造一个推理引擎差不多到这里就结束了。

下一篇,将是本系列的终结篇,也是一个小的milestone: 下一篇将尝试用我们自己的推理引擎来推理YOLOX检测模型,并加入移动端优化加速