Ascend昇腾设备上启容器时映射NPU,解决无法找到npu、无法使用npu-smi info的情况
在昇腾服务器启容器时,可能会遇到识别不到npu,或者npu-smi info不能正常使用的情况
在昇腾服务器启容器时,可能会遇到识别不到npu,或者npu-smi info不能正常使用的情况,比如说:npu-smi: command not foundnpu-smi: error while loading shared libraries: libc_sec.so: cannot open shared object file: No such file or directory
首先确保宿主机上内核驱动正常安装,然后就可以通过
- 启容器时,将宿主机上的设备节点、Ascend的一些工具、库都都要映射过去。并且设置好环境变量PATH,告诉容器去哪找要用的工具或依赖。
- 直接安装Ascend的工具/库(CANN toolkit/runtime、
npu-smi依赖的.so等),这个好处是可以随着镜像直接移植。
下面的方法是用1.的方式的解决方法和过程,好处是宿主机有啥就用啥,也不容易出现“容器库版本和宿主机驱动不匹配”的情况。所以也会出现在不同宿主机上要用的启容器指令都不太一样,要根据宿主机的情况来看。
解决方法:
快速入门:使用容器设置环境
参考的官方教程:https://www.hiascend.com/developer/ascendhub/detail/17da20d1c2b6493cb38765adeba85884
官方triton-inference-server-ge-backend容器启动指令
docker run --privileged --name=ge_backend --net=host --shm-size=500g \
--device /dev/davinci1 \
--device /dev/davincix \ # 如果有多卡都要挂载上
--device ...... \ # 如果有多卡都要挂载上
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-it triton-inference-server-ge-backend:latest bash
1. 检查宿主机的设备、驱动和权限
设备、驱动
# 宿主机执行,查看设备节点
vanity@hello-pc:~$ ls -l /dev/davinci* /dev/ascend* 2>/dev/null
# 输出信息如
crw-rw---- 1 HwHiAiUser HwHiAiUser 234, 0 7月 24 13:31 /dev/davinci0
crw-rw---- 1 HwHiAiUser HwHiAiUser 234, 1 7月 24 13:31 /dev/davinci1
crw-rw---- 1 HwHiAiUser HwHiAiUser 234, 2 7月 24 13:31 /dev/davinci2
crw-rw---- 1 HwHiAiUser HwHiAiUser 234, 3 7月 24 13:31 /dev/davinci3
crw-rw---- 1 HwHiAiUser HwHiAiUser 235, 0 7月 24 13:31 /dev/davinci_manager
# 再看 CANN/驱动是否安装:列出 /usr/local/Ascend 目录下的内容
vanity@hello-pc:~$ ls /usr/local/Ascend 2>/dev/null
# 输出信息如下,能看到这些条目,说明在宿主机上,至少 Ascend 软件栈的安装目录结构是存在的
develop driver firmware host_servers_remove.sh host_servers_setup.sh host_services_exit.sh host_services_setup.sh host_sys_init.sh version.info
然后就可以在 docker run 的 --device 参数后面加上刚刚查询到的设备节点,把 4 张 NPU 卡(或 4 个 NPU 设备实例)映射进容器。如果宿主机还有 /dev/ascendctl 或其它 /dev/ascend* 控制节点,有些环境也需要额外挂进去
--device=/dev/davinci0 \
--device=/dev/davinci1 \
--device=/dev/davinci2 \
--device=/dev/davinci3 \
--device=/dev/davinci_manager \
同时也要挂载底层通信和内存管理相关的设备节点 /dev/devmm_svm 和 /dev/hisi_hdc :
--device /dev/devmm_svm
--device /dev/hisi_hdc
检查是否有权限访问npu
通常非 root 用户如果不在 HwHiAiUser 这个组里,会没有权限访问 npu 设备
# 使用groups查询自己是否在HwHiAiUser组,否则无法访问npu
vanity@hello-pc:~$ groups
docker HwHiAiUser
2. 检查 npu-smi位置
不同的服务器上,可能npu-smi的具体位置都会不一样,根据你的宿主机上npu-smi的位置来决定要挂在的目录和环境变量的量路径
vanity@hello-pc:~$ which npu-smi || true
/usr/local/sbin/npu-smi
可以看到我这个宿主机的情况是,npu-smi 是在/usr/local/sbin/npu-smi路径下
所以挂载的npu-smi目录和环境变量:
# docker run中增加挂载和 PATH
-v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi:ro \
-e PATH=/usr/local/sbin:/usr/local/Ascend/ascend-toolkit/latest/bin:$PATH \
3. 目录挂载参数
目录挂载
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-
该路径为宿主机上安装的 NPU 驱动的用户态动态链接库。
-
由于NPU 内核里的驱动和外面的
.so库必须版本完全一致,所以通过挂载,强制容器使用和宿主机内核完全匹配的库文件。
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-
该路径为当前宿主机驱动具体版本号的文本文件。
-
容器内的 CANN 软件(如 ACL 初始化阶段)会读取这个文件来检查兼容性。如果读不到,或者读到的版本号格式不对,初始化可能会失败。
-v /etc/ascend_install.info:/etc/ascend_install.info
- 该文件记录昇腾软件安装路径和配置信息的全局文件。
- 某些工具或库需要通过这个文件找到驱动安装在哪里。如果没有它,系统可能不知道去
/usr/local/Ascend/driver下面找库。
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi
-v /usr/local/dcmi:/usr/local/dcmi
npu-smi是类似于 NVIDIAnvidia-smi的命令行工具,用于查看 NPU 的温度、显存占用、算力利用率等;dcmi是其依赖的底层接口库。- 把宿主机的
npu-smi二进制挂到容器同路径,直接复用宿主机的工具,既省空间又能保证工具版本与驱动匹配。可以解决容器里原本没有npu-smi的问题(否则command not found)。就是刚刚第2步所查询到的路径。
环境变量配置
可以先不配置环境变量,在安装完CANN后会统一进行环境变量设置
解决过程&可能会遇到的问题
查询完设备节点信息后,我先使用下面的指令启容器
docker run -dit -p xxxxx:22 \
--name container_name \
--privileged \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver:ro
-v /etc/ascend_install.info:/etc/ascend_install.info:ro \
--device=/dev/davinci0 \
--device=/dev/davinci1 \
--device=/dev/davinci2 \
--device=/dev/davinci3 \
--device=/dev/davinci_manager \
-e ASCEND_HOME_PATH=/usr/local/Ascend \
-e LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/lib64:/usr/local/Ascend/driver/lib64:$LD_LIBRARY_PATH \
-e PATH=/usr/local/Ascend/ascend-toolkit/latest/bin:$PATH \
<your-image>:<tag> \
bash
报错 :npu-smi: command not found
用上述指令启容器之后发现,可以检查到设备节点,但是使用不了 npu-smi info
root@9424d26cda5a:/work npu-smi info
bash: npu-smi: command not found
出现这个问题,不等于容器没映射到npu,可能只是容器里没找到 npu-smi 的可执行文件
指令挂载的ASCEND_HOME_PATH=/usr/local/Ascend,但npu-smi 这个命令可能并不在 /usr/local/Ascend 目录里,可能每个宿主机的情况都不一样,此时要在宿主机查询一下:
vanity@hello-pc:~$ which npu-smi || true
/usr/local/sbin/npu-smi
可以看到我这个宿主机的情况是,npu-smi 是在/usr/local/sbin/npu-smi路径下
那么就修改一下挂载的npu-smi目录:
# docker run中增加挂载
-v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi
报错 :npu-smi: error while loading shared libraries: libc_sec.so: cannot open shared object file: No such file or directory
修改了挂载目录和环境变量后,出现的新的报错
root@d9b73ab51855:/work npu-smi info
npu-smi: error while loading shared libraries: libc_sec.so: cannot open shared object file: No such file or directory
此时npu-smi 已经被带进容器了,但它依赖的动态库 libc_sec.so 在容器的动态链接器搜索路径里找不到
把相关的都挂载上:
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
然后就成功了,可以成功使用 npu-smi info查看npu设备情况了。
如果接着要在容器中跑pytorch框架的深度学习,可以参考我的另外一篇笔记:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐


所有评论(0)