在NPU单算子(torch_npu )执行时如何进行性能优化?以MinerU为例

1 MinerU介绍

在AI技术快速发展的今天,大量非结构化数据的处理成为亟待解决的问题。尤其是PDF文档,作为最常见的文件格式之一,如何高效准确地提取其中的信息,成为了许多企业和研究机构的痛点。上海人工智能实验室(上海AI实验室)大模型数据基座OpenDataLab团队开源了全新的智能数据提取工具——MinerU,旨在解决这一问题。

MinerU能够将混合了图片、公式、表格、脚注等复杂元素的PDF文档转化为Markdown和JSON格式,大幅提升了AI语料的准备效率。凭借快速准确、开源易用的能力特性,MinerU受到广大用户及大模型开发者青睐,上线八个月,GitHub星标数已接近3万,被开发者誉为"大模型时代的文档提取、转换神器"。

MinerU是由上海人工智能实验室OpenDataLab团队开发的开源文档解析工具,致力于解决大模型(LLM)训练和RAG(检索增强生成)应用中高质量结构化数据的提取难题。自2024年7月开源以来,GitHub星标数迅速突破2.5万,成为开发者社区的热门选择。其核心价值在于将复杂文档(如PDF、网页、电子书)转换为机器可读的Markdown、JSON格式,同时保留原始文档的语义逻辑与多模态元素。

获取MinerU 官方PPT:PDF 解析神器
MinerU.pdf

MinerU官网:MinerU

MinerU代码地址:GitHub - opendatalab/MinerU: A high-quality tool for
convert PDF to Markdown and
JSON.一站式开源高质量数据提取工具,将PDF转换成Markdown和JSON格式。

MinerU 线上demo入口:MinerU

本篇文章通过介绍其在NPU的单算子模式下的一些性能优化的手段。这些手段也可以给其他模型在torch_npu下的使用提供一些优化指导。

torch_npu上的性能调优指南,大家可以关注
PyTorch模型在NPU上的调优

2 torch_npu性能优化

2.1 绑核优化

在PyTorch的训练或推理场景,可以通过设置环境变量CPU_AFFINITY_CONF来控制CPU端算子任务的处理器亲和性,即设定任务绑核。该配置能够优化任务的执行效率,避免跨 NUMA(非统一内存访问架构)节点的内存访问,减少任务调度开销。

可选的绑核方案如下:

  • 粗粒度绑核:将所有任务绑定在NPU对应NUMA的CPU核心上,避免跨NUMA节点的内存访问,并支持粗粒度绑核上的自定义绑核。
  • 细粒度绑核:在粗粒度绑核的基础上进一步优化,将主要任务锚定在NUMA节点的某固定CPU核心上,减少核间切换的开销。

配置示例
示例一:粗粒度绑核

export CPU_AFFINITY_CONF=1

示例二:细粒度绑核

export CPU_AFFINITY_CONF=2

示例三:自定义多张NPU卡的绑核范围

export CPU_AFFINITY_CONF=1,npu0:0-1,npu1:2-5,npu3:6-6

具体可参考:torch_npu绑核优化

2.2 流水优化

  • 一级流水优化
    一级流水优化是一种通用有效的优化方法,主要是将部分算子适配任务迁移至二级流水,使两级流水负载更均衡,并减少dequeue唤醒时间。
  • 使能说明
    该特性可以通过环境变量设置,一般用于以下场景:host-bound严重的网络场景

使用方法如下:

export TASK_QUEUE_ENABLE=2

该环境变量的实现细节请参考《环境变量参考》中的“TASK_QUEUE_ENABLE”章节。

说明
ASCEND_LAUNCH_BLOCKING设置为“1”时,task_queue算子队列关闭,TASK_QUEUE_ENABLE设置不生效。
TASK_QUEUE_ENABLE配置为“2”时,由于内存并发,可能导致运行中NPU内存峰值上升。

2.2.1 TASK_QUEUE_ENABLE

通过此环境变量可配置task_queue算子下发队列是否开启和优化等级。

  • 配置为“0”时:关闭task_queue算子下发队列优化,算子下发任务如图1所示。
    关闭task_queue
    在这里插入图片描述

  • 配置为“1”或未配置时:开启task_queue算子下发队列Level 1优化,算子下发任务如图2所示。
    在这里插入图片描述
    Level 1优化:使能task_queue算子下发队列优化,将算子下发任务分为两段,一部分任务(主要是aclnn算子的调用)放在新增的二级流水上,一、二级流水通过算子队列传递任务,相互并行,通过部分掩盖减少整体的下发耗时,提升端到端性能。

  • 配置为“2”时:开启task_queue算子下发队列Level 2优化,算子下发任务如图3所示。
    Level 2优化:包含Level 1的优化并进一步平衡了一、二级流水的任务负载,主要是将workspace相关任务迁移至二级流水,掩盖效果更好,性能收益更大。该配置仅在二进制场景生效,建议配置值为Level 2优化。
    图3 Level 2优化
    在这里插入图片描述
    此环境变量默认配置为“1”。

注意
ASCEND_LAUNCH_BLOCKING设置为“1”时,task_queue算子队列关闭,TASK_QUEUE_ENABLE设置不生效。

TASK_QUEUE_ENABLE配置为“2”时,由于内存并发,可能导致运行中NPU内存峰值上升。

2.2.2 ASCEND_LAUNCH_BLOCKING

通过此环境变量可控制算子执行时是否启动同步模式

由于在昇腾NPU上进行模型训练时默认算子异步执行,导致算子执行过程中出现报错时,打印的报错堆栈信息并不是实际的调用栈信息。当设置为“1”时,强制算子采用同步模式运行,这样能够打印正确的调用栈信息,从而更容易地调试和定位代码中的问题。设置为“0”时则会采用异步方式执行。

默认配置为0。

注意 ASCEND_LAUNCH_BLOCKING设置为“1”时,强制算子采用同步模式运行会导致性能下降。
ASCEND_LAUNCH_BLOCKING设置为“1”时,task_queue算子队列关闭,TASK_QUEUE_ENABLE设置不生效。
ASCEND_LAUNCH_BLOCKING设置为“0”时,会增加内存消耗,有导致OOM的风险。 配置示例 export
ASCEND_LAUNCH_BLOCKING=1

2.3 其他常用优化操作

配置ACLNN_CACHE_LIMIT环境变量
ACLNN_CACHE_LIMIT用于配置单算子在执行API时,在Host侧缓存的算子信息条目个数。ACLNN_CACHE_LIMIT的单位为个,取值范围为[1,10000000],默认值为10000。缓存的算子信息包含workspace大小、算子计算的执行器以及tiling信息等。动态shape场景下,如算子shape范围较大时,用户可通过配置此环境变量适当增加算子缓存条目,提升调度性能。当模型遇到下发瓶颈时(尤其是问题出现在一级流水时),可以尝试此配置。配置方法如下:

export ACLNN_CACHE_LIMIT=100000

说明 增加算子信息缓存条目会增加Host内存开销,需根据实际情况适当调整。

其他优化手段还有很多,大家可以根据网络当前的性能状况,进行定向选择优化
torch_npu上其他优化手段

3 MinerU性能优化

3.1 通过torch_npu自带配置项优化

export CPU_AFFINITY_CONF=1  # 新版本可设置export CPU_AFFINITY_CONF=2export TASK_QUEUE_ENABLE=2export ACLNN_CACHE_LIMIT=100000

关键优化手段主要包括如上三个环境变量,800T A2单卡优化约30%,其他手段优化效果不明显,投入产出比不高。

3.2 其他优化

3.2.1 OM优化

端到端推理过程中,rapid_table 使用了onnx。默认执行方式会运行在CPU侧,可以使用OM 静态图(TorchAir) 加速推理。

如下onnx图中,在靠近结尾处(图中A处)包含了Loop算子,无法直接转换成OM格式:

在这里插入图片描述
有两种可行的方案:

  1. 提取Loop算子的子图,手动进行循环控制,工作量较大
  2. 对onnx图进行粗粒度切分,Loop算子包括子图直接运行在CPU上,工作量较小

当前选取方案2,在上图中的B处对onnx进行切分。打点分析可知onnx输入是静态shape,因此可以成静态图,使用om+onnx混合推理。

切分代码如下:

import onnx
onnx.utils.extract_model("slanet-plus-sim.onnx","slanet-plus-front.onnx", ["x"], ["hardswish_72.tmp_0"], check_model=False)onnx.utils.extract_model("slanet-plus-sim.onnx","slanet-plus-rear.onnx",["hardswish_72.tmp_0"], ["save_infer_model/scale_0.tmp_0", "save_infer_model/scale_1.tmp_0"], check_model=False)

onnx.utils.extract_model是用于子模型的提取,可以参考如下
Onnx子模型提取

模型切割后,在推理过程中,即可根据输入的参数进行判断,如下以shape进行判断,如

# 调用前先判断shape,避免其他shape的输入
def infer(self, x: List):if x[0].shape == (xx,xxx):front_out = self.static_infer(x)else:front_out = self.single_op_infer(x)

当遇到x的时候才进行静态shape的优化。

由于rapid_table时间占比有限,在100个pdf上进行的测试结果显示可以优化1~2%

3.2.2 高性能内存库

tcmalloc(即Thread-Caching Malloc)是一个通用的内存分配器,通过引入多层次缓存结构、减少互斥锁竞争、优化大对象处理流程等手段,在保证低延迟的同时也提升了整体性能表现。这对于需要频繁进行内存操作的应用来说尤为重要,尤其是在高并发场景下能够显著改善系统响应速度和服务质量。
内存分配高性能库
性能可以提升1%~2%

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/web/86640.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙OS开发IoT控制应用:从入门到实践

引言:万物互联时代的应用开发新范式 在物联网(IoT)技术迅猛发展的今天,智能设备数量呈指数级增长。据IDC预测,到2025年全球IoT连接设备数将达到416亿台。面对碎片化的IoT设备和多样化的控制需求,华为鸿蒙OS(HarmonyOS)应运而生&a…

五层网络模型:网络通信的核心框架

在网络通信的世界里,五层网络模型是一个基础而关键的概念。它帮助我们理解数据是如何在网络上从一个设备传输到另一个设备的。本文将详细介绍五层网络模型的每一层,以及它们在数据传输过程中的作用。 一、五层网络模型概述 五层网络模型是一种分层的网…

常见的强化学习算法分类及其特点

强化学习(Reinforcement Learning, RL)是一种机器学习方法,通过智能体(Agent)与环境(Environment)的交互来学习如何采取行动以最大化累积奖励。以下是一些常见的强化学习算法分类及其特点&#…

【LeetCode 热题 100】438. 找到字符串中所有字母异位词——(解法三)不定长滑动窗口+数组

Problem: 438. 找到字符串中所有字母异位词 题目:给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 【LeetCode 热题 100】438. 找到字符串中所有字母异位词——(解法一&…

求区间最大值

题目描述 给定一个长度为 N 的数列,和 M 次询问,求出每一次询问的区间内数字的最大值。 输入描述 第一行包含两个整数 N,M,分别表示数列的长度和询问的个数。 第二行包含 N 个整数(记为𝑎𝑖)&am…

调试HDMI音频能8通道播放声音

一、使用场景 我们是通过rk主控的hdmi接口播放音视频给到ite68051芯片解析出8声道数据,分别通过4路i2s的数据脚给给到fpga去解析 调试步骤: 1.根据相关手册配置hdmi输出,hdmi声卡注册,如下: hdmi0_sound: hdmi0-sound {status = "disabled";compatible = &qu…

PowerBI 柱状图显示MoM销量环比示例,以及解决相同列值时设置柱子颜色的问题

先看效果: 假设有Sales表: 1. 我们先给它新增一个计算列,显示销售日期的年月 销售日期YYYYMM YEAR(Sales[销售日期])*100 MONTH(Sales[销售日期]) 2. 然后新增一个计算表,用于保存当前最大的销售日期,和上一个月的日期 DateComparisonT…

【docker】构建时使用宿主机的代理

docker构建过程中报错: pip 下载失败 解决办法:传递宿主机的代理 把宿主机的 HTTP_PROXY/HTTPS_PROXY 传进去,导致容器内的 pip 依然连不上代理,下载 build-dependencies(比如 setuptools)就会失败。 下面两步即可解决: Docker 构建阶段,127.0.0.1:7890 指向的是 容…

[Java 基础]算法

什么是算法 程序 数据结构 算法 算法(Algorithm)就是解决问题的步骤,就像做菜的食谱一样,告诉计算机一步一步如何完成任务。 例如: 排序算法:把一堆数字从小到大排列搜索算法:在一堆数据里…

C++理解for循环 计算题三

计算a的值 #include <iostream> using namespace std; int main() { int a0;for(int i0;i<3;i){for(int j0;j<3;j){aij;}}cout<<"a的值是 "<<a<<endl; return 0; } 计算a的值 #include <iostream> using namespace std; int …

梳理React中的fiber架构

文章目录 产生背景核心概念工作原理工作流程优势特点 产生背景 在React16之前使用的虚拟DOM是数组的形式&#xff0c;又因为React本身是应用级框架&#xff0c;状态改变后并不能准确知道是哪个组件发生了改变&#xff0c;只能对整个应用进行diff协调&#xff0c;受限于虚拟DOM…

Modbus 数据模型:线圈、寄存器与功能码详解(二)

三、Modbus 功能码详解 3.1 功能码分类与作用 Modbus 功能码是 Modbus 通信协议中的关键组成部分&#xff0c;它如同一个 “指令指挥官”&#xff0c;在通信事务处理中扮演着核心角色。功能码占用 1 个字节的空间&#xff0c;取值范围为 1 到 255 &#xff08;0x01 - 0xFF&am…

多表连接查询:语法、注意事项与最佳实践

&#x1f517; 多表连接查询&#xff1a;语法、注意事项与最佳实践 多表连接是 SQL 的核心能力&#xff0c;用于关联多个表的数据。以下是深度解析&#xff0c;涵盖语法规范、性能陷阱及实战技巧&#xff1a; &#x1f4dc; 一、多表连接语法大全 1. 显式连接&#xff08;推荐…

使用Calibre对GDS进行数据遍历

在芯片的GDS数据里&#xff0c;使用Calibre对数据进行处理是非常常见的操作&#xff0c;但是GDS是一种和常规设计结构不太一样的一种数据&#xff0c;这里&#xff0c;通过这个小小的科普文章&#xff0c;一起看看怎么样在GDS里边做数据漫游吧&#xff01;闲言少叙&#xff0c;…

PyQtNode Editor 第二篇自定义可视化视图

在第一篇博客中,我们已经完成了 PyQtNode Editor 的基础环境搭建,并深入解析了自定义图形场景QDMGraphicsScene的实现原理。那个带有网格背景的场景就像一张空白的图纸,现在我们要在这张图纸上开始绘制真正的节点系统。 今天我们将聚焦于节点编辑器的核心数据结构设计,实现…

【扩欧应用】同余方程

与扩欧的联系 在同余方程的求解过程中&#xff0c;我们通常需要将方程转化为线性不定方程&#xff08;Diophantine 方程&#xff09;的形式&#xff0c;然后使用扩展欧几里得算法&#xff08;Extended Euclidean Algorithm, EEA&#xff09;求解。 同余方程是怎么转化为线性不…

结构化数据:NumPy 的结构化数组

文章目录 结构化数据&#xff1a;NumPy 的结构化数组探索结构化数组的创建更高级的复合类型记录数组&#xff1a;结构化数组的变体走向 Pandas 结构化数据&#xff1a;NumPy 的结构化数组 虽然我们的数据通常可以用同质数组很好地表示&#xff0c;但有时情况并非如此。本文将演…

phpcms 更换新域名更新栏目url和内容页url无法更新解决方法

更换域名后更新栏目url和内容页url还是无法更新为新的域名&#xff0c;手动把cache文件夹下能清除的缓存文件清除了还是不行&#xff0c;把数据库的缓存表内容清空了还是不行&#xff0c;问题在于栏目缓存并没有清除。 解决办法: (1)、找到文件&#xff1a;/caches/configs/sys…

玛哈特七辊矫平机:板材平整的精密卫士

在金属板材加工领域&#xff0c;表面平整度是衡量产品质量的核心指标之一。无论是汽车覆盖件、精密仪器外壳&#xff0c;还是建筑装饰板材&#xff0c;任何弯曲、波浪或翘曲都将严重影响后续加工精度、产品强度及美观度。七辊矫平机&#xff0c;凭借其独特的辊系结构设计&#…

融合聚类与分类的退役锂电智能分选技术:助力新能源汽车产业可持续发展

融合聚类与分类的退役锂电智能分选技术&#xff1a;助力新能源汽车产业可持续发展 关键词&#xff1a;退役锂离子电池分选 | 聚类分类融合 | 电化学阻抗谱(EIS) | 动态时间规整(DTW) | 多模态分类模型 新能源汽车 | 电池梯次利用 | 增量学习 | 数字孪生 | 联邦学习 | 双流特征…