title | date | category |
---|---|---|
2022_06_06_12_WNNX从0实现AI推理引擎(五) |
2022-06-06 05:45:45 -0700 |
默认分类 |
本文介绍 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会更快。