-
前言关于单点性能调优的帖子很多,这里从基础理论、实战演练、现网案例三个维度汇总单点性能调优的方法基础理论analyze统计信息https://bbs.huaweicloud.com/blogs/192029explain计划信息https://bbs.huaweicloud.com/blogs/197945分布式计划详解https://bbs.huaweicloud.com/blogs/200449实战演练总体调优策略https://bbs.huaweicloud.com/blogs/200906味道SQL识别https://bbs.huaweicloud.com/blogs/197413好味道表定义https://bbs.huaweicloud.com/blogs/203219SQL改写https://bbs.huaweicloud.com/blogs/203420路径干预https://bbs.huaweicloud.com/blogs/212459Plan hint运用https://bbs.huaweicloud.com/blogs/213195现网案例单点性能案例集锦https://bbs.huaweicloud.com/forum/thread-90331-1-1.html
-
【功能模块】用VSCode 安装性能分析工具报空间不足安装过程:【操作步骤&问题现象】报错:请帮忙查看该问题【日志信息】(可选,上传日志内容或者附件)
-
【功能模块】【操作步骤&问题现象】1、-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/ruijie/diagon/logs/analysis-model-ipb2、-Xlog:all:file=/tmp/gc-%p-%t.log:tags,uptime,time,level:filecount=10,filesize=50m【截图信息】【日志信息】(可选,上传日志内容或者附件)
-
【操作步骤&问题现象】1、添加采样分析报错,且采样状态卡死【截图信息】
-
【操作步骤&问题现象】1、连接目标环境 非root账户 报联系管理2、具体需要那个写文件权限【截图信息】
-
1 调优概述鲲鹏性能分析工具是一款针对鲲鹏平台的性能调优工具,包含系统性能分析、Java性能分析和诊断调试分析三大功能。本调优实践使用的是系统性能分析,针对在虚拟机上部署的Redis性能不高问题,通过执行访存分析任务,找到性能瓶颈和问题点,并根据分析结果进行优化,从而实现Redis数据库性能的提高。2 组网环境表2-1服务器类型KVM虚拟机(基于TaiShan 200服务器(型号2280)部署)配置信息4U8G100GOSCentOS 7.6(内核:4.14.0-115.el7a.0.1.aarch64)应用Redis 5.0性能测试工具redis-benchmark(Redis自带工具)说明: 本实践环境配置信息只用作举例,在其他环境上相关操作类似。3 前提条件 服务器和操作系统正常运行。 目标环境(服务器)上3.T10版本工具已经安装完成,并正常运行。 目标环境(服务器)上已安装好数据库和性能测试工具。4 调优思路 启动Redis数据库服务,使用redis-benchmark工具对数据库进行加压测试。检查压测结果,发现性能指标不是很高。 重新运行压测,同时使用Hyper Tuner工具的访存分析,以整个系统作为采集分析对象创建任务,采样类型全部勾选,根据分析任务分析结果进行分析,根据已有的调优经验或手段进行调优。 重新运行压测工具,检查性能是否得到提升。5 调优过程5.1 执行压测 1.启动Redis数据库服务。 2.使用自带的压测工具在本地对数据库进行压力测试。压测参考命令如下图所示(没有指定特定的压测项,会对所有项进行压测),指定-c 50个并发,-n 10万个请求,-q 只打印最后结果。 3. 检查压测结果通过对压测结果的数据进行分析,发现性能并不是很高,没有达到预期的结果。根据Redis的特点是基于内存的数据库,使用系统性能分析工具的访存分析能力尝试对数据库性能进行分析,找出性能问题点。表5-1类型RPS(requests per second)PING_INLINE47915.67PING_BULK53022.27SET67069.08GET60606.06INCR62073.25LPUSH72463.77RPUSH69300.07LPOP68493.15RPOP70126.23SADD67294.75HSET71633.23SPOP61236.99LPUSH (needed to benchmark LRANGE)72992.70LRANGE_100 (first 100 elements)29859.66LRANGE_300 (first 300 elements)14432.10LRANGE_500 (first 450 elements)10914.65LRANGE_600 (first 600 elements)8775.78MSET (10 keys)72046.11 5.2 执行访存分析1.在后台使用相同的压测参数执行压测,同时在性能分析工具上创建访存分析任务,配置参数如下图所示,利用访存统计分析,检查系统缓存访问和DDR访问情况。 2.任务执行完成后检查任务结果。**在“总览”界面通过查看Core Cache Miss平均值,发现相关指标的值都比较高;而iCache Bandwidth和dCache Bandwidth平均值不是很高,与理论带宽有一定差距。**在“访存访问”页面,可以看到L1D和L2D的带宽也不是很高,对应的L1D命中率在0.98,L2D的命中率在0.82左右。**在“DDR访问”页面可以看到,DDR访问中存在较多的跨DIE访问,相对于本地访问次数的占比超过了50%。总览结果页面:访存访问结果页面:DDR访问结果页面: 3.通过以上访存分析结果,再根据当前服务器类型使用的是虚拟机。分析可能原因:部署的虚拟机的方式,在默认情况下不同虚拟机的vCPU可能运行在相同物理CPU核上,会造成CPU资源竞争,同一个虚拟机在不同时间也可能会运行在不同的物理核上,会造成cache miss的情况。另外也可能出现虚拟机内存访问出现跨die和跨片情况。针对以上情况,可进行的调优手段是,对虚拟机的vCPU进行绑核,绑到同一个NUMA节点上,同时可以将虚拟机内存访问绑到对应的NUMA节点上,可避免出现内存跨die和跨片情况。 5.3 性能优化1、检查虚拟机的配置文件。发现使用的是默认配置,配置文件里的确没有绑核和绑定内存访问的相关配置项。2.手动进行配置项修改,在宿主机上修改虚拟配置文件(命令:virsh edit 虚拟机domian)。在配置文件里配置<numatune>和<cputune>选项,配置项参考如下: <cputune> <vcpupin vcpu='0' cpuset='50'/> <vcpupin vcpu='1' cpuset='51'/> <vcpupin vcpu='2' cpuset='52'/> <vcpupin vcpu='3' cpuset='53'/> <emulatorpin cpuset='50-53'/> </cputune> <numatune> <memory mode='strict' nodeset='1'/> </numatune>将虚拟机的vCPU核绑到对应的物理机的50-53核上,这些物理核所在的NUMA节点为node1,因此将虚拟机的内存访问同时绑到node1这个节点上,模式采用“strict”严格从指定node上申请内存。修改后保存并退出。3、关掉虚拟机(命令:virsh shutdown 虚拟机domian),再重启虚拟机(命令:virsh start 虚拟机domian)。5.4 再次执行访存分析和压测 1.执行访存分析(同时运行压测),查看结果。总览结果界面:Core Cache Miss平均值,发现相关指标的值相比调优前有所降低;而iCache Bandwidth和dCache Bandwidth平均值有所提高。缓存访问结果页面:可以看到L1D带宽有所提高,对应的L1D命中率在0.98,L2D带宽和命中率略有下降,说明CPU cache使用集中在L1上。DDR访问结果页面:DDR访问中,跨片访问次数极低,读DDR跨DIE访问相对本地访问占比在15%,写DDR跨DIE访问也极低。 2.重新单独执行压测。表5-2类型RPS(requests per second)PING_INLINE65104.17PING_BULK62539.09SET71479.62GET65659.88INCR72046.11LPUSH77279.75RPUSH74906.37LPOP75872.54RPOP71839.09SADD71275.84HSET75872.54SPOP66800.27LPUSH (needed to benchmark LRANGE)77101.00LRANGE_100 (first 100 elements)30959.75LRANGE_300 (first 300 elements)14619.88LRANGE_500 (first 450 elements)11106.18LRANGE_600 (first 600 elements)8823.79MSET (10 keys)72833.21 通过测试的结果可以看到性能数据有所提升。 6. 实践结论1.性能结果对比表6-1类型RPS(requests per second)性能对比调优前调优后PING_INLINE47915.6765104.17+35.9%PING_BULK53022.2762539.09+17.9%SET67069.0871479.62+6.6%GET60606.0665659.88+8.3%INCR62073.2572046.11+16.1%LPUSH72463.7777279.75+6.6%RPUSH69300.0774906.37+8.1%LPOP68493.1575872.5410.1%RPOP70126.2371839.092.4%SADD67294.7571275.84+5.9%HSET71633.2375872.54+5.9%SPOP61236.9966800.27+9.1%LPUSH (needed to benchmark LRANGE)72992.7077101.00+5.6%LRANGE_100 (first 100 elements)29859.6630959.75+3.7%LRANGE_300 (first 300 elements)14432.1014619.88+1.3%LRANGE_500 (first 450 elements)10914.6511106.18+1.8%LRANGE_600 (first 600 elements)8775.788823.79+0.5%MSET (10 keys)72046.1172833.21+1.1%通过调优前后性能数据的对比,每一个压测指标项的性能都得到了不同程度的提升。整体性能的提升达到了+8.16%,说明优化的效果是比较明显的。 2.总结本次调试实践,主要是针对在虚拟机平台上利用Hyper Tuner系统性能分析工具的访存分析能力对Redis数据库性能不高问题的分析。根据分析结果发现的问题进行分析,并利用已有的相关调优经验实施调优,最终使性能得到了较大的提升。
-
基于鲲鹏Boostkit进行MySQL性能调优该实验旨在指导用户短时间内了解MySQL数据库编译流程及MySQL数据库参数对性能的影响。1.准备实验环境登录华为云,购买ECS服务器,要求服务器规格:鲲鹏通用计算增强型 | kc1.4xlarge.2 | 16vCPUs | 32GB镜像:Centos7.6系统盘:默认40G数据盘:挂载200G登录弹性云服务器ECS挂载数据盘登录云服务器,执行以下命令获取自动初始化磁盘脚本。wget https://ecs-instance-driver.obs.cn-north-1.myhuaweicloud.com/datadisk/LinuxVMDataDiskAutoInitialize.sh修改自动初始化磁盘脚本权限chmod -x LinuxVMDataDiskAutoInitialize.sh执行初始化脚本自动检测待初始化的数据盘。sh LinuxVMDataDiskAutoInitialize.sh脚本将自动检测当前在服务器上除系统盘之外的盘符并显示出来,如/dev/vdb,然后需要输入要执行的盘符,例如 /dev/vdbStep 3:输入 /dev/vdbStep 5:输入 /data挂载信息,使用df -h,查看挂载信息2.准备MySQL环境安装相关的依赖库执行如下命令安装依赖库:yum -y install ncurses ncurses-devel libaio-devel gmp gmp-devel mpfr mpfr-devel libmpc libmpc-devel zlib-devel net-tools cmake openssl openssl-devel gcc-c++安装cmake系统自带的CMake软件不能满足当前数据库版本的编译要求,需要升级CMake版本至3.4.3或者以上,这里以升级到3.5.2版本为例,执行如下命令下载cmake:cd /home;wget https://cmake.org/files/v3.5/cmake-3.5.2.tar.gz执行如下命令解压安装包:tar -zxvf cmake-3.5.2.tar.gz执行如下命令进入cmake文件夹并运行bootstrap脚本【需等待约3分钟】:cd cmake-3.5.2;./bootstrap执行如下命令编译:make -j 16(参数-j后数字为CPU核数 充分利用多核CPU优势,加快编译速度,可用“cat /proc/cpuinfo | grep processor | wc -l”进行查看)执行如下命令安装cmake:make install执行如下命令确认cmake版本是否为3.5.2:/usr/local/bin/cmake -version;gcc升级yum install centos-release-scl –y;yum install devtoolset-7-gcc* -yscl enable devtoolset-7 bash执行如下命令查看gcc版本:gcc -v安装软件下载安装包并进行编译安装cd /home;wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-boost-5.7.27.tar.gz --no-check-certificate;解压文件夹并进入目录:tar -zxvf mysql-boost-5.7.27.tar.gz;建立一个编译目录,进入编译目录,配置mysql:cd /home/mysql-5.7.27/;mkdir build;cd build;cmake .. -DBUILD_CONFIG=mysql_release -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/data/mysql/data -DWITH_BOOST=/home/mysql-5.7.27/boost/boost_1_59_0make -j 16,这里编译一般会提示报错,请按照如下步骤进行修改 如未报错可忽略,直接执行make -j 16 install继续:cd /home/mysql-5.7.27/sql/,将附件工具包中的文件mysqld.cc上传至该目录,替换原有文件;然后重新执行命令安装,cd /home/mysql-5.7.27/buildcp /usr/include/sys/prctl.h /home/mysql-5.7.27/include;make -j 16;make -j 16 install;编译安装成功,下面开始启动mysql3.启动MySQL添加用户执行如下命令添加用户组mysql:groupadd mysql执行如下命令添加用户mysql属于mysql用户组里:useradd -g mysql mysql执行如下命令进入到目录里:mkdir /data/mysql/cd /data/mysql/执行如下命令分别创建4个目录:mkdir data tmp run log执行如下命令,指定文件的拥有者为用户组(mysql)里的用户(mysql),-R表示指定目录以及其子目录下的所有文件:chown -R mysql:mysql /data配置信息修改配置文件my.cnf:rm -f /etc/my.cnf;echo -e "[mysqld_safe]\nlog-error=/data/mysql/log/mysql.log\npid-file=/data/mysql/run/mysqld.pid\n[mysqldump]\nquick\n[mysql]\nno-auto-rehash\n[client]\ndefault-character-set=utf8\nsocket=/data/mysql/run/mysql.sock\n[mysqld]\nbasedir=/usr/local/mysql\ntmpdir=/data/mysql/tmp\ndatadir=/data/mysql/data\ndefault_authentication_plugin=mysql_native_password\nport=3306\nuser=mysql\n" > /etc/my.cnf;cat /etc/my.cnf;chown mysql:mysql /etc/my.cnf配置环境变量:echo export PATH=$PATH:/usr/local/mysql/bin >> /etc/profile;source /etc/profile运行/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --initialize --basedir=/usr/local/mysql --datadir=/data/mysql/data,上方命令执行后回显信息中最后一行中有初始密码,请注意保存,后续会用到。 例:U4N!8Gw1Zqcl启动数据库:su mysql;/usr/local/mysql/bin/mysqld_safe --basedir=/usr/local/mysql --datadir=/data/mysql/data &可以看到mysql进程已启动:ps -ef | grep mysql以mysql用户登录数据库:/usr/local/mysql/bin/mysql -uroot -p -S /tmp/mysql.sock(此时登录密码为上步骤记录的初始密码)登录数据库后,配置数据库账号密码:alter user 'root'@'localhost' identified by "123456";create user 'root'@'%' identified by '123456';grant all privileges on *.* to 'root'@'%';flush privileges;exit下面切换回root用户,登录数据库并对数据库进行性能测试:su root,输入登录密码;ln -s /tmp/mysql.sock /data/mysql/run/mysql.sockmysql -u root -p,此时输入密码为重新设置的密码123456exit3.Sysbench测试安装测试工具Sysbench安装依赖包:cd /homeyum -y install automake libtool* mysql-devel然后获取sysbench源码包,wget https://github.com/akopytov/sysbench/archive/0.5.zip --no-check-certificatemv 0.5.zip sysbench-0.5.zip注:在线下载可能较慢,建议可直接将附件包上传至服务器/home目录下,效果一样解压:unzip sysbench-0.5.zip编译安装:cd /home/sysbench-0.5/sysbench/drivers/mysql将工具包中的:drv_mysql.c配置文件进行覆盖替换,否则编译报错:cd /home/sysbench-0.5./autogen.sh./configure make -j16 make -j16 install运行Sysbench登录MySQL数据库服务器,创建数据库sysbench:/usr/local/mysql/bin/mysql -u root -p,输入设置的mysql登录密码,本实验设置密码为 123456创建数据库sysbench:create database sysbench;show databases;use sysbench;show tables;Exit;退出mysql数据库,下面加载数据进行测试#执行如下命令生成测试数据,数据量为250张表*25000数据/home/sysbench-0.5/sysbench/sysbench --db-driver=mysql --test=/home/sysbench-0.5/sysbench/tests/db/parallel_prepare.lua --oltp-test-mode=complex --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-db=sysbench --mysql-user=root --mysql-password=123456 --max-time=7200 --max-requests=0 --mysql-table-engine=innodb --oltp-table-size=25000 --oltp-tables-count=250 --rand-type=special --rand-spec-pct=100 --num-threads=60 prepare#进行测试/home/sysbench-0.5/sysbench/sysbench --test=/home/sysbench-0.5/sysbench/tests/db/oltp.lua --db-driver=mysql --debug=off --mysql-db=sysbench --mysql-password=123456 --oltp-tables-count=64 --oltp-index-updates=10 --oltp-non-index-updates=0 --oltp-table-size=25000 --num-threads=100 --max-requests=0 --max-time=60 --oltp-auto-inc=off --mysql-engine-trx=yes --oltp-test-mod=complex --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --oltp-user-delay-min=10 --oltp-user-delay-max=100 --report-interval=10 run执行完成之后,取其中的transactions和read/write requests作为测试指标:transactions:每秒事务数。read/write requests:每秒读写请求4.性能调优记录调优前初始测试结果:实施优化并记录调优结果措施1:内存参数调优vi /etc/sysctl.conf 将vm.swappiness = 0 修改为 vm.swappiness = 1; 保存并退出。sysctl -p;echo 5 > /proc/sys/vm/dirty_ratio执行测试:/home/sysbench-0.5/sysbench/sysbench --test=/home/sysbench-0.5/sysbench/tests/db/oltp.lua --db-driver=mysql --debug=off --mysql-db=sysbench --mysql-password=123456 --oltp-tables-count=64 --oltp-index-updates=10 --oltp-non-index-updates=0 --oltp-table-size=25000 --num-threads=100 --max-requests=0 --max-time=60 --oltp-auto-inc=off --mysql-engine-trx=yes --oltp-test-mod=complex --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --oltp-user-delay-min=10 --oltp-user-delay-max=100 --report-interval=10 run查看性能提升效果并记录措施2:MySQL配置文件调优实施记录:cd /etc/修改mysql配置文件my.cnf,替换为附件工具包中的文件:重新启动mysql数据库:mysql -u root -pshutdown;exit/usr/local/mysql/bin/mysqld_safe --basedir=/usr/local/mysql --datadir=/data/mysql/data &修改配置重启数据库时间较长,可以查看日志确认mysql启动完全后再执行测试。然后执行测试:/home/sysbench-0.5/sysbench/sysbench --test=/home/sysbench-0.5/sysbench/tests/db/oltp.lua --db-driver=mysql --debug=off --mysql-db=sysbench --mysql-password=123456 --oltp-tables-count=64 --oltp-index-updates=10 --oltp-non-index-updates=0 --oltp-table-size=25000 --num-threads=100 --max-requests=0 --max-time=60 --oltp-auto-inc=off --mysql-engine-trx=yes --oltp-test-mod=complex --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --oltp-user-delay-min=10 --oltp-user-delay-max=100 --report-interval=10 run可以看到OLTP INDEX 写场景性能有了极大提升。
-
1. 直接上结果,最终性能调优对比如下:注意的是,根据环境系统负载,数据存在一定波动。性能和精度表现一般,其实不太行,有同学调试的非常好,应该已经合并到仓库了,可以对比原始代码查看差异,得到一些启示,具体代码可见官方仓库:(调优后)一位调试的很好的同学的代码:https://gitee.com/ascend/modelzoo/tree/master/contrib/TensorFlow/Research/nlp/char-level_cnn/CharCNN_tf_hw09124698(调优前)官方原始代码:https://gitee.com/ascend/modelzoo/tree/master/contrib/TensorFlow/Research/nlp/char-level_cnn/CharCNN_tf_huangjinsai2. 性能和精度调优过程(仅供参考,有同学做的更好,可以直接在论坛搜过相关经验分享帖)首先来说,在默认脚本下,精度和性能都是不达标的,主要工作在于性能的提升,且要保证性能提升的同时,精度不下降(与GPU相比),还有就是精度提升。先来介绍一下:基于官方仓库的初始代码进行调试:(1)调整batch size等超参数,寻求最佳超参数组合,具体一些尝试和结果如下:觉得调参这方面提升不大,还有就是数据加载部分耗时很大,明显感受到等待时间很长,在依瞳环境下,一般需要接近20分钟时间,这个解决办法,qoooqqq同学给了一个办法,就是一次性获取完整epoch所需要的数据获得最优数据输入耗时!,具体介绍可参考他的帖子。下面尝试下官方提供的性能调优工具。(3)Auto Tune这是一个官方提供的自动优化用的工具,在Terminal里执行即可,注意仅在该Terminal下有效,具体操作如下:· 在新建的Terminal下执行如下命令:# 注意这是在依瞳环境下,如果使用其他环境,比如ModelArts,请参看相关文档 export install_path=/home/HwHiAiUser/Ascend/ascend-toolkit/latest #export LD_LIBRARY_PATH=${install_path}/driver/lib64/common/:${install_path}/driver/lib64/driver:$LD_LIBRARY_PATH export PATH=${install_path}/fwkacllib/ccec_compiler/bin:${install_path}/fwkacllib/bin:$PATH export LD_LIBRARY_PATH=${install_path}/fwkacllib/lib64:$LD_LIBRARY_PATH export PYTHONPATH=${install_path}/fwkacllib/python/site-packages:$PYTHONPATH export PYTHONPATH=${install_path}/tfplugin/python/site-packages:$PYTHONPATH export ASCEND_OPP_PATH=${install_path}/opp export TE_PARALLEL_COMPILER=8 export REPEAT_TUNE=False sudo chmod -R 777 ${install_path}/fwkacllib/data如果报没有权限的错误,只要赋予其权限就行了,具体参考上述最后一条指令。之后执行你的代码,启动训练。其实,和DS CNN类似,不太行,会报错,得到回复说是暂不支持动态shape。下面是Profiling,这方面我没什么好的优化办法,上面提到的同学提出了一些方法,可以到上面帖子中参考。总的来说,Ascend 910(NPU)和GPU各有优势,得益于AI Core的先天性优势,一般来说比GPU是要快的,但GPU的生态更加完善,这也是目前昇腾所努力的,经过黄金赛,看到了很多同学很好的尝试和努力,觉得他们还是很厉害的,有这样的开发者支持(当然还有很多企业的支持,记得有Powered by Ascend),昇腾的生态也在不断完善和发展,感受很深的是,遇到问题,工程师响应还是很迅速的,回答也比较专业,能迅速定位问题,查找解决办法,还能修改底层算子,执行力非常强大。在这之中,相比之下,自己还有很多不足,需要改进和努力,期待日后的中国软件开源创新大赛·第二赛道:开源任务挑战赛(模型王者挑战赛)能继续参与,尝试。
-
()1. 直接上结果,最终性能调优对比如下:基础条件Acc速度论文95.4%暂无数据GPU(Tesla V100 16GB,单卡)96.26%0.027s / stepAscend 910A(单卡)96.18%0.068s / step注意的是,根据环境系统负载,数据存在一定波动。2. 性能和精度调优过程首先来说,在默认脚本下,DS CNN的精度基本是达标的,主要工作在于性能的提升,且要保证性能提升的同时,精度不下降(与GPU相比)。但是这里也进行了精度提升的调试,先来介绍一下:注意一下均在数据集划分test和val比例均为10%下,基于官方仓库的初始代码进行调试:(1)调整batch size等超参数,寻求最佳超参数组合,在train.py的最下面涉及很多超参数,可以进行调试,我尝试了一些,但是精度影响不大,但是对性能有一定影响,暂时不做考虑,留作性能调优时调整。(2)调整优化损失函数和优化器,一般来讲,损失函数或优化器改进对最终精度还是有比较大影响的,但是考虑到是复现,损失函数只做了一点调整,并未做太多或太大的改动,主要尝试了不同的优化器,一般来说,不同的优化器对收敛速度和最终精度有些影响,但这里发现原始代码的优化器比较好,虽然其他优化器可以更快,但是精度略有损失。(3)Auto Tune这是一个官方提供的自动优化用的工具,在Terminal里执行即可,注意仅在该Terminal下有效,具体操作如下:· 在新建的Terminal下执行如下命令:# 注意这是在依瞳环境下,如果使用其他环境,比如ModelArts,请参看相关文档 export install_path=/home/HwHiAiUser/Ascend/ascend-toolkit/latest #export LD_LIBRARY_PATH=${install_path}/driver/lib64/common/:${install_path}/driver/lib64/driver:$LD_LIBRARY_PATH export PATH=${install_path}/fwkacllib/ccec_compiler/bin:${install_path}/fwkacllib/bin:$PATH export LD_LIBRARY_PATH=${install_path}/fwkacllib/lib64:$LD_LIBRARY_PATH export PYTHONPATH=${install_path}/fwkacllib/python/site-packages:$PYTHONPATH export PYTHONPATH=${install_path}/tfplugin/python/site-packages:$PYTHONPATH export ASCEND_OPP_PATH=${install_path}/opp export TE_PARALLEL_COMPILER=8 export REPEAT_TUNE=False sudo chmod -R 777 ${install_path}/fwkacllib/data如果报没有权限的错误,只要赋予其权限就行了,具体参考上述最后一条指令。之后执行你的代码,启动训练。其实,这个不太行,会报错,得到回复说是暂不支持动态shape,但是可以运行一部分,得到一些优化,具体如下:但是由于后来环境无法使用,这一部分未能合并到知识库中使用,所以不知道最终结果,但应该会有一点性能的提升。之后也尝试过Profiling,具体分析耗时算子,但是暂未能找到相应优化办法。在运行中,可以发现AI Core最高利用率为26%左右,且是间歇性的,一般都是0,这说明未能充分利用AI Core,应该把更多计算放到AI Core上进行,因为这是相比于参考对象GPU来说,Ascend 910或者说NPU最具有优势的地方,AI Core的计算效率胜于GPU,特别是对于CNN来说,未来应该还有优化空间,期待感兴趣的同学和大佬来尝试,官方原始提供的代码可到官方仓库查看,链接如下:https://gitee.com/ascend/modelzoo/tree/master/contrib/TensorFlow/Research/speech/ds-cnn/ds-cnn_tf_huangjinsai
-
### 最终调优结果 数据集读取模式 | BatchSize | 数据读取耗时(ms/step)| 训练耗时(ms/step) | 精度 ----- | ----- | ----- | ----- 默认数据处理 | 100 | 1000 | 22| 96.28% 加载预处理 | 100 | 4 | 22| 96.21% ### 1.开始--精度调优 #### 1.1首先拿到依瞳环境 因为换了新版本,先跑一下全量的训练,看看精度怎么样,训练3w steps,精度结果很差,咨询华为的接口人,需要修改融合规则: ``` { "Switch":{ "GraphFusion":{ }, "UBFusion":{ "TbeDynamicElemwiseBroadcastFusionPass":"off" } }, "Priority":{ "GraphFusion":{ "Top":{ }, "Main":{ ``` #### 1.2 修改融合规则,重新训练 修改融合规则之后,按照下面的超参训练,默认精度模式和混合精度模式下训练精度均达标: ``` python3 train.py --model_architecture ds_cnn \ --model_size_info 6 276 10 4 2 1 276 3 3 2 2 276 3 3 1 1 276 3 3 1 1 276 3 3 1 1 276 3 3 1 1 \ --dct_coefficient_count 40 \ --window_size_ms 30 \ --window_stride_ms 10 \ --learning_rate 0.001,0.0001 \ --how_many_training_steps 10000,10000 \ --batch_size 100 \ --data_dir ./speech_dataset/ \ --summaries_dir ./summary \ --train_dir ./speech_commands_train ``` 训练在13K Step左右可以达到最高精度: 网络 | Val_Accuarcy | Test_Accuarcy ----- | ----- | ----- Dscnn-Large | 95.70% | 96.28% 开启混合精度: ``` python3 train.py --model_architecture ds_cnn \ --model_size_info 6 276 10 4 2 1 276 3 3 2 2 276 3 3 1 1 276 3 3 1 1 276 3 3 1 1 276 3 3 1 1 \ --dct_coefficient_count 40 \ --window_size_ms 30 \ --window_stride_ms 10 \ --learning_rate 0.001,0.0001 \ --how_many_training_steps 10000,10000 \ --batch_size 100 \ --allow_mix_precision=True \ --data_dir ./speech_dataset/ \ --summaries_dir ./summary \ --train_dir ./speech_commands_train ``` 训练在2W Step左右可以达到最高精度: 网络 | Val_Accuarcy | Test_Accuarcy ----- | ----- | ----- Dscnn-Large | 95.64% | 96.27% ### 2.性能调优 #### 2.1 尝试autotune 在训练脚本train.py里面ze增加AutoTune开关,开启Autotune失败: ``` [2021-06-10 23:28:42,560][INFO][../../../../../../latest/fwkacllib/python/site-packages/schedule_search/rl.py][154][search]RL schedule search finish succ! 2021-06-10 23:28:44.566392: W tensorflow/core/framework/op_kernel.cc:1639] Unavailable: failed 2021-06-10 23:28:48.789930: F tf_adapter/kernels/geop_npu.cc:766] GeOp75_0GEOP::::DoRunAsync Failed Error Message is : E90000: Compile operator failed, cause: No module named 'impl.dynamic_atomic_addr_clean' File "/home/HwHiAiUser/Ascend/ascend-toolkit/latest/fwkacllib/python/site-packages/te/platform/fusion_manager.py", line 823, in build_single_op_from_c op_pattern=op_pattern) File "/home/HwHiAiUser/Ascend/ascend-toolkit/latest/fwkacllib/python/site-packages/te/platform/fusion_manager.py", line 850, in build_single_op opm = importlib.import_module(op_module) File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1006, in _gcd_import File "<frozen importlib._bootstrap>", line 983, in _find_and_load File "<frozen importlib._bootstrap>", line 965, in _find_and_load_unlocked ``` 提交Issue: https://gitee.com/ascend/modelzoo/issues/I3V9JH?from=project-issue 开发工程师定位是因为AutoTune工具当前还不支持动态shape,所以这条优化途径,暂时搁置。 #### 2.2 尝试Profiling 根据资料,设置相关的参数,获取到Profiling数据,解析如下:  对这一块如何做优化,暂时不清楚,只好提交Issue,让开发工程师帮忙分析: https://gitee.com/ascend/modelzoo/issues/I3W8GL?from=project-issue #### 2.3 自己尝试定位 https://gitee.com/ascend/modelzoo/issues/I3YF5D?from=project-issue 之前对比过GPU和NPU耗时,每Step,GPU为0.3s,NPU为1.3s 对照训练的代码**train.py**打点分析: ``` # Pull the audio samples we'll use for training. ###############耗时点1 train_fingerprints, train_ground_truth = audio_processor.get_data( FLAGS.batch_size, 0, model_settings, FLAGS.background_frequency, FLAGS.background_volume, time_shift_samples, 'training', sess) # Run the graph with this batch of training data. start = time.time() # new add ###############耗时点2 train_summary, train_accuracy, cross_entropy_value, _, _ = sess.run( [ merged_summaries, evaluation_step, cross_entropy_mean, train_step, increment_global_step ], feed_dict={ fingerprint_input: train_fingerprints, ground_truth_input: train_ground_truth, learning_rate_input: learning_rate_value, dropout_prob: 1.0 }) ###############耗时点3 avg_time_per_step = (time.time() - start) # new add train_writer.add_summary(train_summary, training_step) #avg_time_per_step = (time.time() - start) # new add #start = time.time() # new add tf.logging.info('Step #%d: rate %f, accuracy %.2f%%, cross entropy %f, %f seconds/step' % (training_step, learning_rate_value, train_accuracy * 100, cross_entropy_value, avg_time_per_step)) ``` 1到2之间为数据处理部分的耗时,2到3之间是纯训练时间,纯训练时间NPU优于GPU(0.022s VS 0.06s) 对比纯训练部分性能: Platform | Batchsize | TimeCost(s/step) ----- | ----- | ----- GPU-V100 | 100 | 0.06 NPU | 100 | 0.022 #### 2.4 预处理优化 原有的训练代码中,音频文件的处理和获取ground_truth通过**train.py**文件中这个sess调用实现: ``` train_fingerprints, train_ground_truth = audio_processor.get_data( FLAGS.batch_size, 0, model_settings, FLAGS.background_frequency, FLAGS.background_volume, time_shift_samples, 'training', sess) ``` 通过前后打点,发现在NPU上面,这个过程耗时1s,而在GPU上面耗时0.24s,性能差距主要在这里。 这里根据空间换时间的思路进行优化:先调用get_data接口,读取训练数据,生成6000组预处理后的音频特征和gt ``` bash data_preprocess.sh ``` 或者执行: ``` python3 preprocess_datasets.py --model_architecture ds_cnn \ --model_size_info 6 276 10 4 2 1 276 3 3 2 2 276 3 3 1 1 276 3 3 1 1 276 3 3 1 1 276 3 3 1 1 \ --dct_coefficient_count 40 \ --window_size_ms 30 \ --window_stride_ms 10 \ --batch_size 100 \ --data_dir ./speech_dataset/ \ --summaries_dir ./summary \ --train_dir ./speech_commands_train ``` 训练时使用numpy直接读取处理好的数据: ``` bash train_npu_preload.sh ``` 或者执行: ``` nohup python3 train.py --model_architecture ds_cnn \ --model_size_info 6 276 10 4 2 1 276 3 3 2 2 276 3 3 1 1 276 3 3 1 1 276 3 3 1 1 276 3 3 1 1 \ --dct_coefficient_count 40 \ --window_size_ms 30 \ --window_stride_ms 10 \ --learning_rate 0.001,0.0001,0.00001 \ --how_many_training_steps 10000,10000,10000 \ --batch_size 100 \ --data_dir ./speech_dataset/ \ --summaries_dir ./summary \ --allow_mix_precision=True \ --use_processed_data=True \ --train_dir ./speech_commands_train | tee train_use_processed.log 2>&1 & ``` 优化后性能: Platform | Batchsize | 数据处理耗时(s/step) | 训练耗时(s/step) ----- | ----- | ----- | ----- NPU | 100 | 0.004 | 0.022 精度: 网络 | Val_Accuarcy | Test_Accuarcy ----- | ----- | ----- Dscnn-Large | 95.66% | 96.21% 所有源码和说明请参考: https://gitee.com/king12387/modelzoo/edit/dscnn_newest/contrib/TensorFlow/Research/speech/ds-cnn/ds-cnn_tf_huangjinsai/README.md
-
### 最终调优结果 数据集读取模式 | BatchSize | 性能(FPS) | 精度(F1) ----- | ----- | ----- | ----- 默认数据处理 | 20 | 47 | 82.5% 加载预处理 | 20 | 90 | 80.3% ### 前期提要 关于模型的迁移和精度调测参考前两次的总结帖子: [EAST模型迁移总结](https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=93859&page=1#pid670935) [EAST模型精度调优总结](https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=116177) ### 1.开始--精度调优 #### 1.1首先拿到依瞳环境 因为换了新版本,先跑一下全量的训练,看看精度怎么样,训练10w steps,total loss结果: ``` Step 099930, model loss 0.0338, total loss 0.0662, 0.73 seconds/step, 19.16 examples/second Step 099940, model loss 0.0582, total loss 0.0905, 0.46 seconds/step, 30.67 examples/second Step 099950, model loss 0.0743, total loss 0.1066, 0.45 seconds/step, 31.39 examples/second Step 099960, model loss 0.0255, total loss 0.0578, 0.40 seconds/step, 34.76 examples/second Step 099970, model loss 0.0448, total loss 0.0772, 0.41 seconds/step, 34.44 examples/second Step 099980, model loss 0.0306, total loss 0.0630, 0.37 seconds/step, 37.40 examples/second Step 099990, model loss 0.0838, total loss 0.1162, 0.53 seconds/step, 26.20 examples/second ``` 这个Loss值一看就不对,正常训练totalLoss收敛至0.003左右,于是提交[issue](https://gitee.com/ascend/modelzoo/issues/I3T3BY?from=project-issue) 检测结果也没法看:  精度不对,下面的性能也无从谈起,然后和华为的专家交流,需要按照如下方法规避: ``` 1、修改log.py文件,添加input_x = tbe.vmaxs(input_x,tvm.const(1.18e-7,dtype)) if _isclose(scale, 1.0) and _isclose(shift, 0.0): input_x = tbe.vmaxs(input_x,tvm.const(1.18e-7,dtype)) 2、修改sigmoid.py 修改 sigmoid_compute函数中:添加 data_input = tbe.vmaxs(data_input, tvm.const(-11,dtype)) if dtype == "float32" and not mul_support:函数中添加如下: error_manager_vector.raise_err_input_dtype_not_supported(kernel_name, 'x', ("float16",), dtype) data_input = tbe.vmaxs(data_input, tvm.const(-11,dtype)) 3、minimum_grad.py文件 注释: #@tbe_platform.fusion_manager.fusion_manager.register("minimum_grad") ``` 改完之后,再训练一遍模型终于收敛了 #### 1.2修改优化器 与华为的专家交流,1处的log算子修改不能作为正式方案,需要自己在训练代码里面解决loss溢出的 问题。所以参考码云社区上面的案例,修改优化器: ``` class MixedPrecisionOptimizer(tf.train.Optimizer): """An optimizer that updates trainable variables in fp32.""" def __init__(self, optimizer, scale=None, name="MixedPrecisionOptimizer", use_locking=False): super(MixedPrecisionOptimizer, self).__init__( name=name, use_locking=use_locking) self._optimizer = optimizer self._scale = float(scale) if scale is not None else 1.0 def compute_gradients(self, loss, var_list=None, *args, **kwargs): if var_list is None: var_list = ( tf.trainable_variables() + tf.get_collection(tf.GraphKeys.TRAINABLE_RESOURCE_VARIABLES)) replaced_list = var_list if self._scale != 1.0: loss = tf.scalar_mul(self._scale, loss) gradvar = self._optimizer.compute_gradients(loss, replaced_list, *args, **kwargs) final_gradvar = [] for orig_var, (grad, var) in zip(var_list, gradvar): if var is not orig_var: grad = tf.cast(grad, orig_var.dtype) if self._scale != 1.0: grad = tf.scalar_mul(1. / self._scale, grad) final_gradvar.append((grad, orig_var)) return final_gradvar def apply_gradients(self, *args, **kwargs): return self._optimizer.apply_gradients(*args, **kwargs) ``` 因为加了LossScale=1024,使用新的优化器,可以避免在Loss溢出的时候GlobalStep无法更新,进而影响后续的学习率动态下降。 GPU v100上面有个已知新Cuda版本的精度问题,训练出来的模型F1值才0.5,这里使用之前T4的精度数据对比, NPU新训练出来的模型+优化了NMS参数,F1精度由0.811提升至0.825:  ### 2、性能优化 #### 2.1、调整超参和AutoTune 原有的超参如下: ``` python3.7 npu_train.py \ --input_size=512 \ --batch_size_per_gpu=14 \ #----增加BatchSize --checkpoint_path=./checkpoint/ \ --text_scale=512 \ --training_data_path=./ocr/icdar2015/ \ --geometry=RBOX \ --learning_rate=0.0001 \ --num_readers=24 \ #----增加线程数 --pretrained_model_path=./pretrain_model/resnet_v1_50.ckpt ``` 调整为: ``` python3.7 npu_train.py \ --input_size=512 \ --batch_size_per_gpu=20 \ --checkpoint_path=./checkpoint/ \ --text_scale=512 \ --training_data_path=./ocr/icdar2015/ \ --geometry=RBOX \ --learning_rate=0.0001 \ --num_readers=30 \ --max_steps=200000 \ --pretrained_model_path=./pretrain_model/resnet_v1_50.ckpt ``` 训练性能从35FPS --> 45FPS左右. 再使用华为的AutoTune调优工具,RL和GA模式,调优后的性能:  超过GPU的性能基准43FPS。 **小tips:** 对于这些混合精度、AutoTune这些功能,我看了一些官方的代码,是加了参数控制,默认情况下关闭,然后需要的时候再打开: 所以在训练的代码也是参考官方的样例添加开关控制: ``` tf.app.flags.DEFINE_boolean('allow_mix_precision', False, 'whether to allow mix precision') tf.app.flags.DEFINE_boolean('auto_tune', False, 'whether to autotune') ... if FLAGS.allow_mix_precision: custom_op.parameter_map["precision_mode"].s = tf.compat.as_bytes("allow_mix_precision") if FLAGS.auto_tune: custom_op.parameter_map["auto_tune_mode"].s = tf.compat.as_bytes("RL,GA") ``` #### 2.2、进一步优化性能 原有的训练代码逻辑,是起多个线程,一边训练的同时一边进行数据预处理,然后喂给训练的session,这里根据空间换时间的思路进行优化: 先调用**icdar.py**原有接口,预处理好图片,得到按照Batchsize划分的1000组预处理好的数据, 包括resized_image、score_map、geo_map、mask: ``` #此处参数要与训练的参数保持一致 python3.7 preprocess_datasets.py \ --input_size=512 \ --batch_size_per_gpu=20 \ --num_readers=30 \ --processed_data=./processed_dataset/ \ --training_data_path=./ocr/icdar2015/ ``` 训练时直接加载处理过的数据,可以大大提高训练的性能: 与GPU上面使用相同的预处理优化,性能对比:  在模型训练的过程中,可以执行python3 get_best_ckpt.py,脚本会以100s为间隔轮询,取最新的ckpt在NPU/CPU/GPU上面验证测试集精度,并保存最优者:  最终的代码和详细说明请参考: https://gitee.com/king12387/modelzoo/blob/EAST_%E7%B2%BE%E5%BA%A6&%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98/contrib/TensorFlow/Research/cv/east/EAST_ID0238_for_TensorFlow/readme.md
-
一、背景文字检测是当今计算机视觉的热点问题,EAST模型是文本检测的经典模型。EAST做文本检测只需要两步:先是一个全卷积的网络直接产生一个字符或者文本行的预测(可以是旋转的矩形或者不规则四边形),然后通过NMS(Non-Maximum Suppression)算法合并最后的结果。图片出自https://arxiv.org/pdf/1704.03155.pdf二、EAST模型在基于昇腾CANN实现的Gitee链接:https://gitee.com/ascend/modelzoo/pulls/3369 三、调优流程在通读整个代码结构后,影响训练性能主要在两点,一个是数据预处理,一个是网络结构。1、数据预处理关于数据预处理这部分,EAST是跟正常用图片处理后构建一个完整的数据集然后输入网络略有不同,里面有不少随机的流程,导致无法实现全部预先处理完毕后加载到内存中。generator函数里面是对每张图片和对应的txt读取后会进行随机切割图片中的带文字部分与背景部分,并resize以及pad成要求尺寸的样本图片,然后根据切割部分的gt内容制作score_map, geo_map, rotation_map。此处有一个比较耗时的函数crop_area,这个函数对样本图片进行切割,以一定的几率切出来一副图片中的某一完整的文字块,或者一块没有文字的部分,之后对其进行填充,重定义尺寸,最终产生样本。这块的调优是我使用了多进程去处理除了随机处理外可以预加载的部分,加载到内存去,然后对里面使用for循环、循环数目大的部分,利用numba模块去提高处理速率,采取这两种方案后,速度确实提高不少。图片出自https://arxiv.org/pdf/1704.03155.pdf2、网络部分2.1、CANN-Profiling首先我尝试用了CANN-Profiling工具,这工具可以准确定位系统的软、硬件性能瓶颈,提高性能分析的效率,通过针对性的性能优化方法,以最小的代价和成本实现业务场景的极致性能。使用后部分分析结果如下Operator Schedule:1)Task wait time has reached the upper limit: [model_0/split_1,global_step/Assign,resnet_v1_50/block4/unit_2/bottleneck_v1/conv2/weights/Assign,model_0/gradients/model_0/Minimum_3_grad/LessEqual,model_0/AddN/tmp_var_accum_0,model_0/add_10,atomic_addr_clean0_21,trans_TransData_20018,trans_TransData_3113,trans_TransData_8652,atomic_addr_clean0_51,trans_TransData_3120,save_1/Assign_104,resnet_v1_50/block4/unit_3/bottleneck_v1/conv2/weights/Assign]可以看得出来像assign算子的执行等待时间是比较长的,所以我继续尝试了一些性能模式的调试。2.2、混合精度模式混合精度训练方法是通过混合使用float16和float32数据类型来加速深度神经网络训练的过程,并减少内存使用和存取,从而可以训练更大的神经网络。同时又能基本保持使用float32训练所能达到的网络精度。详细文档在下面的链接里。https://support.huawei.com/enterprise/zh/doc/EDOC1100191905/a5c4a868CANN中就提供了性能调优的一些功能,尝试了混合精度模式(allow_mix_precision),设置也很简单,使用后性能略有提升。custom_op.parameter_map["precision_mode"].s = tf.compat.as_bytes("allow_mix_precision")2.3、AutoTune模式接着我又继续尝试了AutoTune模式,这个模式的作用就是充分利用硬件资源进行算子的自动调优。详细文档参考下面的链接:https://support.huaweicloud.com/tfmigr-cann502alpha5training/atlasmprtg_13_0009.html这里实际上有些比较曲折的使用体验,一开始我使用的模式是在代码中加入:export install_path=/home/HwHiAiUser/Ascend/ascend-toolkit/latest #export LD_LIBRARY_PATH=${install_path}/driver/lib64/common/:${install_path}/driver/lib64/driver:$LD_LIBRARY_PATH export PATH=${install_path}/fwkacllib/ccec_compiler/bin:${install_path}/fwkacllib/bin:$PATH export LD_LIBRARY_PATH=${install_path}/fwkacllib/lib64:$LD_LIBRARY_PATH export PYTHONPATH=${install_path}/fwkacllib/python/site-packages:$PYTHONPATH export PYTHONPATH=${install_path}/tfplugin/python/site-packages:$PYTHONPATH export ASCEND_OPP_PATH=${install_path}/opp #export ASCEND_AICPU_PATH=${install_path} #export ASCEND_DEVICE_ID=0 export TE_PARALLEL_COMPILER=8 export REPEAT_TUNE=False首先要设置好环境变量,如果变量设置有问题,跑代码的时候会一直报错“GA get failed”的错误,我这边是因为PYTHONPATH的指向路径有问题,基本上如果是还没开始就报错,那基本调试可以在环境变量这里。custom_op.parameter_map["auto_tune_mode"].s = tf.compat.as_bytes("RL,GA")这我是在代码中加的,从目前来看,GA在线训练的速度会比RL的速度要快得多,RL我跑了一天多的时间,一度怀疑是不是代码出问题了,还提了相关issue(https://gitee.com/ascend/modelzoo/issues/I3XGXH),社区维护小伙伴回复的速度还是值得点赞的,从官方得知:1、RL调优针对vector类算子,GA调优针对CUBE类算子,RL调优耗时比GA长;DUMP离线模式调优耗时比在线模式更长。目前RL调优耗时确实比较长,我们正在优化中,预计将来能缩短到一半。如果要缩短时间可以通过配置环境变量:export TUNE_TIMEOUT=500,这样每个vector类算子RL调优超过500S就退出调优,只是可能调优的结果并不是很好。2、NPU算子初始化耗时长并不影响AutoTune的使用,后续会逐步优化。然后我又踩了一个坑,假设你已经使用AutoTune模式调优过一次,结果已经存到自定义知识库,那么下一次如果不使用(强调!!)重新调优一次的话,那么直接注释上面那个代码段即可,昇腾处理的时候回自动检索自定义知识库,这块是会影响到最终的性能结果。经过正确使用AutoTune模式后,从单纯使用AutoTune结果来看,最终FPS从39到42点多,提升还是不少的。使用AutoTune效果:Step 000000, model loss 0.0274, total loss 0.0598, 10.76 seconds/step, 1.30 examples/second Step 000010, model loss 0.0209, total loss 0.0533, 9.99 seconds/step, 1.40 examples/second Step 000020, model loss 0.0269, total loss 0.0593, 0.27 seconds/step, 51.72 examples/second Step 000030, model loss 0.0291, total loss 0.0615, 0.26 seconds/step, 54.13 examples/second Step 000040, model loss 0.0202, total loss 0.0525, 0.22 seconds/step, 63.92 examples/second Step 000050, model loss 0.0256, total loss 0.0580, 0.21 seconds/step, 65.59 examples/second Step 000060, model loss 0.0178, total loss 0.0502, 0.21 seconds/step, 65.24 examples/second Step 000070, model loss 0.0290, total loss 0.0613, 0.21 seconds/step, 67.75 examples/second Step 000080, model loss 0.0134, total loss 0.0458, 0.26 seconds/step, 53.50 examples/second Step 000090, model loss 0.0187, total loss 0.0510, 0.30 seconds/step, 46.22 examples/second Step 000100, model loss 0.0209, total loss 0.0533, 0.31 seconds/step, 45.77 examples/second Step 000110, model loss 0.0158, total loss 0.0482, 0.33 seconds/step, 41.86 examples/second Step 000120, model loss 0.0222, total loss 0.0546, 0.31 seconds/step, 45.59 examples/second Step 000130, model loss 0.0348, total loss 0.0671, 0.31 seconds/step, 45.01 examples/second Step 000140, model loss 0.0254, total loss 0.0577, 0.31 seconds/step, 45.35 examples/second Step 000150, model loss 0.0201, total loss 0.0524, 0.29 seconds/step, 47.83 examples/second不使用AutoTune效果:Step 000000, model loss 0.0241, total loss 0.0565, 10.87 seconds/step, 1.29 examples/second Step 000010, model loss 0.0323, total loss 0.0647, 9.75 seconds/step, 1.44 examples/second Step 000020, model loss 0.0310, total loss 0.0634, 0.26 seconds/step, 53.28 examples/second Step 000030, model loss 0.0248, total loss 0.0571, 0.27 seconds/step, 51.09 examples/second Step 000040, model loss 0.0334, total loss 0.0657, 0.31 seconds/step, 44.93 examples/second Step 000050, model loss 0.0300, total loss 0.0623, 0.32 seconds/step, 43.88 examples/second Step 000060, model loss 0.0224, total loss 0.0548, 0.32 seconds/step, 44.23 examples/second Step 000070, model loss 0.0208, total loss 0.0532, 0.30 seconds/step, 46.59 examples/second Step 000080, model loss 0.0521, total loss 0.0845, 0.32 seconds/step, 44.20 examples/second Step 000090, model loss 0.0200, total loss 0.0524, 0.31 seconds/step, 44.48 examples/second Step 000100, model loss 0.0248, total loss 0.0572, 0.31 seconds/step, 45.38 examples/second Step 000110, model loss 0.0166, total loss 0.0490, 0.35 seconds/step, 40.47 examples/second Step 000120, model loss 0.0246, total loss 0.0570, 0.32 seconds/step, 44.05 examples/second Step 000130, model loss 0.0245, total loss 0.0569, 0.31 seconds/step, 45.69 examples/second Step 000140, model loss 0.0348, total loss 0.0672, 0.31 seconds/step, 45.89 examples/second Step 000150, model loss 0.0186, total loss 0.0509, 0.30 seconds/step, 46.83 examples/second2.4、调整网络结构east中使用了slim.batch_norm,该处默认的是tf.nn.batch_normalization,这是一个低级的操作函数,调用者需要自己处理张量的平均值和方差。我尝试在slim.batch_norm的参数中加入fused=True,就成为tf.nn.fused_batch_norm,这是另一个低级的操作函数,和前者十分相似,不同之处在于它针对4维输入张量进行了优化,前者tf.nn.batch_normalization则接受任何等级大于1的张量,这样操作后FPS也略有提升。最后有个Tips,如果你在使用后台常驻方式如nohup去跑NPU的话,有可能出现中途被kill的情况(几次10wSteps被killed的心累教训),官方建议是使用setsid去处理(https://gitee.com/ascend/modelzoo/issues/I3Y8G7)。 四、经验总结从我尝试Tensorflow模型迁移的经验来看,CANN在模型迁移上已经做了很多预处理工作,使得迁移难度已大大下降,所以一般来说我们在迁移时需要考虑以下几点:1、输入的是动态shape还是固定shape,CANN对动态shape的支持有限,如果以固定shape输入能够得到更好的优化;2、运行训练脚本时是否执行时间过长,如果时间过长,则可以用CANN的profling工具去分析算子耗时,它可以准确定位系统的软、硬件性能瓶颈,这时候我们可以根据分析结果提issue,或者能力允许可以进一步自定义算子或者开启混合计算模式让耗时长的算子留在Host由前端框架执行;3、经过上述步骤后,在CANN上训练模型已经有基本性能可以支撑我们花更少时间去调整精度。假如模型精度跟预期一样,那就皆大欢喜,但一般来说还是需要略做调整。这时候CANN的精度比对工具和溢出检测工具就派上用场了,这两个工具基本都是为了得到训练过程中各算子的运算结果(即Data Dump数据),然后和业界标准算子(如TensorFlow)运算结果进行数据偏差对比。若算子精度有问题,最简单还是提issue,如果是大牛就直接上自定义算子去修正得了(此处应有掌声)。总的来说,如今在CANN上做模型迁移相较之前已方便许多,而且社区的氛围也越来越好,昇腾作为国内少有的全场景AI基础设施方案。作为一名开发者,我希望它能够茁壮成长,成为深度学习领域不可缺少的一股中坚力量。
-
1.调优概述使用鲲鹏性能分析工具(Hyper Tuner)中的热点函数分析及锁与等待分析功能对目标环境的多线程应用程序进行采样分析,找到性能瓶颈点,并根据分析结果进行优化修改,从而实现应用性能提升。2.环境要求本实践以TaiShan 200服务器(型号2280)+CentOS 7.6组网举例,Hyper Tuner在其他鲲鹏平台和操作系统上的操作类似。3.前提条件服务器和操作系统正常运行。PC端已经安装SSH远程登录工具。目标环境上HyperTuner工具已经安装完成,并正常运行。4.调优思路在进行调优之前,先用HyperTuner工具对目标环境的多线程应用程序进行采样分析。针对应用中的热点函数进行分析,通过相关函数实现进行优化。对优化后的应用再次进行热点函数分析及锁与等待分析,验证调优后的效果。5.调优过程现状分析函数实现的功能为多个线程对一个变量进行累加操作。执行热点函数分析可以看到实际的两个线程对应的功能函数fun2与main时钟周期占比很小,主要热点在glibc对应的互斥锁上面。执行锁与等待分析任务可以看到对应锁的调用情况,以及对应功能函数里的源码,对于变量num进行累加操作前后需要使用互斥锁,保证读个线程的操作均被执行到。但是应用的实际效率是很低的,过多的开销花费在了互斥锁的require和release上面。性能瓶颈分析和优化实际功能代码的执行速度很快,多线程使用锁的方案会把大量的开销花费在锁的竞争上面,为了减少公共资源的的抢占可以通过原子变量无锁的编程的方式优化代码。重新执行热点函数分析和锁与等待分析任务可以看到功能函数main和fun2成为了热点函数且已经没有锁函数的调用存在。6.调优结果分析通过热点函数分析和锁与等待分析任务,找到多线程应用代码中公共资源抢占下使用锁机制带来的额外开销,通过原子变量实现无锁编程实现了同样的效果,减少了不必要的开销。一下为实际二进制的运行结果对比,可以看到通过无锁编程以及编译优化下,同样的一个功能应用耗时从5s优化到了1.5s左右。
-
模型介绍 Character-level Convolutional Networks for Text Classification 使用字符级卷积网络进行文本分类,证明字符级卷积网络也可以达到非常不错的精度!论文链接:https://arxiv.org/pdf/1509.01626.pdf。在这篇论文中,作者将字符级的文本当做原始信号,并且使用一维的卷积神经网络来处理它。研究表明,单词嵌入表示可以直接用于卷积神经网络,而无需考虑语言的语法或语义结构。 图片来自https://arxiv.org/pdf/1509.01626.pdf本次Char-CNN调优过程来源于本人参加的昇腾模王赛的一道赛题,在本次比赛中尝试将Char-CNN迁移至昇腾910上进行训练并调试其训练性能。调优过程 首先在完全不改动的情况下训练性能比V100 GPU稍慢,GPU平均13秒每100 step,NPU平均14-15秒每100 step。调优思路是从两方面如下:数据处理和降低网络计算量。 从原作者的代码里就能看出来数据读取方面只是以能用即可的原则编写的,也就留给了我们很大的调优空间,其次就是优化模型训练耗时这方面可以使用CANN自带的Profiling工具分析各个算子的耗时并进行针对性调优,还有AutoTune工具可以对网络所有算子性能进行自动的微调。昇腾的文档也有非常详细的介绍和使用例子,可以参照执行。数据处理调优:首先一眼可以看出来的问题每次开始一轮新的Epoch的时候都会比平时多2-3秒Iter: 3100, ... Time: 0:00:14.935000 Epoch: 3 Iter: 3200, ... Time: 0:00:18.824000<-- Iter: 3300, ... Time: 0:00:16.197000 Iter: 3400, ... Time: 0:00:15.179000 Iter: 3500, ... Time: 0:00:14.960000 Epoch: 4 Iter: 4800, ... Time: 0:00:17.197000<-- Iter: 4900, ... Time: 0:00:14.839000 Iter: 5000, ... Time: 0:00:14.802000 Epoch: 5 Iter: 6300, ... Time: 0:00:17.356000<-- Iter: 6400, … Time: 0:00:14.860000分析一下原始代码 run_cnn.py#L144从被调用函数batch_iter继续分析原因cnews_loader.py#L147indices = np.random.permutation(np.arange(data_len))每个新的epoch会重新对数据进行打乱,并且没有并行处理而导致占用了几秒的耗时。这里想到TensorFlow提供 的tf.data.Dataset可使数据进行并行处理。但是在我将数据处理过程改为使用tf.data.Dataset后,验证时发现中途的val数据输入过程不能使用dataset.repeat,所以每次开始验证时都需要重新初始化iterator,这样就会造成训练途中每次都会多出来大约200毫秒的初始时间。经过不断的尝试,得出最终结论,只有一次性获取完整epoch所需要的数据才能获得最优数据输入耗时!下面是优化后的代码。class data_load(object): def __init__(self, sess,x,y,is_train=True): with tf.device('/cpu:0'): self.x = x self.y = y self.x_ = tf.placeholder(self.x.dtype, self.x.shape) self.y_ = tf.placeholder(self.y.dtype, self.y.shape) self.sess = sess dataset = tf.data.Dataset.from_tensor_slices((self.x_, self.y_)) if is_train: dataset = dataset.shuffle(len(self.x)) dataset = dataset.repeat() dataset = dataset.batch(len(self.x)) else: dataset = dataset.batch(len(self.x)) dataset = dataset.prefetch(2) self.iterator = dataset.make_initializable_iterator() self.next = self.iterator.get_next() self.sess.run(self.iterator.initializer, feed_dict={self.x_: self.x,self.y_: self.y}) def replay(self): self.sess.run(self.iterator.initializer, feed_dict={self.x_: self.x,self.y_: self.y})至此数据输入调优已完成! 模型调优:首先尝试CANN自带的AutoTune自动调优功能。AutoTune工具可全自动地完成模型中算子的性能自动优化,提升模型端到端的运行速度。尝试自动AutoTune自动调优后发现效果不明显,从华为技术人员得知,当前的版本尚不支持动态shape算子的优化,正在开发中。期待后续版本的优化效果。然后就是开始使用Profiling工具(https://support.huaweicloud.com/developmenttg-cann503alpha1training/atlasprofiling_16_0003.html)。训练过程中支持采集性能数据,然后借助Profiling工具进行数据分析,从而准确定位系统的软、硬件性能瓶颈,提高性能分析的效率,通过针对性的性能优化方法,以最小的代价和成本实现业务场景的极致性能。下图是Profiling的分析结果:1、从结果中发现,耗时最大的是score/fc2/MatMul,猜测是计算量太大导致的。为了解决这个问题,尝试使能混合精度训练(https://support.huaweicloud.com/tfmigr-cann503alpha1training/atlasmprtg_13_0037.html)。混合精度训练方法是通过混合使用float16和float32数据类型来加速深度神经网络训练的过程,并减少内存使用和存取,从而可以训练更大的神经网络。同时又能基本保持使用float32训练所能达到的网络精度。从修改后的再次运行的profiling分析结果看,score/fc2/MatMul的耗时已大幅降低。2、再分析当前最耗时的算子:score/Dropout/dropout_1/random_uniform/RandomUniform 可以看到Dropout算子随机数生成使用了很多时间将cnn_model.py#L85tf.contrib.layers.dropout(fc, self.keep_prob)修改成NPU优化后的dropoutfrom npu_bridge.estimator import npu_opsnpu_ops.dropout(fc, self.keep_prob)问题也可以顺利解决继续看最耗时的算子optimize/Adam/update_embedding/Unique 这个属于优化器反向传播更新向量但优化器并没有可以下手的地方所以只能看向上一层tf.nn.embedding_lookup,This function is used to perform parallel lookups on the list of tensors in params. It is a generalization oftf.gather, where params is interpreted as a partitioning of a large embedding tensor.从tf官方的解释上可以理解为在单个张量的输入实际上和tf.gather功能上完全一致,刚好从昇腾cann文档上也看到了tf.gather的优化方式@tf.custom_gradient def gather_npu(params, indices): def grad(dy): params_shape = tf.shape(params, out_type=tf.int64) params_shape = tf.cast(params_shape, tf.int32) grad_gather = tf.unsorted_segment_sum(dy, indices, params_shape[0]) return grad_gather, None return tf.gather(params, indices), gradscore/Dropout/dropout_1/random_uniform/RandomUniform 可以看到Dropout算子随机数生成使用了很多时间,因此这里需要修改成NPU优化后的dropout。修改cnn_model.py#L85修改前:问题顺利解决。3、继续看最耗时的算子optimize/Adam/update_embedding/Unique 这个属于优化器反向传播更新向量,但优化器并没有可以下手的地方所以只能看向上一层tf.nn.embedding_lookup,从TensorFlow官方的解释上可以理解为在单个张量的输入实际上和tf.gather功能上完全一致,刚好从昇腾cann文档上也看到了tf.gather的优化方式并将cnn_model.py#L83tf.nn.embedding_lookup(embedding, self.input_x)改为gather_npu(embedding, self.input_x)即可解决4、继续优化,因为GatherV2 暂无优化方法先略过。看耗时第二长的cnn/conv/BiasAdd 这个来自tf.layers.conv1d。如果使用 use_bias=False去掉的话会导致精度下降严重,所以要用其他办法降低耗时,这时可以看Profiling导出的summary数据:从summary数据中可以看到cnn/conv/BiasAdd的数据是来自cnn/conv/conv1d。cnn/conv/conv1d输出为FP16的NC1HWC0数据,然后通过trans_TransData_76把FP16的NC1HWC0转换为FP16的NHWC。再然后通过trans_Cast_77 把FP16的数据转回FP32。最后再把转换后的数据输入到cnn/conv/BiasAdd。就是这样的复杂数据转换导致了这3个算子使用了非常多的时间。思路清晰后解决方法也就简单了,只需要把BiasAdd也降成半精度即可解决问题!根据昇腾cann文档中的说明,我们可以手动指定某个算子是否支持降精度执行!接下来动手。在训练环境下打开文件:/home/HwHiAiUser/Ascend/ascend-toolkit/5.0.1/arm64-linux/opp/op_impl/built-in/ai_core/tbe/config/ascend910/aic-ascend910-ops-info.json通过搜索BiasAdd 添加降精度规则即可allow_mix_precision模式下,用户可以在内置优化策略基础上进行调整,自行指定哪些算子允许降精度,哪些算子不允许降精度。 切换到“OPP安装目录/opp/op_impl/built-in/ai_core/tbe/config/ascend910”目录下。 对aic-ascend910-ops-info.json文件增加写权限。 chmod u+w aic-ascend910-ops-info.json 修改或增加算子信息库aic-ascend910-ops-info.json文件中对应算子的precision_reduce字段: "precision_reduce":{ "flag":"true" } true:允许将当前float32类型的算子,降低精度到float16。 false:不允许将当前float32类型的算子,降低精度到float16。 不配置:当前算子的混合精度处理机制和前一个算子保持一致,即如果前一个算子支持降精度处理,当前算子也支持降精度;如果前一个算子不允许降精度,当前算子也不支持降精度在依瞳环境下文件在/home/HwHiAiUser/Ascend/ascend-toolkit/5.0.1/arm64-linux/opp/op_impl/built-in/ai_core/tbe/config/ascend910/aic-ascend910-ops-info.json通过搜索BiasAdd 添加降精度规则即可修改后再次分析:可以看到BiasAdd耗时降低并且Cast TransData已经融合成一个算子,大大减少了训练耗时!5、后续还修改了GatherV2D和ReduceMeanD的降精度运行规则不过效果不大就不详细介绍了!至此所有调优已经完成!最终调优结果:bs512精度训练速度step/s推理时间Ascend91095.3321.231.79sV10095.077.62442.418s 精度和GPU一致维持在95.2X% 偶尔可以到95.3%总结:纵观整个模型王者挑战赛可以看到昇腾的模型代码迁移性能调优并不难,昇腾CANN作为昇腾AI处理器的使能平台,提供了例如精度对比工具、Profiling工具等等强大的能力,使得调优过程变得相对容易。另外所有操作在各个公开的文档里都描述的非常清楚,善用搜索引擎可以解决非常多问题。而且遇到的所有问题也可以在issues上提问并且有强大的团队处理,对昇腾的产品使用上基本没有后顾之忧!调优后的源码:https://gitee.com/ascend/modelzoo/tree/master/contrib/TensorFlow/Research/nlp/char-level_cnn/CharCNN_tf_hw09124698
上滑加载中
推荐直播
-
华为开发者空间玩转DeepSeek
2025/03/13 周四 19:00-20:30
马欣 山东商业职业技术学院云计算专业讲师,山东大学、山东建筑大学等多所本科学校学生校外指导老师
同学们,想知道如何利用华为开发者空间部署自己的DeepSeek模型吗?想了解如何用DeepSeek在云主机上探索好玩的应用吗?想探讨如何利用DeepSeek在自己的专有云主机上辅助编程吗?让我们来一场云和AI的盛宴。
即将直播 -
华为云Metastudio×DeepSeek与RAG检索优化分享
2025/03/14 周五 16:00-17:30
大海 华为云学堂技术讲师 Cocl 华为云学堂技术讲师
本次直播将带来DeepSeek数字人解决方案,以及如何使用Embedding与Rerank实现检索优化实践,为开发者与企业提供参考,助力场景落地。
去报名
热门标签