惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cyberwarzone
Cyberwarzone
F
Full Disclosure
V
Visual Studio Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
有赞技术团队
有赞技术团队
J
Java Code Geeks
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
L
LINUX DO - 最新话题
T
Threatpost
S
SegmentFault 最新的问题
Vercel News
Vercel News
云风的 BLOG
云风的 BLOG
C
Cyber Attacks, Cyber Crime and Cyber Security
Google DeepMind News
Google DeepMind News
Know Your Adversary
Know Your Adversary
S
Schneier on Security
V
Vulnerabilities – Threatpost
D
DataBreaches.Net
G
GRAHAM CLULEY
Latest news
Latest news
P
Privacy International News Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
Scott Helme
Scott Helme
L
Lohrmann on Cybersecurity
T
The Exploit Database - CXSecurity.com
Security Latest
Security Latest
G
Google Developers Blog
L
LangChain Blog
MyScale Blog
MyScale Blog
Project Zero
Project Zero
N
News and Events Feed by Topic
Hacker News - Newest:
Hacker News - Newest: "LLM"
大猫的无限游戏
大猫的无限游戏
P
Proofpoint News Feed
Blog — PlanetScale
Blog — PlanetScale
阮一峰的网络日志
阮一峰的网络日志
N
News | PayPal Newsroom
www.infosecurity-magazine.com
www.infosecurity-magazine.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
SecWiki News
SecWiki News
T
Tor Project blog
C
Check Point Blog
Google Online Security Blog
Google Online Security Blog
GbyAI
GbyAI
The Last Watchdog
The Last Watchdog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
WordPress大学
WordPress大学

Пусть этот камень будет более крепким, чем человек

【琐记】烟火与尘埃 【Triton】Triton实现矩阵乘 【LLM推理加速】FlashAttention 【LLM推理加速】PagedAttention 【LLM推理加速】Online Softmax LLM基础知识【1】 Transformer模型 【AI编译】LayerGroup Tiling Tile的疑惑和思考 【AI编译】深度优先的Tile调度,万事大吉? 【AI编译】多级流水线Tile调度策略 【CUDA C++】GPU内存使用【3】 【AI编译】Cache缓存地址映射 【CUDA C++】GPU存储【2】 【CUDA C++】GPU基本介绍【1】 【00】0序章-不受欢迎的来客 【转载】我来了——持续低熵 【Halide】调度优化【2】 【感想】写作进度报告5 【Halide】调度优化【1】 【转载】北大中文男足战报2 【BYOC】TVM切分子图 【转载】北大中文男足战报1 【AI编译】张量生命周期管理 SystemC 用寄存器同步建模方法 【脉动阵列】脉动阵列类型 【im2col】AScend conv accelerate 【感想】写作进度报告4 【BYOC】TVM添加自定义编译器 ccompiler 【感想】写作进度报告3 【Tengine】推理流程脑图【1】 【NCNN】学习ncnn模型转换 【编译器】使用llvm编译自定义语言【3】编译 object 【编译器】使用llvm编译自定义语言【2】转llvm IR 【编译器】使用llvm编译自定义语言【1】构建AST 【AI编译】如何进行内存分配 【感想】写作进度报告2 【AI编译】layer-group之后如何tiling 【AI编译】如何进行layer-group 【量化】连续卷积层首尾量化的可行性 【Gemm】内存对齐 【gemm】Gemm计算加速 【TVM】通过代码学习编译流程【5】FuseOps 【TVM】通过代码学习编译流程【6】CodeGen 【TVM】通过代码学习类【3.5】Pass 【TVM】通过代码学习编译流程【4】BuildRelay 【AI编译】Tiling操作能优化什么时间 【TVM】通过代码学习编译流程【3】模型编译 【TVM】通过代码学习编译流程【2】模型转换 【TVM】通过代码学习编译流程【1】必要知识 【感想】写作进度报告1 【Winograd】卷积加速算法原理及实现 SystemC 等待异步事件解决方案 【TVM】Python脚本实现模型编译和保存 【推理引擎】常见AI推理框架 【3D建模】T110E3卡迪夫蓝调皮肤模型 【TVM】C++部署运行TVM 【推理引擎】NCNN和Tengine量化推理逻辑对比 【3D建模】IS-7攻城锤流纹岩皮肤展示 【TVM】根据例子走通代码库 博客汇总目录 【Im2Col】卷积加速算法【2】NHWC 【Im2Col】卷积加速算法【1】 NCHW openBlas库的安装与简单使用 C语言工程调用Cpp库解决方案 foo Hello World
【Tengine】推理流程脑图【2】
Post author: XianMu@Пусть этот камень будет более крепким, чем ч · 2025-04-27 · via Пусть этот камень будет более крепким, чем человек

# 前言

本篇通流程脑图和代码介绍 Tengine 推理引擎的推理流程。本篇是第二篇。第一篇地址Tengine 工程地址

作为初学者,错误在所难免,还望不吝赐教。

# 介绍

Tengine

Tengine 由 OPEN AI LAB 主导开发,该项目实现了深度学习神经网络模型在嵌入式设备上的快速、高效部署需求。为实现在众多 AIoT 应用中的跨平台部署,该项目使用 C 语言进行核心模块开发,针对嵌入式设备资源有限的特点进行了深度框架裁剪。同时采用了完全分离的前后端设计,有利于 CPU、GPU、NPU 等异构计算单元的快速移植和部署,降低评估、迁移成本。

# 总流程图

总流程图:

Tengine推理流程图

init_tengine()create_graph() 流程位于第一篇地址中。

# prerun_graph_multithread()

prerun_graph_multithread推理流程图

该函数是神经网络模型运行前的与运行流程。从流程图中看,其主要调用了三个函数。

# 1.infer_ir_graph_shape()

推理引擎要根据输入 tensor 的维度来推理输出 tensor 的维度。例如某个卷积节点的输入维度是【1,32,128,128】,依据 kernel 大小计算出输出维度【1,64,128,128】。所以该函数会按顺序执行所有节点,并调用每个节点的 op->infer_shape 方法(前述提到过),完成整个模型的 tensor 维度推理。

# 2.optimizer->split_graph()

切分子图。这是一个为了实现多设备运行而实现的方法,即通过切分子图实现。

当前已有一个总图,包含模型所有的节点。而设备可能包括 CPU、GPU、NPU、DNNL 等等,而这些设备可能仅支持一部分算子,这就要求将总图切分成设备支持的子图,和设备不支持的子图。设备支持的子图交给设备运行,不支持的交给 CPU 执行。

经过这个函数之后,子图就变成一各执行单元。

# 3.schedule->prerun()

预运行,其调用的是 interface->prerun() ,即前述的,和设备相关的接口中的 prerun() 函数。其又调用了三个函数:

create_exec_graph() :为每个子图创建执行子图。

通过 find_node_ops() 函数,找到节点的所有执行方式。前述卷积算法,就注册了三种执行方式。

ret = register_conv_ref_op();
    ret = register_conv_dw_hcl_x86_op();
    ret = register_conv_hcl_x86_op();

找到所有执行方式之后,调用每种执行方式的 node_ops->score() 函数,获得一个得分。例如 conv_hcl_x86_op 这种实现方式,其 score() 函数如下。它根据该节点的参数返回一个得分。

static int score(struct node_ops* node_ops, struct exec_graph* exec_graph, struct node* exec_node)
{
    struct node* ir_node = exec_node;
    struct graph* ir_graph = ir_node->graph;
    struct tensor* input_tensor = get_ir_graph_tensor(ir_graph, ir_node->input_tensors[0]);
    struct tensor* output_tensor = get_ir_graph_tensor(ir_graph, ir_node->output_tensors[0]);
    struct conv_param* param = (struct conv_param*)exec_node->op.param_mem;
    int group = param->group;
    int kernel_h = param->kernel_h;
    int kernel_w = param->kernel_w;
    int in_c = input_tensor->dims[1] / group;
    int out_c = output_tensor->dims[1] / group;
    if (input_tensor->data_type != TENGINE_DT_FP32 && input_tensor->data_type != TENGINE_DT_UINT8 && input_tensor->data_type != TENGINE_DT_INT8)
        return 0;  
    if (group != 1)
        return 0;  
    return OPS_SCORE_PREFER;   
}

得分分为以下几档:

#define OPS_SCORE_STATIC 10000
#define OPS_SCORE_BEST   8000
#define OPS_SCORE_PREFER 6000
#define OPS_SCORE_CANDO  4000
#define OPS_SCORE_NOTSUP 2000

推理引擎将选择得分最高的作为执行方法,而得分低于 4000 的方法不可使用。

下一步是调用 node_ops->init_node() 函数,是初始化节点预留的接口。

通过 prerun_exec_graph() 函数调用 node_ops->prerun() ,这个是节点预运行而预留的接口。

# run_graph()

run_graph推理流程图

到这里才开始实际执行图的每个节点。

和前述一样,还是调用和设备相关的接口 interface->run() ,先调用每个算子的 node_ops->reshape() 函数,从工程中来看该函数仍然是在做维度推理的工作,与前述的 infer_shape() 相同。似乎是重复的做法,不过不同之处在于前述的 infer_shape() 只在模型构建完成之后运行一次,而这个 reshape() 函数在算子每次执行之前都要调用。

可能是为了防止模型的每次运行,输入 tensor 大小都不一样?毕竟神经网络模型通常会不断输入数据,重复运行。(当开发者确定每次输入输入维度一致时,这里的运算就有些浪费时间了。)

然后调用算子的具体执行: node_ops->run()

# postrun_graph()

postrun_graoh推理流程图

图的后处理。

调用每个节点的后运行 node_ops->postrun()

调用子图的释放函数 release_exec_graph() ,调用每个节点的释放函数 node_ops->release_node()

# destroy_graph()

destroy_graph推理流程图

调用整个图的释放函数 interface->release_graph()

一张脑图就帮我们整体把握 Tengine 推理引擎。

# 后记

本博客目前以及可预期的将来都不会支持评论功能。各位大侠如若有指教和问题,可以在我的 github 项目 或随便一个项目下提出 issue,并指明哪一篇博客,我看到一定及时回复!