Skip to content

Latest commit

 

History

History
128 lines (78 loc) · 4.37 KB

2022_06_06_12_WNNX从0实现AI推理引擎(五).md

File metadata and controls

128 lines (78 loc) · 4.37 KB
title date category
2022_06_06_12_WNNX从0实现AI推理引擎(五)
2022-06-06 05:45:45 -0700
默认分类

本文介绍 2022_06_06_12_WNNX从0实现AI推理引擎(五)

2022_06_06_12_WNNX从0实现AI推理引擎(五)

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

这个系列已经更新到第五篇了,我们从一开始的一个idea,到一步步的实现IR设计,到实现从torchscript直接转模型,再到搭建一个大致的前传框架,这个坑可谓是越来越深了。今天,我继续分享 wnnx的构造进度。

目前经过各种血泪的调试,wnnx 的前传播终于比较稳定了。对于简单的 FC layer可以稳定的推理。但是对于稍微复杂的模型,例如,算子包括了 binary_add, binary_mul, layernorm, softmax 等诸多layer的模型。。。。

复杂模型可视化测试

先来看看pytorch下这个模型结构:

别看这个结构简单,但其实非常灵活,不是常用的Conv_Bn_relu 就完了。

这里面包含了:

  • fc layer;
  • ELU;
  • add;
  • softmax;
  • layernorm

并且,这个模型是多输入的,这也可以进一步验证我们的推理框架,是否具备多输入的推理能力。这个也就是为上一节说要解决的问题。

先来第一步,我们将其转为wnnx的格式:

./build/src/townnx -m test_simple_fc_mm.pt -s 1x864,1x256

可以看到输出:

这其实是wnnx一个优点,你转换的时候就可以看到每一层的细节调试信息,当然这个可以关掉,debug默认打开。

这样看不过瘾,我们继续用 netron可视化以下:

没啥优化的地方,但是最起码基本机构看起来是对上的。wnnx看起来就简单多了。这跟我们 打造一个足够小,足够简单的前推框架的初衷相符

前推测试

接下来就是见证奇迹的时刻了! 我们推理一波,这里贴上 wnnx的前推代码:

auto wnn_model = wnn::NNForward();

  LOG(INFO) << "nnforward initiated.";

  if (wnn_model.load_from_file(model_f)) {
    LOG(INFO) << "model loaded.";
    auto in_names = wnn_model.get_input_names();
    auto out_names = wnn_model.get_output_names();
    LOG(INFO) << "input name: " << in_names[0];
    LOG(INFO) << "out name: " << out_names[0];
  } else {
    LOG(INFO) << "model might load failed.";
  }

  auto input_tensor = wnn::ones({1, 864});
  auto input_tensor2 = wnn::ones({1, 256});
  vector<wnn::Tensor> inputs;
  inputs.push_back(input_tensor);
  inputs.push_back(input_tensor2);

  wnn::Tensor output_tensor =
      wnn::Tensor({1, 752}, 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;

没有错,就是这么简单!! 输入直接 wnn::ones 或者自己构建一个tensor,指定维度,就可以前传了。 wnnx里面的Tensor是可以直接打印输出的,这个十分方便,直接 std::cout即可

可以看到输出结果:

非常简单的打印方式,非常的人性化。

再来看pytorch的结果:

pytorch只打印了前面40个值。可以看到,不能说完全一致,简直是一模一样!

再一次印证了我们的推理框架:

  • 基本上是图完备的,对于多输入处理依旧鲁棒;
  • 即便是许多算子的复杂组合,也可以得到正确的结果。

最后,最重要的一点是:

744K  6月  2 13:06 libwnn.a

目前整个前推框架,包括了基本上常用的层,麻雀虽小五脏俱全,动态库体积仅有 744K!!

下一篇,我们要进一步实现,卷积模型的推理测试!

顺便说以下,我发现ncnn里面计算layernorm竟然是naive算法。用welford会更快。