安装驱动和固件

检查服务器是否安装驱动与固件(终端输入npu-smi info,如果正常返回显卡信息,说明驱动已安装好。使用python测试acl.rt.ser_device(0)命令,正常返回说明固件已安装好,卡死无返回说明固件没装)。如果没有,可从https://westwell.feishu.cn/drive/folder/HqbkfCASolpFxwd2lIVczNcWn8b拿到安装文件,拉到服务器上,进行安装,安装命令如下:

bash Ascend-hdk-310p-npu-driver_25.5.2_linux-aarch64.run # 安装驱动
bash Ascend-hdk-310p-npu-firmware_7.8.0.7.220.run #安装固件

安装docker

yum install -y dockeryum install -y docker

拉取镜像

  参考方式一:拉取容器镜像-安装CANN(容器场景)-软件安装-CANN商用版8.0.RC2开发文档-昇腾社区

docker pull swr.cn-south-1.myhuaweicloud.com/ascendhub/mindie:3.0.0b2-300I-Duo-py311-openeuler24.03-lts

启动容器

  启动脚本如下

#!/bin/bash
docker stop ascend-310p_3
docker rm ascend-310p_3
docker run -itd --privileged \
  --net=host \
  --ipc=host \
  --name ascend-310p_3 \
  --device=/dev/davinci0 \
  --device=/dev/davinci2 \
  --device=/dev/davinci4 \
  --device=/dev/davinci6 \
  --device=/dev/davinci_manager \
  --device=/dev/devmm_svm \
  --device=/dev/hisi_hdc \
  --device=/dev/isomgr \
  -v /cv:/cv \
  -v /usr/local/Ascend/driver:/usr/local/Ascend/driver:ro \
  -v /usr/local/Ascend/add-ons:/usr/local/Ascend/add-ons:ro \
  -v /var/log/npu/:/var/log/npu/ \
  -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi:ro \
  -v /var/log/npu/conf/devmm/common_devmm.cfg:/var/log/npu/conf/devmm/common_devmm.cfg \
  1f6e1a6cee5f \
  /bin/bash

容器内安装相关软件

#安装开发工具包组 (包含 make, gcc, g++ 等)
dnf groupinstall "Development Tools" -y 
# 安装opencv
cd opencv-4.11.0/
mkdir build && cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D WITH_V4L=ON -D WITH_QT=OFF -D WITH_GTK=OFF -D WITH_OPENGL=OFF -D BUILD_EXAMPLES=OFF ..
make -j$(nproc) 
sudo make install
# 安装ros2
bash -c 'cat << EOF > /etc/yum.repos.d/ROS.repo
[openEulerROS-humble]
name=openEulerROS-humble
baseurl=https://eulermaker.compass-ci.openeuler.openatom.cn/api/ems1/repositories/ROS-SIG-Multi-Version_ros-humble_openEuler-24.03-LTS-TEST4/openEuler%3A24.03-LTS/aarch64/
enabled=1
gpgcheck=0
EOF'
sudo dnf update
sudo dnf install ros-humble-ros-base -y

  参考gitee.com安装aclite

onnx转om

# yolov8
atc --model=yolov8n.onnx \
    --framework=5 \
    --output=yolov8n \
    --input_shape="images:1,3,640,640" \
    --soc_version=Ascend310P3 \
    --log=error

推理

import acl
import sys
import numpy as np
import cv2

# 假设你的 acllite 路径如下
sys.path.append('/home/samples/inference/acllite/python')
from acllite_model import AclLiteModel
from acllite_resource import AclLiteResource

def post_process(infer_output, conf_threshold=0.25, iou_threshold=0.45):
    """
    YOLOv8 后处理
    infer_output: model.execute 的返回值 (list of numpy arrays)
    """
    # 1. 提取输出(YOLOv8 默认输出 shape 为 [1, 84, 8400])
    # 84 代表: 4个坐标 + 80个类别
    # 8400 代表: 3个尺度的预测框总和
    data = infer_output[0][0] 
    data = data.transpose()  # 转置为 [8400, 84]

    boxes = []
    scores = []
    class_ids = []

    for row in data:
        classes_scores = row[4:]
        max_score = np.amax(classes_scores)
        
        if max_score > conf_threshold:
            # YOLOv8 输出的是 [center_x, center_y, w, h]
            cx, cy, w, h = row[:4]
            
            # 转换为 [x1, y1, w, h] 用于 cv2.dnn.NMSBoxes
            left = int(cx - w / 2)
            top = int(cy - h / 2)
            
            boxes.append([left, top, int(w), int(h)])
            scores.append(float(max_score))
            class_ids.append(np.argmax(classes_scores))

    # 2. 非极大值抑制 (NMS) 过滤重叠框
    indices = cv2.dnn.NMSBoxes(boxes, scores, conf_threshold, iou_threshold)
    
    results = []
    if len(indices) > 0:
        for i in indices.flatten():
            results.append({
                "box": boxes[i],
                "score": scores[i],
                "class_id": class_ids[i]
            })
    return results

# --- 主程序 ---
resource = AclLiteResource(2)
resource.init()

model = AclLiteModel("yolov8n.om")

# 预处理:注意 YOLOv8 通常需要归一化 (1/255.0)

start_event, ret = acl.rt.create_event()
end_event, ret = acl.rt.create_event()

stream = resource.stream

image = cv2.imread('/cv/1713418474155.jpg')
img_h, img_w = image.shape[:2]
while 1:
    #acl.rt.record_event(start_event, stream)
    image_resized = cv2.resize(image, (640, 640))
    image_data = image_resized.astype(np.float32) / 255.0  # 归一化
    image_data = image_data.transpose(2, 0, 1) # HWC 转 CHW

    # 执行推理
    acl.rt.record_event(start_event, stream)
    result_list = model.execute([image_data,])
    acl.rt.record_event(end_event, stream)

    acl.rt.synchronize_stream(stream)
    time_ms, ret = acl.rt.event_elapsed_time(start_event, end_event)
    # 后处理
    detections = post_process(result_list)
    #acl.rt.record_event(end_event, stream)

    #acl.rt.synchronize_stream(stream)
    #time_ms, ret = acl.rt.event_elapsed_time(start_event, end_event)

    print(f"硬件纯推理耗时 (NPU Pure Inference): {time_ms:.2f} ms")

    # 3. 可视化结果
    for det in detections:
        x, y, w, h = det['box']
        score = det['score']
        class_id = det['class_id']
    
        # 坐标还原到原图大小
        x = int(x * img_w / 640)
        y = int(y * img_h / 640)
        w = int(w * img_w / 640)
        h = int(h * img_h / 640)

        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.putText(image, f"ID:{class_id} {score:.2f}", (x, y - 10), 
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

    print(f"检测到 {len(detections)} 个目标")
    #cv2.imwrite('result.jpg', image)

acl.rt.destroy_event(start_event)
acl.rt.destroy_event(end_event)

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐