华为Ascend芯片显卡docker环境搭建并完成YOLO8推理

news2024/12/23 22:23:39

目前随着AI应用的爆发式增长,支持AI模型训练的显卡硬件也变得炙手可热。目前,由于xx颁布了芯片销售禁令,随着而来的是,在国内高端的英伟达显卡买不到了,中低端的显卡价格也水涨船高。在此环境下,华为技术有限公司自研的达芬奇架构的Ascend芯片映入了AI开发者的视野,据说Ascend910高端型号的芯片的算力已经跟NVIDIA A100旗鼓相当,但是前者价格是后者的十分之一!!!  目前国内生成式AI巨头,比如阿里的通义千问,智谱AI的ChatGLM都对华为Ascend芯片做了适配,可见未来Ascend芯片无论是市场前景还是行业应用,都将越来越普遍,或许在不久,显卡不再是英伟达一家独大。

想了解更多有关Ascend芯片的架构及特点,可以查看官方写的论文,地址:

Ascend: a Scalable and Unified Architecture for Ubiquitous Deep Neural Network Computing : Industry Track Paper | IEEE Conference Publication | IEEE Xplore

本文记录如何在拥有Ascend310芯片的Ubuntu服务器上搭建docker推理环境并完成YOLO8推理。

一、驱动下载安装

 直接到Ascend官网,根据自己的芯片型号下载对应的驱动

固件与驱动-昇腾社区

我们安装上面页面给出的下载链接,下载driver和固件 

  驱动的安装也较为简单,首先增加对软件包的可执行权限

chmod +x A300-3010-npu-driver_23.0.0_linux-x86_64.run
chmod +x A300-3010-npu-firmware_7.1.0.3.220.run

 然后执行下面的命令安装:

./A300-3010-npu-driver_23.0.0_linux-x86_64.run --full --install-for-all

关机重启,驱动安装成功 

关于驱动安装,官方也给出了具体的详细教程:

昇腾社区-官网丨昇腾万里 让智能无所不及

二、Docker环境搭建

Ascend芯片推理环境我们选择在docker容器内搭建,AscendHub上有各种各样已经搭建好相关环境的Docker镜像,只需要宿主机有ascend芯片和驱动即可,免去了我们手动下载配置CANN、mxvision等软件。因此,这种环境配置方式首先需要在服务器上安装好docker,docker的安装较为简单,如果没有安装,apt源设置正确且可用,直接按照下面的步骤即可安装docker。

 安装好docker以后就可以下载ascendhub的官方镜像,下面给出AscendHub地址: 

AscendHub

我们直接注册账号然后按照上面给出的步骤把docker images下载到服务器即可。值得注意的是宿主机需要满足下面的调条件:

  • 物理机上有Ascend芯片
  • 物理机已安装对应CANN版本的驱动和固件(注意跟你要下载的镜像支持的驱动对应,比如在ascendhub下载的镜像往往是最新版本的cann、mxvision,此时宿主机的驱动版本注意对应,如果驱动太老的话是不行的,需要升级或者重装。版本对应关系可以从下面给出的昇腾官网查询到)
  • 物理机已安装Docker,且Docker网络可用

我这里以安装 infer-modelzoo 镜像(mxvision版本)为例,该镜像包含模型转换、模型推理等功能。

将镜像下载到本地以后,docker启动命令示例如下

docker run -it \
--device=/dev/davinci0 \
--device=/dev/davinci_manager \
--device=/dev/devmm_svm \
--device=/dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /var/log/npu:/var/log/npu \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v /usr/slog:/usr/slog \
-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/tools/:/usr/local/Ascend/driver/tools/ \
-v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ \
-v /data:/data \
ascendhub.huawei.com/public-ascendhub/infer-modelzoo:{tag} \
/bin/bash
  • tag为镜像版本号,如21.0.3。
  • -u 以指定用户进入容器,如不指定用户,默认为HwHiAiUser。
  • /usr/local/Ascend/driver为物理机上安装的NPU驱动目录,根据实际安装的驱动目录进行挂载。
  • /data为模型转换和推理要用的代码目录,根据实际代码目录进行挂载。
  • 命令中默认挂载0卡到容器中,可根据实际需要挂载device。

 下面是我自己的docker容器启动命令:

docker run -itd --name ascend-infer --network=host --device=/dev/davinci0 --device=/dev/davinci_manager --device=/
dev/devmm_svm --device=/dev/hisi_hdc -v /usr/local/dcmi:/usr/local/dcmi -v /var/log/npu:/var/log/npu -v /usr/local/Ascend/driver:/usr/local/Ascend/driver -v
 /usr/slog:/usr/slog -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/Ascen
d/driver/tools/:/usr/local/Ascend/driver/tools/ -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ -v /work:/work ascendhub.huawei.com/public-ascendhub/infer-modelzoo:23.0.RC2-mxvision /bin/bash

 上图可以看到,我们成功启动了容器并进入到了容器中。

三、模型转化 

接下来我们在本地电脑将yolov8s.pt转onnx(我这里直接用的是yolo export命令)

特别需要注意,pt模型转onnx模型的过程中,onnx算子版本必须保持为11,否则后onnx转om会失败!!! 

 将转化好的ONNX模型上传到服务器的work目录下(由于容器启动的时候/work挂载/work,因此将本地的onnx模型上传到根目录下的/work目录下,在容器内就可以使用该onnx文件)

下面在容器内对onnx模型进行转化,将其转化为适用于Ascend显卡平台的om模型 。这里我们要使用到ATC转化工具(上面运行的容器内有安装好),下面首先简单了解一下ATC命令:

 atc  --model=./yolov8s.onnx  --framework=5 --output=./yolov8s --input_format=NCHW --input_shape="images:1,3,640,640" --soc_version=Ascend310

--model:待转换的ONNX模型。(必须)

--framework:5代表ONNX模型。(必须)

--output:输出的om模型。(必须)

--input_format:输入数据的格式。Caffe、ONNX默认为NCHW;TensorFlow默认为NHWC。

--input_shape:输入数据的shape

--soc_version: 模型转换时指定芯片版本(必须)

上面的转换指令几乎是最简的,更多atc转化参数请参考官方文档,链接如下: 

昇腾社区-官网丨昇腾万里 让智能无所不及

我这里以HwHiAiUser用户登录进docker容器内执行 上述atc模型转换命令出现报错,有大量的Permission Error。(因为我是以root登录进服务器并且以root身份将onnx文件上传到服务器,因此onnx文件所属组和拥有组都是root)

 大概是 HwHiAiUser用户无相关权限,退出容器以root身份进入docker内,重新执行上述atc模型转化命令,成功。

 此时,在容器内的/work目录下可以看到成功转化的yolov8s.om模型。 

接下来修改yolov8s.om所属组和拥有者,使其所属用户和用户组为HwHiAiUser

chown HwHiAiUser:HwHiAiUser yolov8s.om
chown HwHiAiUser:HwHiAiUser fusion_result.json

可以直接将yolo8s.om所在的上级目录(work目录)更改为所属用户和用户组为HwHiAiUser

chown -R  HwHiAiUser:HwHiAiUser /work

四、使用mxvision sdk进行推理 

接下来我们mxvision使用yolov8s.om模型进行加速推理 。官方也有详细的教程:

开发流程-使用API接口方式开发(Python)-mxVision 用户指南-智能视频分析-MindX SDK5.0.1开发文档-昇腾社区 (hiascend.com)

mxvision sdk一般有两种推理方式。一种是pipeline,需要我们写pipeline文件,不得不说ascend自带的视频图片编解码能力(DVPP、AIPP)真的很强大,不仅自持硬件加速功能,而且模块都封装好了,只需要我们调用相关接口即可,比如图片直接输入、视频流直接输入rtsp流地址即可,无需我们自己写编解码程序、写前处理程序、写后处理程序,直接将模型预测结果返回!!! 改变了我们过去需要用opencv numpy等去做相关的工作。第二种是使用api的方式,这种方式不常用,官方给出的案例都是pipeline推理方式,几乎没有一个完整的api推理的案例,唯一可借鉴的是ascend论坛给出的:

https://www.hiascend.com/forum/thread-0281145770724671193-1-1.html
我们这里使用api推理方式,因为这种方式最符合我们过去使用pytorch、paddlepaddle、tensorflow等原生框架推理、ONNX中间态推理的风格习惯,而使用pipeline推理虽然代码量很少很少,但是得要我们比较深入地了解pipeline的流程及芯片内置的模块、接口等。有的项目为了适配不同的平台,可能分为Tensorrt推理版本的代码、onnx推理版本的代码、opencv dnn推理版本的代码 、openvion推理版本.....而使用api推理只需要我们修改之前写过的很少的代码,就拿onnx推理版本来说,基本上修改几行代码即可将onnx推理版本的代码修改为华为Ascend推理版本的代码。

import cv2
import numpy as np
import time
from mindx.sdk import Tensor  # mxVision 中的 Tensor 数据结构
from mindx.sdk import base

CLASSES={0: 'person', 1: 'bicycle', 2: 'car', 3: 'motorcycle', 4: 'airplane', 5: 'bus', 
 6: 'train', 7: 'truck', 8: 'boat', 9: 'traffic light', 10: 'fire hydrant', 
 11: 'stop sign', 12: 'parking meter', 13: 'bench', 14: 'bird', 15: 'cat', 
 16: 'dog', 17: 'horse', 18: 'sheep', 19: 'cow', 20: 'elephant', 21: 'bear', 
 22: 'zebra', 23: 'giraffe', 24: 'backpack', 25: 'umbrella', 26: 'handbag', 
 27: 'tie', 28: 'suitcase', 29: 'frisbee', 30: 'skis', 31: 'snowboard',
 32: 'sports ball', 33: 'kite', 34: 'baseball bat', 35: 'baseball glove',
 36: 'skateboard', 37: 'surfboard', 38: 'tennis racket', 39: 'bottle', 
 40: 'wine glass', 41: 'cup', 42: 'fork', 43: 'knife', 44: 'spoon', 45: 'bowl', 
 46: 'banana', 47: 'apple', 48: 'sandwich', 49: 'orange', 50: 'broccoli', 
 51: 'carrot', 52: 'hot dog', 53: 'pizza', 54: 'donut', 55: 'cake', 56: 'chair', 
 57: 'couch', 58: 'potted plant', 59: 'bed', 60: 'dining table', 61: 'toilet', 
 62: 'tv', 63: 'laptop', 64: 'mouse', 65: 'remote', 66: 'keyboard', 67: 'cell phone',
 68: 'microwave', 69: 'oven', 70: 'toaster', 71: 'sink', 72: 'refrigerator', 
 73: 'book', 74: 'clock', 75: 'vase', 76: 'scissors', 77: 'teddy bear', 
 78: 'hair drier', 79: 'toothbrush'}

class YOLO8:
    def __init__(self,model_path,conf_thres=0.25, iou_thres=0.45):
        self.conf_threshold = conf_thres
        self.iou_threshold = iou_thres
        self.input_height=640
        self.input_width=640
        self.class_names=CLASSES
        reverse_class_names = {v : k for k, v in self.class_names.items()}
        self.reverse_class_names=reverse_class_names
        #模型初始化
        base.mx_init()
        self.model = base.model(modelPath='yolov8s.om', deviceId=0) 
        
    #前处理模块
    def pre_process(self,img, new_shape):
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img, _, _ = self.letterbox(img, new_shape)
        img = img.astype('float32')
        img /= 255.0
        img = np.transpose(img, [2, 0, 1])
        img = np.expand_dims(img, axis=0)
        img = np.ascontiguousarray(img)
        return img
    #推理模块
    def inference(self,img):
        # print(img)
        img_tensor = Tensor(img)
        img_tensor.to_device(0)
        start = time.perf_counter()
        outputs = self.model.infer([img_tensor])
        print(f"Inference time: {(time.perf_counter() - start) * 1000:.2f} ms")
        nps = [] # 原始numpy结果数组
        for i in range(len(outputs)):
            outputs[i].to_host()
            n = np.array(outputs[i])
            nps.append(n) # 使用自定义后处理时直接用此numpy数组即可!!!
        #这里的nps 数组维度就是[1,84,8400].后续就可以后处理了
        return nps
    .......
    letterbox nms 后处理等模块与原来保持一致,此处省略

然后执行我们写好的yolo8_om_det.py ,我这里推理了yolo官方给出的bus.jpg(下图),推理尺寸640*640

可以看到程序执行成功,整个推理过程为14ms左右,我这里的服务器是租用的,应该是租用服务器Ascend310算力做了切分之类的,反正这个推理速度不是正常的,不过这个主要以演示为主,正常的应该是3ms以内推理一张图片,下面是图片推理结果

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

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

相关文章

YAML详情

一、kubernetes支持对象 Kubernetes支持YAML和JSON格式管理资源对象 JSON格式:主要用于api接口之间消息的传递YAML格式:用于配置和管理,YAML是一种简洁的非标记性语言,内容格式人性化,较易读 二、YAML语法格式注意点 …

起保停电路工作原理

一、电路组成 起保停电路由电源保护设备(空气开关)、交流接触器、启动按钮、停止按钮和用电设备组成。 起保停电路的组成部分通常可分为四个部分: 保护部分:(空气开关)在电流或电压超出一定范围时自动切断…

web学习笔记(五十八)

目录 1. v-model 双向数据绑定 2. 事件修饰符 3. 路径别名 4. setup语法糖 4.1 语法糖的概念 4.2 setup语法糖 5. 配置代理服务器 1. v-model 双向数据绑定 v-model 双向数据绑定只能使用在表单标签; v-model双向数据绑定原理:采用 Object.de…

Unity3D让BoxCollider根据子物体生成自适应大小

系列文章目录 unity工具 文章目录 系列文章目录unity工具 👉前言👉一、编辑器添加👉二、代码动态添加的方法(第一种)👉三、代码动态添加的方法(第二种)👉四、重新设置模型的中心点👉壁纸分享👉…

打卡信奥刷题(21)用Scratch图形化工具信奥P7071 [CSP-J2020] 优秀的拆分

使用2进制进行拆分是比较好的解决方案,毕竟对于大家来说二进制转换是非常熟的,如果不会可以参考打卡信奥刷题(19)用Scratch图形化工具信奥B3972 [语言月赛 202405] 二进制 题解 ,输出的时候再转换一下输出,…

【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数

本节博客是对阅读剑指offer后的笔记归纳总结,有需要借鉴即可。 目录 1.p21-p25内容概要2.询问语法概念常考:CPP关键字理解举例:sizeof空类 3.分析代码举例:类中拷贝构造的无限递归问题 4.写代码常考点:类内成员函数、迭…

封装了一个iOS水平方向瀑布流布局

首先查看效果图 是支持多分区的 思路就是和竖直方向上的瀑布流布局是一样的, 只不过这里记录的列是水平方向的,同时要记录下 当前最小的x 所在的列,其实原理和竖直方向上的是相同的 ,下面贴出代码 父类layout中的代码 // // …

MacOS使用PhpStorm+Xdebug断点调式

基本环境: MacOS m1 PhpStorm 2024.1 PHP7.4.33 Xdebug v3.1.6 1、php.ini 配置 [xdebug] zend_extension "/opt/homebrew/Cellar/php7.4/7.4.33_6/pecl/20190902/xdebug.so" xdebug.idekey "PHPSTORM" xdebug.c…

Java开发大厂面试第26讲:生产环境如何排查问题和优化 JVM?

通过前面几个课时的学习,相信你对 JVM 的理论及实践等相关知识有了一个大体的印象。而本课时将重点讲解 JVM 的排查与优化,这样就会对 JVM 的知识点有一个完整的认识,从而可以更好地应用于实际工作或者面试了。 我们本课时的面试题是&#x…

C++ (week4):Linux系统编程1:文件

文章目录 一、文件:Linux文件操作1.基于文件指针的文件操作2.Linux目录操作(1)目录路径0.error1.getcwd2.chdir3.创建目录:mkdir4.删除目录:rmdir5.unlink(路径名) (2)目录流 DIR*0.模型1.opendir:打开目录流2.closedir&#xff1…

MT3040 矩形覆盖

代码&#xff1a; #include <bits/stdc.h> using namespace std; typedef long long ll; const int N 3e5 10; int n, ans, d, w; stack<int> s; // 单调栈 // 如果楼高度类似121&#xff08;凸&#xff0c;两边相等&#xff0c;中间比两边的大&#xff09;&…

【C++】二叉树进阶(二叉搜索树)

目录 一、内容安排说明二、 二叉搜索树2.1 二叉搜索树概念2.2 二叉搜索树操作2.2.1 二叉搜索树的查找2.2.2 二叉搜索树的插入2.2.3 二叉搜索树的删除 2.3 二叉搜索树的代码实现2.3.1 二叉搜索树的节点设置2.3.2 二叉搜索树类的框架2.3.3 二叉搜索树的查找函数2.3.3.1 非递归方式…

如何使用多种算法解决LeetCode第135题——分发糖果问题

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

企业档案管理系统软件都有哪些分类

企业档案管理系统软件可以根据其功能和特点进行分类。以下是一些常见的分类&#xff1a; 1. 全能类档案管理系统&#xff1a;提供文件存储和检索功能&#xff0c;并支持多种文件类型和格式的管理&#xff0c;如文本文件、图像文件、音频文件等。 2. 电子档案管理系统&#xff1…

源码编译安装LAMP(安装apeche mysql php 论坛 网站 巨详细版)

目录 一.LAMP架构相关概述 1.各组件作用 Linux&#xff08;平台&#xff09; Apache&#xff08;前台&#xff09; MySQL&#xff08;后台&#xff09; PHP/Perl/Python&#xff08;中间连接&#xff09; 总结 二.编译安装Apache httpd服务 1.关闭防火墙&#xff0c;将…

2024年【T电梯修理】考试内容及T电梯修理新版试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【T电梯修理】考试内容及T电梯修理新版试题&#xff0c;包含T电梯修理考试内容答案和解析及T电梯修理新版试题练习。安全生产模拟考试一点通结合国家T电梯修理考试最新大纲及T电梯修理考试真题汇总&#xff0c;…

UI控件与视图层次:探索界面的无限可能

[OC]UI学习笔记 文章目录 [OC]UI学习笔记视图和视图层次结构CGRectUILabelUIButtonUIView控件UIView的层级关系UIWindow定时器和视图移动UISwitch进度条和滑动条控件步进器和分栏控件警告对话框与等待指示器UITextField 视图和视图层次结构 Objective-C中的UI编程主要围绕视图…

IO系列(八) -浅析NIO工作原理

一、简介 现在使用 NIO 的场景越来越多&#xff0c;很多网上的技术框架或多或少的使用 NIO 技术&#xff0c;譬如 Tomcat、Jetty、Netty&#xff0c;学习和掌握 NIO 技术已经不是一个 Java 攻城狮的加分技能&#xff0c;而是一个必备技能。 那什么是 NIO 呢&#xff1f; NIO…

民国漫画杂志《时代漫画》第24期.PDF

时代漫画24.PDF: https://url03.ctfile.com/f/1779803-1248635000-177187?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps: 资源来源网络!

怎么理解直接程序控制和中断方式?

直接程序控制 看完之后是不是依然一头雾水&#xff1f;来看下面两个例子 无条件传送 假设你正在使用键盘打字。当你敲击键盘上的一个键时&#xff0c;键盘会立即产生一个信号&#xff08;即输入数据&#xff09;&#xff0c;并且这个信号会立即被电脑接收。在这个过程中&…