一、背景需求
华为Atlas200 DK对tensorflow、caffe深度学习框架的适配性比较好,但是对pytorch框架适配不是很好。
结合华为提供的资料,和师姐探讨了一下,将pytorch框架下训练的模型放到Atlas200 DK上进行推理,有以下两种技术路线:
(1)将训练好的pytorch模型通过华为atc工具转换为tensorflow或onnx模型,然后按照tensorflow或onnx在Atlas200 DK上的部署方法进行模型部署。
(2)在Atlas200 DK上安装华为开发的Pytorch Adapter,修改test源码,进行移植,适配昇腾NPU版本的pytorch,直接在Atlas200 DK运行test,进行在线推理。
目前选择了第二种技术路线,在安装Pytorch Adapter上折腾了很长时间,将遇到的坑记录一下。
使用的版本如下:
(1)Pytorch Adapter版本:v2.0.4
(2)Pytorch版本:1.5.0
(3)CANN 版本:2.0.4
(4)Python版本:3.7.5
(5)gcc、cmake等工具版本,按照官方编译参考要求安装即可。
官方编译、安装文档链接(v2.0.4版本):https://gitee.com/ascend/pytorch/blob/v2.0.4/README.zh.md
二、问题及解决
1、pytorch源码及三方依赖代码下载,能使用github一定要使用github,不要自己下载。
【问题描述】:
由于在国内使用github安装非常慢,甚至无法使用,所以一开始安装pytorch第三方依赖代码的时候,没有直接使用命令行从github上拉取代码,而是一个一个下载的第三方依赖代码包。
这样带来了版本匹配的问题,导致后面编译过程遇到了非常多的编译错误。
【解决方案】:
架梯子,按官方文档中来,使用git直接从github上拉取代码。
2、在Atlas200 DK上编译,内存不够,导致编译陷入无限卡死/循环的状态。
【问题描述】:
在编译过程中,屏幕会输出类似Building CXX/C Projects的提示信息,显示当前正在编译的文件和编译进度等。Atlas200 DK CPU性能不强,所以编译一个.c或.cpp文件用时几分钟或十几分钟很正常。但过了一两个小时甚至更长的时间,仍然在编译一个文件,即提示信息无变化,像陷入死循环或卡死。
【解决方案】:
出现这个问题时,考虑到可能是爆内存了,于是加了3个G的交换空间(swap)。但是后面还出现这个问题,以为不是内存的原因,结果折腾了一圈,用free -m查看了一下,发现3个G不够,于是加到了16个G,上述问题解决。
这里自我反思一下,导致折腾一圈的原因就是操作不严谨,明明已经考虑到了是内存问题,加了内存后就想当然认为够用了,没有验证,不然不会耽误这么长时间。
【附录】:增加swap交换空间方法
(1)首先制作swap文件。swapfile文件位置可以自己确定,文件大小为bs * count,这里就是16个G。
sudo dd if=/dev/zero of=/home/swapfile bs=1G count=16
sudo mkswap /home/swapfile
(2)激活启动swapfile。
sudo swapon /home/swapfile
(3)每次开机自动增加swap,需要在/etc/fstab
文件中增加一行。
/home/swapfile swap swap defaults 0 0
(4)如果想删除或扩展swapfile,需要先停用swapfile。
sudo swapoff /home/swapfile
(5)激活swapfile后,可以使用以下命令查看swap是否生效。
free -m
3、import torch时,libc10_npu.so出现undefined symbol问题
【问题描述】:
安装完昇腾pytorch插件后,需要验证是否安装成功。最简单的方法就是运行python3,然后import torch。结果在import的时候,出现了如下错误:

【解决方案】:
这个问题查阅了好多资料,均说是版本不匹配的问题。直到后面解决,才真正理解为什么是版本不匹配问题。
首先查看一下对应的.so文件中没有定义的符号。
ldd -r libc10_cpu.so
c++filt _ZN3c1011StorageImpl17release_resourcesEv
可以看到是c10::StorageImpl::release_resources()没有定义。回到安装pytorch插件的源码目录,搜索一下这个函数出现的位置。
grep -rni "StorageImpl::release_resources()"

发现这个函数定义在c10/core/StorageImpl.cpp
中,然后搜索一下这个文件参与的编译。
grep -rni "StorageImpl.cpp"

根据编译命令显示,这个文件只被编译成.o文件并被链接到了libc10.so中,没有被直接链接到libc10_npu.so中。
因此推测,是由于libc10_npu.so中libc10.so库的链接位置不对,再次使用ldd -r libc10_npu.so
命令查看一下,发现libc10_npu.so中libc10.so的链接路径为/usr/lib64/aicpu_kernels/..........
。

此路径不是我们指定的路径,所以是由于环境变量设置出现问题。要修改LD_LIBRARY_PATH导出的路径顺序,让libc10.so链接到正确的.so文件,见下图。

修改完LD_LIBRARY_PATH后,重新设置系统的动态库路径。
ldconfig
再次运行python3,import torch,发现libc10_npu.so undefined symbol问题已经解决。
4、import torch时,JIT报TypeError错误
【问题描述】:
运行python3,import torch时,torch/jit/__init__.py报“”TypeError: Object of 'module' is not an instance of 'function'类型错误。如下图所示。

【解决方案】:
设置环境变量,禁用JIT。暂时不知道会不会有什么功能上的影响。
export PYTORCH_JIT=0
三、Feelings
本人资深花粉,手机、电脑、手表、平板、耳机、音箱全是华为的,还有一堆华为的智能家居产品。华为消费者业务(现在已经与商业合并,叫华为终端业务)产品个人体验良好,但是这个昇腾的体验的确不好,主要有以下几个方面吧。
(1)参考资料结构杂乱,插件源码、参考文档版本太多,而且位置不统一,最新版本文档(截止2022/4/25)内容不全。
(2)论坛支持做的不好,提的问题帖子往往是回答一次之后就石沉大海。之前自己也使用过TI的论坛,技术支持做的要比华为好。
道阻且长,希望华为继续加油。
本文地址: 华为Atlas200 DK Pytorch框架(Pytorch Adapter)安装踩坑记录