当前位置: 首页 > news >正文

Amlogic NPU 上手(一):安装amlnn-toolkit,YOLOv8n 导出ADLA

最近在做Amlogic NPU,想把流程记清楚。官方有开源仓库,但对照README自己装一遍,还是会踩到不少坑——尤其是国内网络、Git LFS、以及S905X5平台ID这件事。

这篇就按我自己实际操作的顺序写,走通这条链路:
yolov8n.pt → yolov8n.onnx → yolov8n_s905x5_w8a8.adla

1. amlnn-toolkit是干什么的

amlnn-toolkit是 Amlogic开源的一套转换工具,负责:

  • 导入.onnx/.tflite等模型
  • 量化(本文用w8a8
  • 按目标芯片编译
  • 导出.adla

可以简单理解为:

格式含义
.ptPyTorch 权重
.onnx中间交换格式
.adla给指定 Amlogic NPU 用的可部署模型

常见两种用法:

  1. x86_64 Linux PC:装amlnn_toolkit,在主机上转换模型(本文)
  2. Amlogic Debian 板端:装 edge toolkit,在板子上跑

相关仓库:

  • Amlogic-NN/amlnn-toolkit
  • Amlogic-NN/amlnn-model-playground

2. 安装 Miniconda / Miniforge

工具依赖PyTorch、ONNX、TensorFlow一堆包,建议独立Conda 环境,别污染系统 Python。我这边实测机器是x86_64 Linux。如果本机还没有Conda,先装Miniforge(或 Miniconda 也行):

wgethttps://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.shbashMiniforge3-Linux-x86_64.sh

安装时按提示确认许可证、安装目录,建议执行conda init。完成后:

source~/.bashrc conda--version

如果不想每次自动进base

conda config--setauto_activate_basefalse

然后创建 Python 3.10 环境(公开仓库 README 和cp310wheel 都按 3.10 来):

conda create-namlnn_toolkit_py310python=3.10-yconda activate amlnn_toolkit_py310 python--version

3. 克隆amlnn-toolkit(注意 Git LFS)

仓库里的 x86 wheel用 Git LFS 存的。如果只git clone没装 LFS,后面你会发现.whl只有一百多字节——那是指针文件,不是真正的包。

3.1 安装Git LFS

Ubuntu / Debian:

sudoaptupdatesudoaptinstall-ygitgit-lfsgitlfsinstall

3.2 克隆仓库

gitclone https://github.com/Amlogic-NN/amlnn-toolkit.gitcdamlnn-toolkitgitlfs pull

3.3 坑一:clone GitHub较慢

直连经常卡在几十 KB/s,甚至超时。可以换镜像试试:

gitclone https://ghproxy.net/https://github.com/Amlogic-NN/amlnn-toolkit.gitcdamlnn-toolkitgitlfs pull

注意:镜像站点会变,失效了就换别的代理 / 也可以本机下好再上传服务器或虚拟机。

3.4 检查wheel是否真正下下来了

ls-lhamlnn_toolkit/whl/linux_x86/

正常情况类似:

amlnn_toolkit-1.0.0-cp310-cp310-linux_x86_64.whl 约 100MB+ amlnn_toolkit-1.0.0-cp311-...whl amlnn_toolkit-1.0.0-cp312-...whl requirements_x86_64.txt

如果.whl只有134B左右,百分之九十九是 LFS 没拉成功,回去再执行:

gitlfsinstallgitlfs pull

4. 安装Python依赖

conda activate amlnn_toolkit_py310cdamlnn-toolkit

官方 README写得是:

pipinstall-ramlnn_toolkit/whl/linux_x86/requirements_x86_64.txt pipinstallamlnn_toolkit/whl/linux_x86/amlnn_toolkit-1.0.0-cp310-cp310-linux_x86_64.whl

实际在安装上,大家不一定能一把梭成功。

4.1 添加镜像源

网速慢的话,添加阿里云镜像源能加速下载速度,安装会需要一段时间。
网好的可直接装。

pipinstall-ramlnn_toolkit/whl/linux_x86/requirements_x86_64.txt-ihttp://mirrors.aliyun.com/pypi/simple pipinstallamlnn_toolkit/whl/linux_x86/amlnn_toolkit-1.0.0-cp310-cp310-linux_x86_64.whl-ihttp://mirrors.aliyun.com/pypi/simple

4.2 坑二:装完ai-edge-torch后,import amlnn报 TF Lite so 缺符号


原因大致是ai-edge-tensorflow和正式版tensorflow==2.20.0打架。处理办法:

python-mpipinstall--force-reinstall --no-deps'tensorflow==2.20.0'-ihttps://pypi.tuna.tsinghua.edu.cn/simple

4.3 安装 amlnn wheel

依赖齐了之后再装 wheel。依赖已经手动搞定的话,可以用--no-deps,避免又回去解析 nightly:

python-mpipinstall--no-deps amlnn_toolkit/whl/linux_x86/amlnn_toolkit-1.0.0-cp310-cp310-linux_x86_64.whl

验证:

python-c"from amlnn.api import AMLNN; print('amlnn-toolkit import OK')"

看到:amlnn-toolkit import OK

就说明这一关过了。

5. 准备 YOLOv8n:.pt.onnx

5.1 安装 Ultralytics(别把 torch 冲掉,如果已经有对应pt或者onnx模型文件可跳过此步骤)

toolkit 已经钉死torch==2.9.1。如果直接:

pipinstallultralytics

它可能顺手把 torch / CUDA 相关包装得乱七八糟。稳一点的话可以执行下面代码:

python-mpipinstall--no-deps ultralytics\-ihttps://pypi.tuna.tsinghua.edu.cn/simple python-mpipinstallmatplotlib pandas seaborn ultralytics-thop\py-cpuinfo'torchvision==0.24.1'nvidia-ml-py polars\-ihttps://pypi.tuna.tsinghua.edu.cn/simple

5.2 建工作目录

mkdir-p~/amlnn_workspace/modelsmkdir-p~/amlnn_workspace/calibration/imagescd~/amlnn_workspace/models

5.3yolov8n.pt下载

Ultralytics 默认从 GitHub Releases 拉权重,超时的话,可以改用 HF 镜像:

curl-fL-oyolov8n.pt\"https://hf-mirror.com/Ultralytics/YOLOv8/resolve/main/yolov8n.pt"ls-lhyolov8n.pt# 大约 6MB 左右

5.4 导出 ONNX(固定 640×640)

amlnn api输入格式支持ONNX、PyTorch、PyTorch pt2、TFLite,这里使用ONNX输入。
第一次转换建议先固定 shape,少给后面编译添变量:

yoloexport\model=yolov8n.pt\format=onnx\imgsz=640\batch=1\dynamic=False\simplify=True\opset=13\nms=False

Amlogic 官方 YOLOv8 脚本会切这三个内部输出(Ultralytics 版本不同名字可能变):

/model.22/Concat_2_output_0 /model.22/Concat_1_output_0 /model.22/Concat_output_0

我用 Ultralytics 8.4.x 导出后,图里仍能看到这三个节点。建议用 Netron 再确认一眼。

6. 准备量化校准图

w8a8需要图片列表。把 jpg/png 放到:

~/amlnn_workspace/calibration/images/

生成路径文件:

cd~/amlnn_workspacefind"$(pwd)/calibration/images"-typef\\(-iname'*.jpg'-o-iname'*.jpeg'-o-iname'*.png'\)\|sort>calibration/coco_subset.txtwc-lcalibration/coco_subset.txtheadcalibration/coco_subset.txt


校准集对精度的影响以后再单独测。

7. 导出 ADLA(S905X5 / 005)

官方 playground 里有现成的 YOLOv8 转换脚本。可以整个 clone:

gitclone https://github.com/Amlogic-NN/amlnn-model-playground.git# 国内慢就同样用镜像

也可以只把examples/yolov8/py/export_adla.py拷到本地,例如:

import argparse import shutil from pathlib import Path import numpy as np from amlnn.api import AMLNN # Normalization constants used for quantization config MEAN = np.array([0, 0, 0], dtype=np.float32) STD = np.array([255, 255, 255], dtype=np.float32) def snapshot_adla_files(search_dir): return {path: path.stat().st_mtime for path in search_dir.rglob("*.adla")} def find_updated_adla_files(search_dir, known_files): current_files = snapshot_adla_files(search_dir) updated_files = [ path for path, mtime in current_files.items() if path not in known_files or mtime > known_files[path] ] return sorted( updated_files, key=lambda path: path.stat().st_mtime, reverse=True, ) def main(): parser = argparse.ArgumentParser(description="Export ONNX to ADLA") parser.add_argument("--onnx", required=True, help="Path to ONNX model") parser.add_argument("--dataset-path", required=True, help="Path to quant dataset") parser.add_argument("--target-platform", required=True, help="Platform ID, e.g. 001, 002, 003") parser.add_argument("--adla", default="../model", help="Optional output .adla path") args = parser.parse_args() search_dir = Path.cwd() known_adla_files = snapshot_adla_files(search_dir) if args.adla else {} amlnn = AMLNN() # NOTE: These node names may be different depending on your model amlnn.load_onnx( model=args.onnx, outputs=[ "/model.22/Concat_2_output_0", # <-- Stride 32 (1x144x13x13 grid) "/model.22/Concat_1_output_0", # <-- Stride 16 (1x144x2x26 grid) "/model.22/Concat_output_0" # <-- Stride 8 (1x144x52x52 grid) ]) amlnn.config( normalization_mean=[MEAN.tolist()], normalization_std=[STD.tolist()], quantized_dtype="w8a8", target_platform=f"PRODUCT_PID0XA{args.target_platform.zfill(3)}", ) amlnn.compile(dataset=args.dataset_path) amlnn.export_adla() if args.adla: new_adla_files = find_updated_adla_files(search_dir, known_adla_files) if not new_adla_files: raise RuntimeError("export_adla did not create or update a .adla file") output_path = Path(args.adla) output_path.parent.mkdir(parents=True, exist_ok=True) if new_adla_files[0].resolve() != output_path.resolve(): shutil.copy2(new_adla_files[0], output_path) print(f"saved: {output_path}") if __name__ == "__main__": main()

核心就是四步:

amlnn.load_onnx(...)amlnn.config(...)amlnn.compile(...)amlnn.export_adla()

关键配置:

amlnn.config(normalization_mean=[[0.0,0.0,0.0]],normalization_std=[[255.0,255.0,255.0]],quantized_dtype="w8a8",target_platform=f"PRODUCT_PID0XA{target_platform}",)

执行:

python ~/amlnn_workspace/scripts/export_adla.py\--onnx~/amlnn_workspace/models/yolov8n.onnx\--dataset-path ~/amlnn_workspace/calibration/coco_subset.txt\--target-platform 005\--adla~/amlnn_workspace/models/yolov8n_s905x5_w8a8.adla

成功日志里应出现:

ls-lh~/amlnn_workspace/models/yolov8n_s905x5_w8a8.adla

用 adlainfo 看一眼结果

# 仓库路径: amlnn-toolkit/amlnn_toolkit/function_tool/02_adla_info_tool/ cd ~/amlnn-toolkit/amlnn_toolkit/function_tool/02_adla_info_tool chmod +x adlainfo_release ./adlainfo_release -v ~/amlnn_workspace/models/yolov8n_s905x5_w8a8.adla ./adlainfo_release -io ~/amlnn_workspace/models/yolov8n_s905x5_w8a8.adla

实测大致是:

  • Compile Version:3.4.4
  • Aml Hw Version:4.0
  • 输入:1×640×640×3,Int8
  • 输出:三路检测相关张量,Int8

参考

  1. Amlogic-NN/amlnn-toolkit
  2. Amlogic-NN/amlnn-model-playground
  3. YOLOv8 示例
  4. Ultralytics Export
  5. ONNX

本文基于公开仓库个人实测整理,仅供学习记录。工具版本和平台映射可能变化,请以当下 README / release note 为准。欢迎转载,请注明出处。

http://www.cnnetsun.cn/news/3521891.html

相关文章:

  • 如何3步永久激活IDM:开源脚本免费解锁Internet Download Manager完整功能
  • 如何快速掌握BepInEx:游戏插件框架的终极解决方案
  • UVM 中 virtual 关键字的使用详解
  • TI F2838x DCSM安全模块实战:寄存器配置与内存隔离指南
  • 深入解析TMS320F2838x I2C驱动:从寄存器到Driverlib函数映射与实战
  • 缠论量化框架chan.py:技术实现与实战应用深度解析
  • TMS320F28003x ERAD模块实战:硬件断点、事件计数器与CRC的嵌入式调试利器
  • 纯HTML单文件实现玛雅十字帕托利 —— 用52格闭环与5颗豆子还原古玛雅双人棋
  • 2026年聚四氟乙烯厂家排行榜前十名品牌有哪些?
  • nRF52芯片DFU升级方案与优化实践
  • ESP32-S3音乐播放器开发实战:WAV解码与I2S音频接口应用
  • AI时代的程序员修养:测试是 AI 编程的安全带
  • 【Claude企业级部署安全白皮书】:从API密钥隔离到上下文泄露防护,金融级合规实践首次公开
  • TMS320F2838x时钟与安全监控:从架构解析到高可靠系统设计实战
  • 如何5分钟快速上手SpringBoot操作日志组件mzt-biz-log
  • 鸿蒙ArkUI实战:生成账本数据导出预览
  • C2000 ePWM高级功能解析:谷底开关、多模块同步与HRPWM实战
  • Priceline Design System 企业级应用案例:如何在大型项目中实施设计系统
  • Intern-S2-Preview-397B-FP8代理集成:连接OpenClaw和Hermes的终极指南
  • QobuzDownloaderX-MOD用户指南:自定义音乐下载路径与音质设置全攻略
  • 【2024最严苛AI模型功能评测】:从零代码微调到合规审计,仅2款模型通过全部19项企业级交付验收标准
  • 关于图论【力扣797.所有可能的路径的思考】
  • DingFlow:基于React的高效审批流程构建工具终极指南
  • 邮件系统错误处理与智能诊断方案Mail-Error详解
  • 如何快速安装Lyric-Getter:Xposed模块歌词获取完整教程
  • pgagroal源码解析:深入理解PostgreSQL高性能连接池的核心实现原理
  • 《持续交付2.0系列四》组织文化---从恐惧到信任
  • BiliScope终极指南:解锁B站深度浏览体验的免费神器
  • AI+医疗:从疾病诊断到新药研发,哪些领域已落地?
  • 3步掌握猫抓扩展:让网页视频下载变得像截图一样简单