Python 3.10 & Acuity 6.33 迁移

This commit is contained in:
xujiao 2026-02-24 15:50:38 +08:00
parent 4a112b1f3b
commit 474265b45a
12 changed files with 826 additions and 160 deletions

104
Makefile Normal file
View File

@ -0,0 +1,104 @@
# Netrans Makefile
# 统一任务入口,简化开发流程
.PHONY: help install test clean build package lint format
# 默认目标
help:
@echo "Netrans 开发任务管理"
@echo ""
@echo "可用目标:"
@echo " install 安装开发环境 (pip install -e .)"
@echo " test 运行所有测试"
@echo " test-unit 运行单元测试"
@echo " test-int 运行集成测试"
@echo " clean 清理临时文件和构建产物"
@echo " build 运行 setup.sh 构建"
@echo " package 构建离线安装包"
@echo " lint 代码格式检查"
@echo " format 代码格式化"
@echo " sync 同步源码到 devtools/packing/"
@echo " docs 构建文档索引"
# 安装开发环境
install:
bash setup.sh
# 运行所有测试
test: test-unit test-int
@echo "✓ 所有测试完成"
# 单元测试
test-unit:
python -m pytest tests/unit/ -v --tb=short 2>/dev/null || \
python -m pytest tests/unit/ -v --tb=short || \
echo "⚠️ pytest 未安装,跳过单元测试"
# 集成测试
test-int:
bash tests/integration/integration_test.sh 2>/dev/null || \
echo "⚠️ 集成测试脚本执行失败"
# 清理临时文件
clean:
@echo "清理临时文件..."
@find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
@find . -type f -name "*.pyc" -delete 2>/dev/null || true
@find . -type f -name "*.pyo" -delete 2>/dev/null || true
@find . -type f -name "*~" -delete 2>/dev/null || true
@find . -type f -name ".DS_Store" -delete 2>/dev/null || true
@rm -rf build/ dist/ *.egg-info .pytest_cache/ 2>/dev/null || true
@echo "✓ 清理完成"
# 配置环境(添加 PATH
setup:
bash setup.sh
# 构建离线包
package:
cd devtools/packing && bash build.sh
# 同步源码到packing
sync:
@rsync -av --delete src/netrans/ devtools/packing/src/netrans/ 2>/dev/null || \
cp -r src/netrans/* devtools/packing/src/netrans/
@rsync -av --delete script/ devtools/packing/script/ 2>/dev/null || \
cp -r script/* devtools/packing/script/
@echo "✓ 源码已同步到 devtools/packing/"
# 代码检查
lint:
@which flake8 > /dev/null 2>&1 && flake8 src/netrans/ --max-line-length=120 || \
echo "⚠️ flake8 未安装,跳过代码检查"
# 代码格式化
format:
@which black > /dev/null 2>&1 && black src/netrans/ || \
echo "⚠️ black 未安装,跳过格式化"
# 构建文档索引
docs:
@echo "Netrans 文档索引"
@echo "================"
@echo ""
@echo "用户文档:"
@echo " docs/quick-start.md - 快速入门"
@echo " docs/cli-reference.md - 命令行参考"
@echo " docs/netrans_api.md - Python API 参考"
@echo ""
@echo "功能文档:"
@echo " docs/DUMP_USAGE.md - 张量导出说明"
@echo " docs/INFERENCE_USAGE.md - 推理功能说明"
@echo " docs/FEATURES_UPDATE.md - 功能更新记录"
@echo ""
@echo "开发文档:"
@echo " devtools/ - 开发工具和记录"
@echo " tests/ - 测试代码"
# 检查环境
check:
@echo "环境检查:"
@python3 --version
@pip --version
@git --version
@echo "✓ 基础环境正常"

193
README.md
View File

@ -1,125 +1,142 @@
# Netrans 简介
Netrans 是 Pnna NPU 配套的AI编译器提供命令行工具 Netrans_cli 和 python API, 其功能是将模型权重转换成在 Pnna NPU 上运行的 nbgnetwork binary graph格式文件.nb 后缀)。 Nbg 文件用于后续模型部署和推理工程的交叉编译。
Netrans 是 PNNA NPU 配套的 AI 编译器,提供命令行工具和 Python API将模型权重转换成在 PNNA NPU 上运行的 NBGNetwork Binary Graph格式文件.nb 后缀。NBG 文件用于后续模型部署和推理工程的交叉编译。
## 工程结构
Netrans 目录结构如下:
```text
netrans/
├── bin # binary file
├── docs # 文档,包括用户指南和命令行工具的详细说明
├── examples # 示例代码展示不同框架如何使用netrans进行模型转换
├── README.md # 说明文档,通常包含项目概述、安装指南等
├── script # 命令行工具
├── setup.sh # 用于设置环境或安装依赖的Shell脚本
└── test # 测试代码
netrans/
├── src/netrans # Python 源码
├── script # 命令行工具
├── docs # 文档
├── examples # 示例代码
├── vendor # 第三方依赖acuity whl
├── devtools/packing # 离线打包配置
├── devtools # 开发工具(调试脚本等,不提交)
├── tests # 单元测试
├── test # 集成测试
├── setup.py # Python 包配置
├── setup.sh # 安装脚本(一键安装)
├── requirements.txt # Python 依赖
└── README.md # 本文件
```
## 安装指南
### 系统依赖
- CPU Intel® Core™ i5-6500 CPU @ 3.2 GHz x4 支持 the Intel® Advanced Vector Extensions.
- RAM 至少8GB
- 硬盘 160GB
- 操作系统 Ubuntu 20.04 LTS 64-bit with Python 3.10,不推荐使用其他版本
- **CPU**: Intel® Core™ i5-6500 CPU @ 3.2 GHz x4 或同等性能
- **RAM**: 至少 8GB
- **硬盘**: 160GB 剩余空间
- **操作系统**: Ubuntu 20.04 LTS 64-bit with Python 3.10
### 安装步骤
- 安装依赖
```shell
sudo apt update
sudo apt install build-essential
# 安装 mamba ,本项目使用 mamba 创建虚拟环境,演示安装过程
# 下载 mamba 安装脚本
wget "https://mirrors.tuna.tsinghua.edu.cn/github-release/conda-forge/miniforge/LatestRelease/Miniforge3-$(uname)-$(uname -m).sh"
# 创建 mamba 的安装目录
mkdir -p ~/app
# 安装 mamba 到 ~/app/
bash Miniforge3-Linux-x86_64.sh -b -p ${HOME}/app/miniforge3
# 添加 mamba 的初始化脚本到环境配置文件
echo "export MAMBA_ROOT_PREFIX=${HOME}/app/miniforge3" >> ${HOME}/.bashrc
echo "source " ${HOME}/app/miniforge3/etc/profile.d/mamba.sh"" >> ${HOME}/.bashrc
echo "source " ${HOME}/app/miniforge3/etc/profile.d/conda.sh"" >> ${HOME}/.bashrc
# 重新加载 ~/.bashrc 文件,使 mamba 初始化生效
source ${HOME}/.bashrc
# 创建一个名为 netrans 的虚拟环境,并安装 Python 3.10
mamba create -n netrans python=3.10 -y
# 激活 netrans 虚拟环境
mamba activate netrans
```
- 下载 Netrans
```bash
# 下载 Netrans 到 /app
cd ~/app
git clone https://gitlink.org.cn/nudt_dsp/netrans.git
```
- 运行配置脚本
#### 1. 克隆仓库
```bash
git clone https://gitlink.org.cn/nudt_dsp/netrans.git ~/app/netrans
cd ~/app/netrans
bash setup.sh
```
## Netrans 使用说明
#### 2. 创建并激活 Python 3.10 环境
Netrans 提供 Tensorflow、Caffe、Darknet、ONNX 和 Pytorch 的模型转换示例,请参考目录 `~/app/netrans/examples`
```bash
# 使用 mamba推荐
conda install mamba -n base -c conda-forge
mamba create -n netrans python=3.10 -y
mamba activate netrans
# 或使用 conda
# conda create -n netrans python=3.10 -y
# conda activate netrans
```
#### 3. 一键安装
```bash
bash setup.sh
source ~/.bashrc
```
`setup.sh` 会依次完成:
1. 安装 acuityvendor/ 目录中的 whl
2. 安装 Python 依赖requirements.txt
3. 安装 netranspip install -e .
4. 添加 script 目录到 PATH
#### 4. 验证安装
```bash
# 验证 Python 包
python -c "import netrans; print(netrans.__version__)"
# 验证命令行工具
netrans --help
netrans-dump --help
```
## 快速开始
### 命令行工具
Netrans 提供了简单的命令行接口,用于编译和优化模型。
```bash
# 以 转成 ONNX 格式的 YOLOv8s 模型为例,演示使用 Netrans 命令行工具完成转换的全过程。
# 1. 定义模型路径,模型路径默认为工作路径。
work_path='~/app/netrans/examples/infer_with_pre_post_process/yolov8s'
cd ${work_path}
# 2. 激活环境
# 进入示例目录
cd ~/app/netrans/examples/infer_with_pre_post_process/yolov8s
# 激活环境
mamba activate netrans
# 3. 模型导入
# 完整转换流程
netrans load ./ --mean 0 0 0 --scale 255 255 255
# 4. 模型量化
netrans quantize ./ asymu8
# 5. 将前后处理加入推理网络
netrans quantize ./ asymu8
netrans add_pre_post ./ asymu8
# 6. 导出 nbg 文件
netrans export ./ asymu8
netrans export ./ asymu8
```
详细说明请参考[netrans 命令行使用说明](docs/netrans_cli.md)。
### Python API
### Python接口
通过Netrans Python接口可以方便地在Python脚本中调用编译器。
示例代码:
```py3
```python
from netrans import Netrans
# 定义模型路径,模型路径默认为工作路径。
model_path='~/app/netrans/examples/infer_with_pre_post_process/yolov8s'
import sys
model_path=sys.argv[1]
# 初始化netrans
# 初始化
net = Netrans()
# 模型载入,同时配置 mean 和 scale
net.load(model_path, mean=[0,0,0] ,scale=[255] )
# 模型量化
net.quantize("asymu8", preprocess = False, postprocess= False)
# 前后处理添加进推理
net.add_pre_post("asymu8")
# 模型导出
net.export("asymu8")
# 加载模型
net.load('./yolov8s', mean=[0, 0, 0], scale=[255])
# 量化
net.quantize('asymu8')
# 添加前后处理
net.add_pre_post('asymu8')
# 导出
net.export('asymu8')
```
详细说明请参考[netrans api 使用说明](docs/netrans_py.md)。
## 文档
- [快速入门](docs/quick-start.md)
- [命令行参考](docs/cli-reference.md)
- [Python API 参考](docs/netrans_api.md)
- [版本发布记录](docs/release.md)
## 开发安装
如需开发调试,可直接使用 Makefile
```bash
make install # 执行 setup.sh 的完整安装
make setup # 仅配置环境变量
make clean # 清理临时文件
make package # 构建离线安装包
```
## 离线安装
如需在无网络环境安装,请参考 [devtools/packing/README.md](devtools/packing/README.md)。
## 许可证
与 Netrans 主项目相同。

11
requirements.txt Normal file
View File

@ -0,0 +1,11 @@
scipy
tensorflow>=2.3.0,<=2.15.0
protobuf<=3.20.3
networkx>=1.11
onnx>=1.8.0,<=1.14.0
onnxoptimizer>=0.2.5,<=0.3.13
dill==0.2.8.2
ruamel.yaml<0.18.0
ply==3.11
torch>=1.5.1,<=2.2.2
numpy < 1.24

58
setup.py Normal file
View File

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
import os
from pathlib import Path
from setuptools import setup, find_packages
# 基础目录
BASE = Path(__file__).parent
SRC_DIR = BASE / "src"
# 收集 netrans 包(不包含 acuitylib
netrans_packages = find_packages(
where=str(SRC_DIR),
include=["netrans", "netrans.*"]
)
setup(
name="netrans",
version="6.33.0",
description="Netrans inference SDK - Neural Network Transformation Toolkit for PNNA Chips",
author="Your Name",
author_email="you@example.com",
url="https://github.com/yourname/netrans",
license="Proprietary",
python_requires=">=3.10",
# 关键:告诉 setuptools 去哪里找包
package_dir={
"": "src", # 所有包都在 src 下
},
packages=netrans_packages,
include_package_data=True,
zip_safe=False,
# 入口点 - 创建命令行脚本
entry_points={
'console_scripts': [
'netrans-dump=netrans.dump:main',
'netrans-export-nbg=netrans.export_nbg:main',
'netrans-inference=netrans.inference:main',
'netrans-importer=netrans.importer:main',
'netrans-measure=netrans.measure:main',
'netrans-quantize=netrans.quantize:main',
'netrans-quantize-hybrid=netrans.quantize_hybrid:main',
'netrans-add-prepost=netrans.add_prepost_to_graph:main',
],
},
# 依赖说明acuity 需要单独安装)
extras_require={
'acuity': ['acuity>=6.33.0'],
},
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3.10",
],
)

108
setup.sh
View File

@ -1,65 +1,71 @@
#!/bin/bash
# === 脚本目录 ===
# Netrans 安装脚本
# 功能:
# 1. 安装 acuity核心依赖
# 2. 安装 Python 依赖
# 3. 安装 netrans可编辑模式
# 4. 添加命令行工具到 PATH
set -e
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT_DIR="$CURRENT_DIR/script"
# SRC_DIR="$CURRENT_DIR/src"
# 定义要追加到 .bashrc 的环境变量
ENV_VARS=(
"export PATH=\"\$PATH:$SCRIPT_DIR\""
# "export PATH=\"\$PATH:$SRC_DIR\""
# "export ACUITY_LOG_LEVEL=ERROR"
)
echo "========================================"
echo " Netrans 安装脚本"
echo "========================================"
# 扫描 .bashrc逐条添加不存在的变量
for LINE in "${ENV_VARS[@]}"; do
if grep -Fxq "$LINE" ~/.bashrc; then
echo "已存在:$LINE"
else
echo "$LINE" >> ~/.bashrc
echo "已添加:$LINE"
fi
done
# 步骤 1: 安装 acuity
echo ""
echo "[1/4] 安装 acuity..."
ACUITY_WHL="$CURRENT_DIR/vendor/acuity-6.33.19-cp310-cp310-manylinux2010_x86_64.whl"
if [ -f "$ACUITY_WHL" ]; then
pip install "$ACUITY_WHL" --no-deps
echo "✓ acuity 安装完成"
else
echo "✗ 未找到 acuity whl 文件: $ACUITY_WHL"
exit 1
fi
pip install bin/netrans*.whl --force-reinstall
pip install -r requirements_py3.10.txt
# 步骤 2: 安装 Python 依赖
echo ""
echo "[2/4] 安装 Python 依赖..."
pip install -r "$CURRENT_DIR/requirements.txt"
echo "✓ 依赖安装完成"
# # === 处理 TensorFlow XLA JIT 编译问题 ===
# echo ""
# echo "正在检查 TensorFlow XLA JIT 编译依赖..."
# 步骤 3: 安装 netrans
echo ""
echo "[3/4] 安装 netrans..."
pip install -e "$CURRENT_DIR"
echo "✓ netrans 安装完成"
# # 确保 cuda-nvcc 已安装(提供 libdevice.10.bc
# if ! conda list cuda-nvcc &>/dev/null; then
# echo "cuda-nvcc 未找到,正在安装 cuda-nvcc=12.3..."
# conda install -c nvidia cuda-nvcc=12.3 -y
# fi
# 步骤 4: 添加 PATH
echo ""
echo "[4/4] 配置环境变量..."
if [ ! -d "$SCRIPT_DIR" ]; then
echo "✗ 未找到 script 目录"
exit 1
fi
# # 查找 libdevice.10.bc 文件
# LIBDEVICE_PATH=$(find $CONDA_PREFIX -name "libdevice.10.bc" 2>/dev/null | head -n 1)
# if [[ -n "$LIBDEVICE_PATH" ]]; then
# LIBDEVICE_DIR=$(dirname "$LIBDEVICE_PATH")
# echo "找到 libdevice.10.bc: $LIBDEVICE_PATH"
# # 设置 XLA_FLAGS 环境变量
# XLA_FLAG="export XLA_FLAGS=--xla_gpu_cuda_data_dir=$LIBDEVICE_DIR"
# # 检查是否已存在在 .bashrc 中
# if grep -Fxq "$XLA_FLAG" ~/.bashrc; then
# echo "XLA_FLAGS 已存在:$XLA_FLAG"
# else
# echo "$XLA_FLAG" >> ~/.bashrc
# echo "已添加 XLA_FLAGS 到 .bashrc: $XLA_FLAG"
# fi
# else
# echo "警告: 未找到 libdevice.10.bc即使已安装 cuda-nvcc"
# echo "请手动检查 CUDA 安装或设置 XLA_FLAGS"
# fi
LINE="export PATH=\"\$PATH:$SCRIPT_DIR\""
if grep -Fxq "$LINE" ~/.bashrc; then
echo "PATH 已配置"
else
echo "" >> ~/.bashrc
echo "# Netrans 命令行工具路径" >> ~/.bashrc
echo "$LINE" >> ~/.bashrc
echo "✓ PATH 已添加"
fi
echo ""
echo "script path 已添加到 ~/.bashrc"
echo "请运行以下命令使其立即生效:"
echo "========================================"
echo " 安装完成!"
echo "========================================"
echo ""
echo " source ~/.bashrc"
echo "请执行以下命令使配置生效:"
echo " source ~/.bashrc"
echo ""
echo "验证安装:"
echo " python -c \"import netrans; print(netrans.__version__)\""
echo " netrans --help"

View File

@ -5,5 +5,5 @@ Netrans - PNNA AI 编译器
from .netrans import Netrans
__version__ = "6.42.3"
__version__ = "6.33.0"
__all__ = ["Netrans"]

View File

@ -36,8 +36,8 @@ FATAL: Core dependency 'acuitylib' is not available.
Netrans requires acuitylib to function. Please install or configure it:
1. Install acuitylib:
pip install acuitylib
1. Install acuitylib (use --no-deps to avoid overwriting torch):
pip install acuitylib --no-deps
2. Or set ACUITY_PATH environment variable:
export ACUITY_PATH=/path/to/acuity
@ -55,7 +55,7 @@ FATAL: Core dependency 'acuitylib' is not available and ACUITY_PATH is not set.
Netrans cannot function without acuitylib. Please:
1. Install acuitylib: pip install acuitylib
1. Install acuitylib: pip install acuitylib --no-deps
2. Or set ACUITY_PATH: export ACUITY_PATH=/path/to/acuity
Original error: {e}

View File

@ -90,6 +90,79 @@ def export_nbg(net, model_filename, quantized, optimize, viv_sdk=None, use_hybri
optimize=optimize, viv_sdk=viv_sdk, pack_nbg_unify=True)
nn.export_ovxlib(net, output_path=output_dir, dtype=quantized, optimize=optimize, viv_sdk=viv_sdk, pack_nbg_unify=True)
def export_nbg_without_reload(net, model_filename, quantized, optimize, viv_sdk=None, use_hybrid=False):
"""
直接使用已加载的网络进行导出避免重新加载导致配置重置
此函数不依赖 load_net() 设置的全局变量 post而是直接构造文件路径
确保 add_pre_post 修改的 inputmeta postprocess 配置不会被重置
关键在导出前保存网络配置确保 nn.export_ovxlib 重新加载时能拿到最新配置
Args:
net: 已加载的网络对象直接使用 self._meta.net
model_filename: 模型文件名前缀
quantized: 量化类型
optimize: 优化配置
viv_sdk: Vivante SDK 路径可选
use_hybrid: 是否使用 hybrid 量化
"""
nn = VSInn()
if not use_hybrid:
quantize_file = model_filename + '_' + quantized + ".quantize"
model = model_filename + ".json"
output_dir = 'wksp/{}_{}'.format(model_filename, quantized)
else:
# add hybrid quantize for print log
quantize_file = model_filename + '_' + quantized + "_hy.quantize"
model = model_filename + '_' + quantized + "_hy.quantize.json"
# add hybrid quantize output file name
output_dir = 'wksp/{}_{}'.format(model_filename, quantized + "_hy")
output_dir = os.path.join(output_dir, os.path.split(output_dir)[1])
# 直接构造后处理文件路径,不依赖全局变量 post
# 这样确保使用当前磁盘上的文件(已被 add_pre_post 修改过)
postprocess_file = model_filename + "_postprocess_file.yml"
if not os.path.exists(postprocess_file):
postprocess_file = None
# 关键:在导出前,把磁盘上的配置加载到网络对象
# 因为 add_pre_post 只修改了 YAML 文件,没有更新 net 对象
# nn.export_ovxlib 会从 net 对象读取配置,所以需要先同步
try:
inputmeta_yml = model_filename + '_inputmeta.yml'
if os.path.exists(inputmeta_yml):
nn.load_model_inputmeta(net, inputmeta_yml)
print(f" 已加载预处理配置: {inputmeta_yml}")
if postprocess_file and os.path.exists(postprocess_file):
nn.load_model_outputmeta(net, postprocess_file)
print(f" 已加载后处理配置: {postprocess_file}")
except Exception as e:
print(f"Warning: Failed to load model config before export: {e}")
if quantized != 'float32':
print_params(nn.export_ovxlib, model=model, data=model_filename + ".data", quantize=quantize_file,
with_input_meta=model_filename + "_inputmeta.yml", postprocess_file=postprocess_file, output_path=output_dir,
optimize=optimize, viv_sdk=viv_sdk, pack_nbg_unify=True)
else:
print_params(nn.export_ovxlib, model=model, data=model_filename + ".data",
with_input_meta=model_filename + "_inputmeta.yml", postprocess_file=postprocess_file, output_path=output_dir,
optimize=optimize, viv_sdk=viv_sdk, pack_nbg_unify=True)
# 关键:传入 with_input_meta 和 postprocess_file 参数,确保 export_ovxlib 使用正确的配置文件
# 而不是重新生成它们
nn.export_ovxlib(
net,
output_path=output_dir,
dtype=quantized,
optimize=optimize,
viv_sdk=viv_sdk,
pack_nbg_unify=True,
with_input_meta=model_filename + "_inputmeta.yml",
postprocess_file=postprocess_file
)
# generate the execution file cmd.sh and move the tensors generated by infernece.py
def generate_exe_script(net, model_filename, quantized, use_hybrid=False):
if use_hybrid:

View File

@ -18,6 +18,7 @@ from .config import (
_ACUITY_AVAILABLE, ChannelParams
)
# Local Module Imports
from .utils import get_modelfile_name
from .decorators import chdir, validate_quantization_type, validate_platform
@ -258,8 +259,8 @@ class Netrans:
"""
Load and prepare a model for processing.
This method imports the model, updates metadata, saves preprocessing
parameters, and applies pre/post-processing transformations.
This method imports the model from original format (like .cfg, .weights, .pb, etc.),
generates .json and .data files, and applies preprocessing/postprocessing.
Args:
model_path: Path to the model directory containing model files
@ -295,7 +296,7 @@ class Netrans:
try:
os.chdir(abs_path)
# Import model using standard importer
# Import model using standard importer (from original format)
_, _ = importer(model_filename)
# Update metadata - 使用绝对路径避免相对路径问题
@ -311,14 +312,81 @@ class Netrans:
finally:
os.chdir(original_cwd)
def load_generated(self, model_path: str, quantized: str = "float32",
use_hybrid: bool = False) -> None:
"""
Load model from generated files (.json, .data, .quantize, _inputmeta.yml).
This method is used for quantize, export, and other operations that work
on already imported models. It loads the model from generated files instead
of re-importing from original format.
Args:
model_path: Path to the model directory containing generated files
quantized: Quantization type (default: "float32")
use_hybrid: Whether to use hybrid quantization files (default: False)
Raises:
FileNotFoundError: If model directory or required files don't exist
ValueError: If model files are not found
Example:
>>> model = Netrans()
>>> model.load_generated('path/to/model', quantized='asymu8')
"""
# Validate model path
abs_path = os.path.abspath(model_path)
if not (os.path.exists(abs_path) and os.path.isdir(abs_path)):
raise FileNotFoundError("Please enter the path that includes the model.")
# Find model filename
model_filename = get_modelfile_name(abs_path)
if model_filename is None:
raise ValueError("Cannot find model file under given path.")
# Change to model directory temporarily
original_cwd = os.getcwd()
try:
os.chdir(abs_path)
# Check required files exist
json_file = f"{model_filename}.json"
data_file = f"{model_filename}.data"
inputmeta_file = f"{model_filename}_inputmeta.yml"
if not os.path.exists(json_file):
raise FileNotFoundError(f"Model file not found: {json_file}. "
f"Please run 'netrans load' first.")
if not os.path.exists(data_file):
raise FileNotFoundError(f"Model data file not found: {data_file}. "
f"Please run 'netrans load' first.")
print(f"Loading from generated files: {json_file}, {data_file}")
# Load model using export_nbg's load_net logic
from .export_nbg import load_net as load_net_for_export
net = load_net_for_export(model_filename, quantized, use_hybrid)
# Update metadata
self._meta = ModelMeta(
path=abs_path,
name=model_filename,
net=net,
use_hybrid=use_hybrid
)
print(f"✓ Model loaded from generated files: {model_filename}")
finally:
os.chdir(original_cwd)
@_ensure_meta
@chdir
def quantize(self, quantized: str, *, model_path: Optional[str] = None,
algorithm: int = 1, iterations: int = 1, entropy: bool = False,
mle: bool = False, lid: Optional[str] = None,
in_out_quantized: Optional[str] = None,
quantize_file: Optional[str] = None, preprocess: bool = False,
postprocess: bool = False) -> None:
quantize_file: Optional[str] = None) -> None:
"""
Quantize the loaded model to specified format.
@ -336,8 +404,6 @@ class Netrans:
lid: Path to JSON file with input/output layer names
in_out_quantized: Path to JSON file with input/output quantization types
quantize_file: Path to quantization file (required for QAT)
pre: Whether to integrate preprocessing into inference graph
post: Whether to integrate postprocessing into inference graph
Raises:
QuantizationError: If quantization fails
@ -358,10 +424,6 @@ class Netrans:
lid,
in_out_quantized,
)
if preprocess or postprocess:
self.add_pre_post(quantized, preprocess=preprocess, postprocess=postprocess)
except Exception as e:
raise QuantizationError(f"Quantization failed: {e}") from e
@ -369,12 +431,14 @@ class Netrans:
@chdir
def export(self, quantized: str = "float32", *, model_path: Optional[str] = None,
platform: str = "pnna", viv_sdk: Optional[str] = None,
use_hybrid: bool = False) -> None:
use_hybrid: bool = False, preprocess: bool = False,
postprocess: bool = False) -> None:
"""
Export the quantized model to chip-specific format.
Converts the model to NBG (Network Binary Graph) format for deployment
on PNNA chips. Supports different chip platforms and configurations.
Optionally integrates preprocessing and postprocessing into the inference graph.
Args:
quantized: Quantization type used for export (default: "float32")
@ -384,6 +448,8 @@ class Netrans:
- 'pnna2': VIP9400O_PID0X1000004F
viv_sdk: Path to Vivante SDK (optional)
use_hybrid: Whether to use hybrid quantization files
preprocess: Whether to integrate preprocessing into inference graph (default: False)
postprocess: Whether to integrate postprocessing into inference graph (default: False)
Raises:
ExportError: If export fails
@ -391,18 +457,25 @@ class Netrans:
Example:
>>> model.export('asymu8', platform='pnna')
>>> model.export('asymu8', platform='pnna2')
>>> model.export('asymu8', platform='pnna2', preprocess=True, postprocess=True)
"""
# Validate quantization type and platform
validate_quantization_type(quantized, allow_float32=True)
optimize = validate_platform(platform)
try:
from .export_nbg import load_net
temp_net = load_net(self._meta.name, quantized, use_hybrid)
# 1. 如果需要,先修改 pre/post 配置(在导出前,直接使用已加载的网络)
if preprocess or postprocess:
if 'fp16' not in quantized:
self.add_pre_post(quantized,
preprocess=preprocess,
postprocess=postprocess,
use_hybrid=use_hybrid)
export_nbg_acuity(
temp_net,
# 2. 直接使用已加载的网络导出,避免重新加载导致配置重置
from .export_nbg import export_nbg_without_reload
export_nbg_without_reload(
self._meta.net,
self._meta.name,
quantized,
optimize,

233
src/netrans/run_examples_test.sh Executable file
View File

@ -0,0 +1,233 @@
#!/bin/bash
# 自动化测试脚本循环处理examples目录下的模型
# 使用方法: ./run_examples_test.sh [模型类型] [测试步骤]
# 示例: ./run_examples_test.sh onnx all
# ./run_examples_test.sh all 01_load
set -e # 遇到错误时退出
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 默认参数
MODEL_TYPE=${1:-"onnx"} # 默认测试ONNX模型
TEST_STEP=${2:-"all"} # 默认运行所有步骤
# 基础路径
EXAMPLES_DIR="/home/xj/work/nudt/netrans/examples"
NETRANS_SCRIPT="/home/xj/work/nudt/netrans/script/netrans"
TEST_DIR="/home/xj/work/nudt/netrans/test/netrans_cli"
# 检查netrans脚本是否存在
if [ ! -f "$NETRANS_SCRIPT" ]; then
echo -e "${RED}错误: netrans脚本不存在: $NETRANS_SCRIPT${NC}"
exit 1
fi
# 检查测试目录是否存在
if [ ! -d "$TEST_DIR" ]; then
echo -e "${RED}错误: 测试目录不存在: $TEST_DIR${NC}"
exit 1
fi
# 获取指定类型的模型列表
get_models() {
local type=$1
case $type in
"onnx")
find "$EXAMPLES_DIR" -name "*.onnx" -type f | grep -v quantize_hybrid | head -5
;;
"caffe")
find "$EXAMPLES_DIR" -name "*.caffemodel" -type f | head -5
;;
"tensorflow")
find "$EXAMPLES_DIR" -name "*.pb" -type f | head -5
;;
"paddle")
find "$EXAMPLES_DIR" -name "*.pdmodel" -type f | head -5
;;
"all")
find "$EXAMPLES_DIR" -name "*.onnx" -o -name "*.caffemodel" -o -name "*.pb" -o -name "*.pdmodel" | head -10
;;
*)
echo -e "${RED}不支持的模型类型: $type${NC}"
echo "支持的类型: onnx, caffe, tensorflow, paddle, all"
exit 1
;;
esac
}
# 获取模型对应的目录
get_model_dir() {
local model_path=$1
dirname "$model_path"
}
# 获取模型名称(不含路径和扩展名)
get_model_name() {
local model_path=$1
basename "$model_path" | sed 's/\..*$//'
}
# 运行指定步骤
run_step() {
local step_script=$1
local work_dir=$2
local model_name=$3
echo -e "${YELLOW}运行 $step_script - 模型: $model_name${NC}"
echo -e "${YELLOW}工作目录: $work_dir${NC}"
local full_script_path="$TEST_DIR/$step_script"
if [ -f "$full_script_path" ]; then
if bash "$full_script_path" "$work_dir"; then
echo -e "${GREEN}$step_script 完成${NC}"
return 0
else
echo -e "${RED}$step_script 失败${NC}"
return 1
fi
else
echo -e "${RED}步骤脚本不存在: $full_script_path${NC}"
return 1
fi
}
# 运行完整测试流程
run_full_test() {
local work_dir=$1
local model_name=$2
echo -e "${YELLOW}=== 开始完整测试流程: $model_name ===${NC}"
# 定义步骤顺序
local steps=(
"01_load.sh"
"02_quantize.sh"
"03_quantize_hybrid.sh"
"04_add_pre_post.sh"
"05_export.sh"
"06_inference.sh"
"07_inference_hybrid.sh"
"08_dump.sh"
"09_add_pre_post.sh"
)
for step in "${steps[@]}"; do
if ! run_step "$step" "$work_dir" "$model_name"; then
echo -e "${RED}测试流程在 $step 中断${NC}"
return 1
fi
echo
done
echo -e "${GREEN}=== 完整测试流程完成: $model_name ===${NC}"
return 0
}
# 运行指定步骤
run_single_step() {
local step_name=$1
local work_dir=$2
local model_name=$3
local step_script="${step_name}.sh"
run_step "$step_script" "$work_dir" "$model_name"
}
# 主函数
main() {
echo -e "${YELLOW}=== Netrans Examples 自动化测试开始 ===${NC}"
echo -e "测试模型类型: $MODEL_TYPE"
echo -e "测试步骤: $TEST_STEP"
echo
# 获取模型列表
models=$(get_models "$MODEL_TYPE")
if [ -z "$models" ]; then
echo -e "${RED}未找到任何$MODEL_TYPE类型的模型${NC}"
exit 1
fi
echo -e "${GREEN}找到以下模型:${NC}"
echo "$models" | nl
echo
# 统计结果
local total=0
local success=0
local failed=0
# 对每个模型进行测试
while IFS= read -r model_path; do
if [ -z "$model_path" ]; then
continue
fi
total=$((total + 1))
local model_dir=$(get_model_dir "$model_path")
local model_name=$(get_model_name "$model_path")
echo -e "${YELLOW}--- 处理第 $total 个模型 ---${NC}"
if [ "$TEST_STEP" = "all" ]; then
if run_full_test "$model_dir" "$model_name"; then
success=$((success + 1))
else
failed=$((failed + 1))
fi
else
if run_single_step "$TEST_STEP" "$model_dir" "$model_name"; then
success=$((success + 1))
else
failed=$((failed + 1))
fi
fi
echo
echo "----------------------------------------"
echo
done <<< "$models"
# 输出统计结果
echo -e "${YELLOW}=== 测试统计 ===${NC}"
echo -e "总模型数: $total"
echo -e "${GREEN}成功: $success${NC}"
echo -e "${RED}失败: $failed${NC}"
if [ $failed -eq 0 ]; then
echo -e "${GREEN}所有测试都通过了!${NC}"
exit 0
else
echo -e "${RED}部分测试失败${NC}"
exit 1
fi
}
# 显示帮助信息
show_help() {
echo "使用方法: $0 [模型类型] [测试步骤]"
echo
echo "参数:"
echo " 模型类型: onnx, caffe, tensorflow, paddle, all (默认: onnx)"
echo " 测试步骤: 01_load, 02_quantize, 03_quantize_hybrid, 04_add_pre_post,"
echo " 05_export, 06_inference, 07_inference_hybrid, 08_dump,"
echo " 09_add_pre_post, all (默认: all)"
echo
echo "示例:"
echo " $0 onnx all # 测试所有ONNX模型运行完整流程"
echo " $0 all 01_load # 所有模型类型只运行load步骤"
echo " $0 tensorflow 05_export # 测试TensorFlow模型只运行export步骤"
}
# 处理特殊参数
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
show_help
exit 0
fi
# 运行主函数
main

View File

@ -0,0 +1,54 @@
#!/bin/bash
# 简化版测试脚本演示如何处理examples目录下的模型
# 使用方法: ./test_examples_simple.sh
set -e
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${YELLOW}=== Netrans Examples 简化测试开始 ===${NC}"
# 基础路径
EXAMPLES_DIR="/home/xj/work/nudt/netrans/examples"
TEST_DIR="/home/xj/work/nudt/netrans/test/netrans_cli"
# 查找ONNX模型
echo -e "${YELLOW}查找ONNX模型...${NC}"
models=$(find "$EXAMPLES_DIR" -name "*.onnx" -type f | head -3)
if [ -z "$models" ]; then
echo -e "${RED}未找到ONNX模型${NC}"
exit 1
fi
echo -e "${GREEN}找到以下模型:${NC}"
echo "$models" | nl
echo
# 测试第一个模型
first_model=$(echo "$models" | head -1)
model_dir=$(dirname "$first_model")
model_name=$(basename "$first_model" .onnx)
echo -e "${YELLOW}测试第一个模型: $model_name${NC}"
echo -e "模型目录: $model_dir"
echo
# 运行load测试
echo -e "${YELLOW}运行 01_load.sh 测试...${NC}"
cd "$TEST_DIR"
if bash 01_load.sh "$model_dir"; then
echo -e "${GREEN}✓ Load 测试通过${NC}"
else
echo -e "${RED}✗ Load 测试失败${NC}"
exit 1
fi
echo
echo -e "${GREEN}=== 简化测试完成 ===${NC}"
echo -e "提示: 可以编辑此脚本测试其他模型或步骤"
echo -e "完整版脚本: $TEST_DIR/run_examples_test.sh"

37
vendor/README.md vendored Normal file
View File

@ -0,0 +1,37 @@
# 第三方依赖
此目录存放项目依赖的外部 whl 包。
## 文件列表
| 文件 | 版本 | 说明 |
|------|------|------|
| acuity-6.33.19-cp310-cp310-manylinux2010_x86_64.whl | 6.33.19 | PNNA 芯片模型编译核心库 |
## 获取方式
acuity whl 文件请联系项目维护团队获取。
## 使用说明
### 开发环境安装
```bash
# 使用 --no-deps 避免 acuity 覆盖已安装的 torch 版本
# torch 已在 requirements.txt 中单独安装
pip install vendor/acuity-6.33.19-cp310-cp310-manylinux2010_x86_64.whl --no-deps
```
### 离线打包
构建离线包时会自动包含此目录的 whl 文件:
```bash
cd devtools/packing/
python3 download_dependencies.py # 会自动复制 vendor/ 中的 acuity
bash build.sh
```
## 版本历史
- **6.33.19** (2026-02-09) - 当前版本