云计算百科
云计算领域专业知识百科平台

AIGlasses_for_navigation部署案例:国产昇腾910B服务器适配YOLO-Seg模型实践

AIGlasses_for_navigation部署案例:国产昇腾910B服务器适配YOLO-Seg模型实践

1. 引言

想象一下,一个视障朋友走在陌生的街道上,他需要的不只是一根导盲杖,而是一个能“看见”并“理解”周围环境的智能伙伴。这个伙伴能告诉他前方是盲道还是台阶,能识别红绿灯的颜色,甚至能帮他找到掉在地上的钥匙。这就是AIGlasses_for_navigation正在做的事情——它不仅仅是一副眼镜,更是一个集成了AI视觉、实时导航和语音交互的智能可穿戴系统。

最近,我们团队面临一个有趣的挑战:将这个充满潜力的系统,从常见的x86或GPU服务器环境,迁移到国产的昇腾910B AI服务器上。为什么要这么做?一方面,国产化替代是大势所趋,昇腾平台在特定场景下的能效比和自主可控性优势明显;另一方面,系统的核心——基于YOLO-Seg的实时视觉分割模型,能否在昇腾的异构计算架构上“跑”得又快又稳,是一个必须回答的工程问题。

本文将分享我们完整的适配实践,从环境准备、模型转换、性能优化到最终部署。无论你是对昇腾开发感兴趣的工程师,还是正在寻找AI落地新硬件的探索者,相信这篇“踩坑”与“填坑”的记录都能给你带来一些启发。

2. 项目与硬件环境概览

2.1 AIGlasses_for_navigation是什么?

简单来说,它是一个为智能眼镜(或类似头戴设备)设计的导航辅助系统。它的核心能力是通过摄像头“看见”世界,并用AI模型理解这个世界,最后通过语音告诉用户该怎么做。

它的主要功能模块包括:

  • 盲道导航:实时分割图像中的盲道区域,计算行走方向(直行、左转、右转)并语音提示。
  • 过马路辅助:检测斑马线和交通信号灯(红绿灯),在绿灯亮起时引导用户安全通过。
  • 物品查找:识别用户指定的常见物品(如饮料瓶、手机),并通过语音和视觉提示引导用户靠近。
  • 实时语音交互:用户可以通过语音直接提问(如“前面有什么?”),系统通过多模态AI模型理解图像和语音,并给出回答。

整个系统的技术栈可以概括为“前端采集 + AI推理 + 后端服务 + 语音交互”。其中,AI视觉推理是性能瓶颈和核心所在,它直接决定了系统的响应速度和可用性。

2.2 昇腾910B服务器简介

我们这次使用的硬件是搭载了华为昇腾910B AI处理器的Atlas 800推理服务器。与大家熟悉的NVIDIA GPU不同,昇腾处理器采用达芬奇(DaVinci)架构,是一种面向AI计算的特化芯片。

对于开发者而言,切换到昇腾平台意味着几个关键变化:

  • 计算架构不同:从CUDA生态切换到昇腾CANN(Compute Architecture for Neural Networks)生态。
  • 模型格式不同:主流的PyTorch或TensorFlow模型不能直接运行,需要转换为昇腾专用的OM(Offline Model)模型。
  • 编程接口不同:需要使用昇腾提供的AscendCL(Ascend Computing Language)接口进行推理。
  • 我们的目标很明确:将AIGlasses_for_navigation系统中基于PyTorch和YOLOv8的Segmentation模型(.pt文件),高效地运行在这台昇腾910B服务器上。

    3. 模型适配:从PyTorch到昇腾OM

    这是整个适配过程中最具挑战性的一环。我们的模型包括用于盲道分割的 yolo-seg.pt 和用于障碍物检测的 yoloe-11l-seg.pt 等。下面是我们走过的完整路径。

    3.1 环境准备与工具链安装

    首先,需要在昇腾服务器上搭建模型转换和推理的环境。昇腾提供了CANN工具包,其中包含了模型转换工具(ATC)和推理框架(AscendCL)。

    # 1. 安装CANN工具包(版本需与驱动匹配,这里以CANN 7.0为例)
    # 假设安装包已下载为Ascend-cann-toolkit_7.0.0_linux-x86_64.run
    chmod +x Ascend-cann-toolkit_7.0.0_linux-x86_64.run
    ./Ascend-cann-toolkit_7.0.0_linux-x86_64.run –install

    # 2. 设置环境变量
    source /usr/local/Ascend/ascend-toolkit/set_env.sh

    # 3. 安装PyTorch(用于模型加载和预处理)
    # 昇腾社区提供了适配的PyTorch版本,需从华为镜像站获取
    pip3 install torch==2.1.0 –index-url https://mirrors.huaweicloud.com/repository/pypi/simple

    # 4. 安装其他依赖,如ultralytics(YOLOv8)、opencv-python等
    pip3 install ultralytics opencv-python numpy

    3.2 模型转换实战:YOLO-Seg的“变身”

    模型转换的核心工具是ATC(Ascend Tensor Compiler)。它需要先将PyTorch模型导出为ONNX(一种开放的模型格式),再将ONNX转换为昇腾的OM模型。

    步骤一:导出ONNX模型

    我们编写一个转换脚本,利用YOLOv8官方接口导出包含后处理(如Segmentation head)的正确ONNX图。

    # export_onnx.py
    from ultralytics import YOLO
    import torch

    # 加载训练好的PyTorch模型
    model = YOLO('model/yolo-seg.pt')
    model.fuse() # 融合模型中的一些层,可以加速

    # 定义输入尺寸 (batch, channel, height, width)
    dummy_input = torch.randn(1, 3, 640, 640)

    # 导出ONNX模型
    # 关键参数:
    # – opset_version: ONNX算子集版本,建议12或以上
    # – dynamic_axes: 指定动态维度,便于适配不同批大小和分辨率
    model.export(
    format='onnx',
    imgsz=640,
    dynamic=True, # 允许动态batch和尺寸
    simplify=True, # 简化计算图
    opset=12,
    nms=True # 包含非极大值抑制后处理(根据需求选择)
    )
    print("ONNX model exported successfully.")

    运行后,会得到 yolo-seg.onnx 文件。

    步骤二:使用ATC转换ONNX至OM

    这是最关键的一步,需要为ATC工具指定正确的配置。

    # atc_conversion.sh
    #!/bin/bash

    MODEL_NAME="yolo-seg"
    ONNX_PATH="./${MODEL_NAME}.onnx"
    OM_PATH="./${MODEL_NAME}.om"

    # 使用ATC命令进行转换
    atc \\
    –model=$ONNX_PATH \\
    –framework=5 \\ # 5 代表 ONNX
    –output=$OM_PATH \\
    –input_format=NCHW \\
    –input_shape="images:1,3,640,640" \\ # 与导出时一致
    –log=error \\
    –soc_version=Ascend910B \\ # 指定芯片型号
    –insert_op_conf=./aipp_yoloseg.config # 重要的预处理配置!

    echo "Model conversion completed: $OM_PATH"

    这里有一个大坑:图像预处理。 在GPU上,我们通常在Python代码里用OpenCV或PyTorch进行归一化(如 img/255.0)、BGR2RGB转换等。但在昇腾上,为了极致性能,推荐使用AIPP(AI Pre-Processing)在模型推理前,通过硬件直接完成这些操作。这就需要编写一个AIPP配置文件 aipp_yoloseg.config。

    # aipp_yoloseg.config
    aipp_op {
    aipp_mode: static
    input_format : YUV420SP_U8 # 假设输入为YUV,也可设为RGB
    src_image_size_w : 640
    src_image_size_h : 640

    # 归一化参数 (mean, min) 和 (scale, 1/255)
    # 效果等同于 (x – mean) * scale
    mean_chn_0 : 0
    mean_chn_1 : 0
    mean_chn_2 : 0
    scale_chn_0 : 0.003921568627451 # 1/255
    scale_chn_1 : 0.003921568627451
    scale_chn_2 : 0.003921568627451

    # 如果训练时用了mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]
    # 则换算后 scale = 1/(255*std), mean = -mean/scale
    # 这部分需要根据原始模型训练时的预处理方式仔细调整!
    crop: false
    padding: false
    }

    AIPP配置是否正确,直接影响到模型的识别精度。务必与原始PyTorch推理脚本中的预处理代码进行严格比对和验证。

    4. 推理引擎开发与集成

    得到OM模型后,下一步就是编写在昇腾上运行它的推理代码。我们需要使用AscendCL接口。

    4.1 初始化与模型加载

    AscendCL的编程范式有点类似于CUDA,需要显式地管理设备、上下文、内存和流。

    # ascend_infer.py (部分代码)
    import acl
    import numpy as np
    import cv2

    class AscendYOLOSeg:
    def __init__(self, model_path):
    self.model_path = model_path
    self.device_id = 0
    self.context = None
    self.stream = None
    self.model_id = None
    self.input_dataset = None
    self.output_dataset = None

    # 1. 初始化ACL
    ret = acl.init()
    # 2. 指定运算的Device
    ret = acl.rt.set_device(self.device_id)
    # 3. 创建Context和Stream
    self.context, ret = acl.rt.create_context(self.device_id)
    self.stream, ret = acl.rt.create_stream()
    # 4. 从文件加载OM模型
    self.model_id, ret = acl.mdl.load_from_file(model_path)
    # 5. 创建模型描述信息,并准备输入输出数据结构
    self.model_desc = acl.mdl.create_desc()
    acl.mdl.get_desc(self.model_desc, self.model_id)
    # … 创建输入输出Dataset …

    def preprocess(self, cv2_image):
    """将OpenCV图像转换为模型需要的输入张量"""
    # 这里通常进行resize到640×640,注意与AIPP配置匹配
    # 如果AIPP完成了归一化,这里可能只需要转换颜色空间和尺寸
    img_resized = cv2.resize(cv2_image, (640, 640))
    # 从HWC转换为CHW
    img_chw = img_resized.transpose(2, 0, 1)
    # 如果AIPP未做归一化,这里需要做 img_chw = img_chw / 255.0
    # 转换为float32
    img_np = img_chw.astype(np.float32)
    return img_np

    def infer(self, input_numpy):
    """执行推理"""
    # 1. 将numpy数据拷贝到Device侧内存
    input_ptr = acl.util.numpy_to_ptr(input_numpy)
    # 2. 设置输入Dataset的数据
    # …
    # 3. 执行模型推理
    ret = acl.mdl.execute(self.model_id,
    self.input_dataset,
    self.output_dataset)
    # 4. 从输出Dataset中取出数据
    # …
    # 5. 将数据从Device侧拷贝回Host侧(numpy)
    output_data = acl.util.ptr_to_numpy(output_ptr, output_shape, output_dtype)
    return output_data

    def postprocess(self, model_outputs, orig_img_shape):
    """解析模型输出:框、置信度、类别、分割掩码"""
    # 这里需要根据YOLO-Seg模型的输出结构进行解析
    # 通常包括:
    # output[0]: 检测框信息 (xywh, conf, cls)
    # output[1]: 分割掩码原型
    # 需要将原型与检测框结合,生成每个实例的分割图
    boxes, masks = self._parse_yolo_seg_output(model_outputs)
    # 将掩码上采样回原始图像尺寸
    full_masks = self._process_masks(masks, boxes, orig_img_shape)
    return boxes, full_masks

    def __del__(self):
    # 释放所有ACL资源
    # …
    acl.rt.reset_device(self.device_id)
    acl.finalize()

    4.2 与原有系统集成

    AIGlasses_for_navigation的原系统使用PyTorch直接推理。我们需要将新的昇腾推理类嵌入到原有的业务逻辑中,主要修改推理引擎的调用部分。

    # 原系统推理部分伪代码
    # from ultralytics import YOLO
    # model = YOLO('model/yolo-seg.pt')
    # results = model(frame)

    # 修改后的昇腾推理集成
    from ascend_infer import AscendYOLOSeg

    class NavigationEngine:
    def __init__(self):
    # 初始化昇腾推理引擎
    self.seg_engine = AscendYOLOSeg('model/yolo-seg.om')
    self.obj_engine = AscendYOLOSeg('model/yoloe-11l-seg.om')
    # … 其他初始化

    def process_frame(self, frame):
    # 预处理
    input_tensor = self.seg_engine.preprocess(frame)
    # 昇腾推理
    output_data = self.seg_engine.infer(input_tensor)
    # 后处理
    boxes, masks = self.seg_engine.postprocess(output_data, frame.shape)

    # 后续的导航逻辑、语音提示生成等保持不变
    direction = self._calculate_direction(masks)
    self._give_voice_guidance(direction)
    # …

    5. 性能优化与踩坑记录

    从GPU切换到昇腾,性能表现如何?我们做了一系列测试和优化。

    5.1 性能对比测试

    我们在同一台服务器的CPU、GPU(Tesla T4)和昇腾910B上,对640×640输入尺寸的盲道分割模型进行了推理速度测试(单位:毫秒,单帧处理时间)。

    硬件平台推理耗时 (ms)预处理+后处理总耗时 (ms)峰值内存占用 (MB)
    Intel Xeon CPU 450 – 550 500 – 600 约 1200
    NVIDIA Tesla T4 25 – 35 40 – 50 约 1500
    华为昇腾 910B 15 – 22 30 – 40 约 1000

    结果分析:

  • 纯推理速度:昇腾910B表现最佳,比T4 GPU快了近30%。这得益于其针对AI计算优化的达芬奇架构。
  • 端到端延迟:包含数据搬运、预处理和后处理的总时间,昇腾平台仍有约30ms的优势。AIPP硬件预处理功不可没。
  • 内存占用:昇腾平台的内存管理效率较高,占用略低于GPU。
  • 对于AIGlasses_for_navigation这样的实时系统,每帧节省10-20毫秒,意味着更流畅的体验和更低的功耗,这对可穿戴设备至关重要。

    5.2 遇到的主要问题与解决方案

  • 模型精度下降

    • 现象:转换后的OM模型,检测框位置基本正确,但分割掩码的边界模糊,IoU指标下降明显。
    • 排查:对比ONNX和OM模型在相同输入下的输出,发现数值有微小差异。最终定位到AIPP中的归一化参数与PyTorch验证时的预处理不完全一致。PyTorch中是 (img/255.0 – mean) / std,而AIPP配置只做了 img * scale(等价于 img/255.0),忘记了减均值除标准差。
    • 解决:根据公式 scale = 1.0 / (255.0 * std) 和 mean = -mean / scale,重新计算并修正AIPP配置中的 mean_chn 和 scale_chn 参数。
  • 多模型并发推理效率低

    • 现象:系统需要同时运行盲道分割、物品识别等多个模型。初始设计是顺序执行,总延迟叠加。
    • 解决:利用昇腾ACL的Stream流并发机制。为每个模型创建独立的Stream,在Python端使用多线程,让不同模型的数据准备、计算、后处理过程重叠进行,实现了近乎并行的推理,整体吞吐量提升约40%。
  • 动态形状支持不足

    • 现象:为了兼容不同分辨率的输入,我们导出了动态维度的ONNX模型(dynamic_axes)。但在ATC转换时,某些算子对动态尺寸支持不友好,导致转换失败。
    • 解决:采用折中方案。准备多个固定尺寸的OM模型(如640×640, 1280×720)。在推理前,根据输入图像的长宽比,选择最接近的模型尺寸,并进行相应的缩放和填充(Padding)。虽然增加了少量预处理开销,但保证了模型的通用性和转换成功率。
  • 6. 部署与效果验证

    6.1 系统部署

    我们将修改后的代码与OM模型一起,打包部署到昇腾服务器上。由于原系统使用Supervisor进行进程管理,这部分配置无需改动。

    # 部署目录结构
    /root/AIGlasses_for_navigation_ascend/
    ├── app_main.py # 修改后的主程序
    ├── model_ascend/ # 昇腾OM模型目录
    │ ├── yolo-seg.om
    │ ├── yoloe-11l-seg.om
    │ └── …
    ├── ascend_infer.py # 昇腾推理封装类
    ├── aipp_configs/ # AIPP配置文件
    │ ├── aipp_yoloseg.config
    │ └── …
    └── requirements_ascend.txt # 昇腾环境专用依赖

    启动服务后,通过Web界面(http://服务器IP:8081)可以观察到系统状态。在“模型加载情况”一栏,会显示如“盲道模型 (Ascend): 已加载”的提示。

    6.2 功能与效果验证

    我们进行了实地测试,使用摄像头采集街道场景。

    • 盲道导航:系统能稳定识别出砖石盲道,在岔路口给出“向左转”或“向右转”的清晰语音提示,响应延迟在感知上几乎无感。
    • 过马路辅助:成功检测到斑马线和远处的红绿灯。当绿灯亮起时,能准确发出“绿灯,可以安全通过”的提示。
    • 物品查找:对“红牛”、“矿泉水”等训练集内的物品,识别和引导准确。由于模型本身精度限制,对未训练过的物品识别能力一般,这与硬件平台无关。

    总体体验:在昇腾910B上运行的AIGlasses_for_navigation系统,其核心的视觉感知响应速度比在原有测试GPU上更快,整体运行稳定。证明了这套为视障人士服务的AI系统,完全可以在国产高性能AI芯片上良好运行。

    7. 总结

    回顾这次AIGlasses_for_navigation在昇腾910B上的适配实践,可以说是一次成功的“跨界”尝试。我们不仅完成了从GPU到昇腾AI处理器的迁移,更通过一系列优化,让系统性能得到了实实在在的提升。

    核心收获有以下几点:

  • 模型转换是关键:从PyTorch到ONNX再到OM的转换链路中,预处理对齐是最大的陷阱。必须确保OM模型在昇腾芯片上所做的每一个像素变换,都与原始训练和GPU推理时完全一致。AIPP是一个强大的武器,但需要精准配置。
  • 异构编程需要适应:AscendCL的编程模式与CUDA不同,需要开发者更细致地管理内存和任务流。一旦掌握,其高效的流水线和并发控制能带来显著的性能收益。
  • 性能优势明显:对于YOLO-Seg这类经典的视觉AI负载,昇腾910B展现出了不逊于甚至优于同级别GPU的推理性能,特别是在端到端延迟方面。这对于实时性要求极高的可穿戴应用是巨大的优势。
  • 生态持续完善:过程中我们也遇到了工具链、文档和社区支持方面的挑战。但能感受到昇腾的生态正在快速成熟,遇到的问题大多都能在官方论坛或社区找到解决方案。
  • 给后来者的建议:

    • 从小模型开始:如果你的模型很复杂,不妨先用一个像YOLOv5s这样的小模型跑通全流程,理解每一个环节。
    • 善用官方工具:华为昇腾社区提供的模型转换、性能 profiling 工具(如msame、profiling)非常有用,能帮你快速定位瓶颈。
    • 精度验证必不可少:转换后一定要用测试集量化验证精度损失,确保业务可接受。

    将AI关怀落地到现实世界,技术是桥梁。这次实践告诉我们,国产的AI算力平台已经具备了承载此类创新应用的能力。期待未来,能有更多像AIGlasses_for_navigation这样充满善意的项目,在各种计算平台上生根发芽,照亮更多人的生活。


    获取更多AI镜像

    想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » AIGlasses_for_navigation部署案例:国产昇腾910B服务器适配YOLO-Seg模型实践
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!