diff --git a/cpp/.gitattributes b/cpp/.gitattributes
deleted file mode 100644
index 01e2bca4a26a52b8fa6ade219b8fb5950e00ab34..0000000000000000000000000000000000000000
--- a/cpp/.gitattributes
+++ /dev/null
@@ -1,2 +0,0 @@
-*.axmodel filter=lfs diff=lfs merge=lfs -text
-*.onnx filter=lfs diff=lfs merge=lfs -text
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
deleted file mode 100644
index 0481f5c92197651d742a105ce66ce6037bab8021..0000000000000000000000000000000000000000
--- a/cpp/CMakeLists.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
-project(zipvoice)
-
-if (NOT DEFINED CMAKE_CXX_STANDARD)
- set(CMAKE_CXX_STANDARD 14)
-endif()
-
-if(CMAKE_BUILD_TYPE MATCHES Debug)
- set(CMAKE_CXX_FLAGS "-fvisibility=hidden -g -O0")
-elseif(CMAKE_BUILD_TYPE MATCHES Release)
- set(CMAKE_CXX_FLAGS "-fvisibility=hidden -O2 -fdata-sections -ffunction-sections")
-endif()
-
-# Platform dependencies (AXERA or AXCL)
-include(cmake/msp_dependencies.cmake)
-
-include_directories(${MSP_INC_DIR})
-
-# Project includes
-include_directories(${CMAKE_SOURCE_DIR})
-include_directories(${CMAKE_SOURCE_DIR}/src/)
-
-# Core source files (common to AXERA and AXCL)
-set(SRC
- src/EngineWrapper.cpp
- src/tokenizer.cpp
- src/fbank.cpp
- src/zipvoice_engine.cpp
- src/vocoder.cpp
- third_party/kissfft/kiss_fft.c
-)
-
-# AXCL-only source files (middleware + utilities)
-if(AXCL)
- aux_source_directory(${CMAKE_SOURCE_DIR}/src/middleware AXCL_SRCS)
- aux_source_directory(${CMAKE_SOURCE_DIR}/src/utilities AXCL_SRCS)
- list(APPEND SRC ${AXCL_SRCS})
- message(STATUS "AXCL middleware: ${AXCL_SRCS}")
-endif()
-
-add_executable(${PROJECT_NAME} zipvoice.cpp ${SRC})
-target_include_directories(${PROJECT_NAME} PRIVATE third_party/kissfft)
-target_link_libraries(${PROJECT_NAME} ${MSP_LIBS})
-
-install(TARGETS ${PROJECT_NAME}
- RUNTIME DESTINATION ./)
-set_target_properties(${PROJECT_NAME}
- PROPERTIES
- INSTALL_RPATH "$ORIGIN/")
-
-message(STATUS "========================================")
-message(STATUS "ZipVoice C++ Build Configuration")
-message(STATUS "========================================")
diff --git a/cpp/README.md b/cpp/README.md
deleted file mode 100644
index 1e3af3a39975d4544032d294862eaf97d326e92d..0000000000000000000000000000000000000000
--- a/cpp/README.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# ZipVoice C++ — AXERA & AXCL
-
-## 性能
-
-### Distill 模型 (num_step=4)
-
-| 场景 | 音频 | Python AX650
耗时 RTF | C++ AX650
耗时 RTF | C++ AXCL
耗时 RTF | Python AX630C
耗时 RTF | C++ AX630C
耗时 RTF |
-|------|------|-------------------------|----------------------|---------------------|--------------------------|-----------------------|
-| 中文句子 | 6.41s | 1.992s/0.311 | 1.057s/0.165 | 0.918s/**0.143** | 10.296s/1.606 | 4.650s/0.725 |
-| 中文段落 | 44.97s | 13.457s/0.301 | 7.357s/0.164 | 6.443s/**0.143** | 71.574s/1.600 | 32.590s/0.725 |
-| 英文句子 | 6.41s | 2.045s/0.319 | 1.067s/0.166 | 0.919s/**0.143** | 10.686s/1.667 | 4.654s/0.726 |
-| 英文段落 | 59.16s | 19.715s/0.305 | 10.529s/0.178 | 9.207s/**0.156** | 106.183s/1.640 | 46.541s/0.787 |
-
-### 普通模型 (num_step=10)
-
-| 场景 | 音频时长 | Python AX650 (耗时/RTF) | C++ AX650 (耗时/RTF) | C++ AXCL (耗时/RTF) |
-|------|---------|------------------------|---------------------|---------------------|
-| 中文句子 | 6.41s | 5.781s / 0.902 | 5.709s / 0.891 | 5.452s / **0.850** |
-| 中文段落 | 44.97s | 40.292s / 0.901 | 39.714s / 0.883 | 38.138s / **0.848** |
-| 英文句子 | 6.41s | 5.711s / 0.891 | 5.693s / 0.888 | 5.447s / **0.850** |
-| 英文段落 | 59.16s | 62.161s / 0.960 | 56.759s / 0.957 | 54.451s / **0.920** |
-
-## 环境准备
-
-下载交叉编译器、AXERA SDK、AXCL SDK 到指定目录(记为 ``):
-
-```bash
-bash download_bsp.sh
-
-# 或手动:
-mkdir -p && cd
-wget https://developer.arm.com/-/media/Files/downloads/gnu-a/9.2-2019.12/binrel/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz
-tar -xf gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz
-git clone https://github.com/AXERA-TECH/ax650n_bsp_sdk.git --depth=1
-git clone https://github.com/AXERA-TECH/ax620e_bsp_sdk.git --depth=1
-git clone https://github.com/Abandon-ht/axcl_bsp_sdk.git --depth=1
-```
-
-修改 `cmake/msp_dependencies.cmake` 和 `toolchains/aarch64-none-linux-gnu.toolchain.cmake` 中的路径。
-
-英文分词需 Python 依赖(运行设备上安装):
-```bash
-pip install jieba numpy pypinyin piper_phonemize
-```
-
-## 编译
-
-```bash
-bash build_ax650.sh # → install/ax650/zipvoice
-bash build_ax630c.sh # → install/ax630c/zipvoice
-bash build_axcl.sh # → install/axcl/zipvoice
-```
-
-## 运行
-
-在 repo 根目录(`ZipVoice.AXERA/`)执行:
-
-```bash
-# 板端
-bash run_ax650.sh distill zh sentence
-bash run_ax650.sh distill zh paragraph
-bash run_ax650.sh standard zh sentence
-bash run_ax650.sh standard zh paragraph
-bash run_ax650.sh distill en sentence
-bash run_ax650.sh distill en paragraph
-bash run_ax650.sh standard en sentence
-bash run_ax650.sh standard en paragraph
-
-# 算力卡
-bash run_axcl.sh distill zh paragraph
-bash run_axcl.sh standard en sentence
-
-# AX630C (仅 distill)
-bash run_ax630c.sh zh sentence
-bash run_ax630c.sh en paragraph
-...
-```
-
-## 参数
-
-| 参数 | 说明 | 默认值 |
-|------|------|--------|
-| `--model-dir` | 模型目录 | 必填 |
-| `--prompt-wav` | 提示音频 | 必填 |
-| `--prompt-text` | 提示文本 | 必填 |
-| `--text` / `--text-file` | 合成文本 | 二选一 |
-| `--vocoder-model` | vocos_full.axmodel 路径 | 必填 |
-| `--output-wav` | 输出 WAV | output.wav |
-| `--num-step` | 采样步数 | 10 (distill: 4) |
-| `--seed` | 随机种子 | 42 |
diff --git a/cpp/build_ax650.sh b/cpp/build_ax650.sh
deleted file mode 100644
index bee29b7a887c7baf4da72120def1d60d7dc2a52d..0000000000000000000000000000000000000000
--- a/cpp/build_ax650.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-# Cross-compile ZipVoice for AXERA (AX650 demo board)
-#
-# Prerequisites:
-# - AX650 BSP SDK: cpp/ax650n_bsp_sdk/ (run download_bsp.sh first)
-# - Cross compiler: /data/shared/huyuan/toolchains/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/
-
-set -e
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-cd "$SCRIPT_DIR"
-
-rm -rf build_ax650
-mkdir -p build_ax650 && cd build_ax650
-
-cmake .. \
- -DAX650=ON \
- -DCMAKE_TOOLCHAIN_FILE=../toolchains/aarch64-none-linux-gnu.toolchain.cmake \
- -DCMAKE_INSTALL_PREFIX=../install/ax650 \
- -DCMAKE_BUILD_TYPE=Release \
- $@
-
-make -j$(nproc)
-make install
-
-echo ""
-echo "========================================"
-echo "Build complete!"
-echo "Executable: $(pwd)/../install/ax650/zipvoice"
-echo "========================================"
diff --git a/cpp/build_axcl.sh b/cpp/build_axcl.sh
deleted file mode 100644
index 30d3f199fa37d46adf2b255d0bb03c248c0d7058..0000000000000000000000000000000000000000
--- a/cpp/build_axcl.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-# Cross-compile ZipVoice for AXCL (AXCL compute card)
-#
-# Prerequisites:
-# - AXCL BSP SDK: /data/shared/huyuan/toolchains/axcl_bsp_sdk/
-# - Cross compiler: /data/shared/huyuan/toolchains/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/
-#
-# Clone SDK (one-time):
-# cd /data/shared/huyuan/toolchains
-# git clone https://github.com/Abandon-ht/axcl_bsp_sdk.git --depth=1
-
-set -e
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-cd "$SCRIPT_DIR"
-
-rm -rf build_axcl
-mkdir -p build_axcl && cd build_axcl
-
-cmake .. \
- -DAXCL=ON \
- -DCMAKE_TOOLCHAIN_FILE=../toolchains/aarch64-none-linux-gnu.toolchain.cmake \
- -DCMAKE_INSTALL_PREFIX=../install/axcl \
- -DCMAKE_BUILD_TYPE=Release \
- $@
-
-make -j$(nproc)
-make install
-
-echo ""
-echo "========================================"
-echo "Build complete!"
-echo "Executable: $(pwd)/../install/axcl/zipvoice"
-echo "========================================"
diff --git a/cpp/cmake/msp_dependencies.cmake b/cpp/cmake/msp_dependencies.cmake
deleted file mode 100644
index 4c30586ea8f965e9050b0f82e34f23ebcd635c4a..0000000000000000000000000000000000000000
--- a/cpp/cmake/msp_dependencies.cmake
+++ /dev/null
@@ -1,68 +0,0 @@
-# BSP / SDK Dependencies Configuration
-# Supports both AXERA (demo board) and AXCL (compute card)
-#
-# AXERA: AX650 / AX630C / AX620Q
-# AXCL: AXCL
-
-if (AX650)
- add_definitions(-DAX650)
- if(NOT BSP_MSP_DIR)
- set(BSP_MSP_DIR /data/shared/huyuan/toolchains/ax650n_bsp_sdk/msp/out)
- endif()
- if(NOT EXISTS ${BSP_MSP_DIR})
- message(FATAL_ERROR "BSP_MSP_DIR ${BSP_MSP_DIR} not exist. Run download_bsp.sh first.")
- endif()
- set(MSP_INC_DIR ${BSP_MSP_DIR}/include)
- set(MSP_LIB_DIR ${BSP_MSP_DIR}/lib)
- list(APPEND MSP_LIBS ax_sys ax_engine ax_interpreter)
-
-elseif(AX630C)
- add_definitions(-DAX630C)
- if(NOT BSP_MSP_DIR)
- set(BSP_MSP_DIR /data/shared/huyuan/toolchains/ax620e_bsp_sdk/msp/out/arm64_glibc)
- endif()
- set(MSP_INC_DIR ${BSP_MSP_DIR}/include)
- set(MSP_LIB_DIR ${BSP_MSP_DIR}/lib)
- list(APPEND MSP_LIBS ax_sys ax_engine ax_interpreter)
-
-elseif(AX620Q)
- add_definitions(-DAX620Q)
- if(NOT BSP_MSP_DIR)
- set(BSP_MSP_DIR ${CMAKE_SOURCE_DIR}/ax620e_bsp_sdk/msp/out/arm_uclibc)
- endif()
- if(NOT EXISTS ${BSP_MSP_DIR})
- message(FATAL_ERROR "BSP_MSP_DIR ${BSP_MSP_DIR} not exist.")
- endif()
- set(MSP_INC_DIR ${BSP_MSP_DIR}/include)
- set(MSP_LIB_DIR ${BSP_MSP_DIR}/lib)
- list(APPEND MSP_LIBS ax_sys ax_engine ax_interpreter)
-
-elseif(AXCL)
- add_definitions(-DAXCL)
- add_definitions(-DENV_AXCL_RUNTIME_API_ENABLE)
- add_definitions(-DENV_AXCL_NATIVE_API_ENABLE)
- add_definitions(-DENV_HAS_STD_FILESYSTEM)
- add_definitions(-DENV_HAS_POSIX_FILE_STAT)
-
- # AXCL SDK at /data/shared/huyuan/toolchains/axcl_bsp_sdk/out/
- if(NOT AXCL_SDK_DIR)
- set(AXCL_SDK_DIR /data/shared/huyuan/toolchains/axcl_bsp_sdk/out)
- endif()
- if(NOT EXISTS ${AXCL_SDK_DIR})
- message(FATAL_ERROR "AXCL_SDK_DIR ${AXCL_SDK_DIR} not exist. Run download_bsp.sh first.")
- endif()
- set(MSP_INC_DIR ${AXCL_SDK_DIR}/include ${AXCL_SDK_DIR}/bsp)
- set(MSP_LIB_DIR ${AXCL_SDK_DIR}/lib)
- list(APPEND MSP_LIBS
- axcl_rt axcl_pkg axcl_comm axcl_npu spdlog
- axcl_token axcl_pcie_msg axcl_pcie_dma)
- set(CMAKE_CXX_STANDARD 17)
-
-else()
- message(FATAL_ERROR "Unknown platform. Set -DAX650, -DAX630C, -DAX620Q, or -DAXCL.")
-endif()
-
-link_directories(${MSP_LIB_DIR})
-message(STATUS "MSP_INC_DIR: ${MSP_INC_DIR}")
-message(STATUS "MSP_LIB_DIR: ${MSP_LIB_DIR}")
-message(STATUS "MSP_LIBS: ${MSP_LIBS}")
diff --git a/cpp/download_bsp.sh b/cpp/download_bsp.sh
deleted file mode 100644
index ae1d988bef666f64a419c267540a2ea0d3b29768..0000000000000000000000000000000000000000
--- a/cpp/download_bsp.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-# Download BSP SDKs to /data/shared/huyuan/toolchains/
-
-TARGET=/data/shared/huyuan/toolchains
-mkdir -p $TARGET && cd $TARGET
-
-if [ ! -d ax650n_bsp_sdk ]; then
- echo "Downloading ax650n_bsp_sdk..."
- git clone https://github.com/AXERA-TECH/ax650n_bsp_sdk.git --depth=1
-fi
-
-if [ ! -d ax620e_bsp_sdk ]; then
- echo "Downloading ax620e_bsp_sdk..."
- git clone https://github.com/AXERA-TECH/ax620e_bsp_sdk.git --depth=1
-fi
-
-if [ ! -d axcl_bsp_sdk ]; then
- echo "Downloading axcl_bsp_sdk..."
- git clone https://github.com/Abandon-ht/axcl_bsp_sdk.git --depth=1
-fi
-
-echo "Done. SDKs at $TARGET/"
-ls -d ax650n_bsp_sdk ax620e_bsp_sdk axcl_bsp_sdk 2>/dev/null
\ No newline at end of file
diff --git a/cpp/install/ax650/zipvoice b/cpp/install/ax650/zipvoice
deleted file mode 100644
index b4e789a2f0be02240984eb8c5008488beacdce80..0000000000000000000000000000000000000000
--- a/cpp/install/ax650/zipvoice
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:bb407d306e74de864ee7966937552da945db72207ccdea7c7b17950805642978
-size 582632
diff --git a/cpp/install/ax650/zipvoice_axera b/cpp/install/ax650/zipvoice_axera
deleted file mode 100644
index 0e61c0dfc0dd8a230f31a4cad3d0282ef234ccf6..0000000000000000000000000000000000000000
--- a/cpp/install/ax650/zipvoice_axera
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:0d15168590f21a4255f223055008fb6832babf8a1f096c39f93afe0d78fb4c98
-size 582624
diff --git a/cpp/install/axcl/zipvoice b/cpp/install/axcl/zipvoice
deleted file mode 100644
index ce8c31091f8a705192a974dea8eff8d3b464ab93..0000000000000000000000000000000000000000
--- a/cpp/install/axcl/zipvoice
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:f70b9a838f6505d99d2c1cc3131c89565aa25550109336387fbc8a3d49205165
-size 658128
diff --git a/cpp/scripts/compare_vocoder.py b/cpp/scripts/compare_vocoder.py
deleted file mode 100644
index 46b9903ac3444112400a83387529a4dec069921e..0000000000000000000000000000000000000000
--- a/cpp/scripts/compare_vocoder.py
+++ /dev/null
@@ -1,277 +0,0 @@
-#!/usr/bin/env python3
-"""
-Compare PyTorch vocoder vs quantized axmodel output.
-Saves intermediate tensors for board-side comparison.
-
-Usage:
- # Dev machine: generate test data
- python3 compare_vocoder.py --save-test-data
-
- # Board: run axmodel on same input, save output
- python3 compare_vocoder.py --run-axmodel
-
- # Dev machine: compare results
- python3 compare_vocoder.py --compare
-"""
-import sys, os, math, argparse
-import numpy as np
-
-REPO_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-ONNX_DIR = os.path.join(REPO_DIR, 'cpp', 'vocoder_onnx')
-TEST_DIR = os.path.join(ONNX_DIR, 'test_data')
-os.makedirs(TEST_DIR, exist_ok=True)
-
-FEAT_SCALE = 0.1
-N_FFT = 1024
-HOP = 256
-
-
-def irfft_overlap_add(real_spec, imag_spec):
- """C++ IRFFT + overlap-add, verified to match PyTorch istft (cos_sim=0.999999)."""
- n_freqs = N_FFT // 2 + 1
- T = real_spec.shape[1]
- window = 0.5 * (1.0 - np.cos(2.0 * math.pi * np.arange(N_FFT) / (N_FFT - 1)))
- window_sq = window ** 2
-
- # Build IRFFT basis
- irfft_cos = np.zeros((N_FFT, n_freqs), dtype=np.float32)
- irfft_sin = np.zeros((N_FFT, n_freqs), dtype=np.float32)
- for n in range(N_FFT):
- for k in range(n_freqs):
- ang = 2.0 * math.pi * k * n / N_FFT
- if k == 0:
- irfft_cos[n, k] = 1.0 / N_FFT
- irfft_sin[n, k] = 0.0
- elif k == n_freqs - 1:
- irfft_cos[n, k] = math.cos(ang) / N_FFT
- irfft_sin[n, k] = 0.0
- else:
- irfft_cos[n, k] = math.cos(ang) * (2.0 / N_FFT)
- irfft_sin[n, k] = math.sin(ang) * (2.0 / N_FFT)
-
- out_len = (T - 1) * HOP + N_FFT
- audio = np.zeros(out_len, dtype=np.float32)
- envelope = np.zeros(out_len, dtype=np.float32)
-
- for t in range(T):
- r = real_spec[0, t, :]
- im = imag_spec[0, t, :]
- frame = irfft_cos @ r - irfft_sin @ im
- pos = t * HOP
- for n in range(N_FFT):
- p = pos + n
- if p < out_len:
- audio[p] += frame[n] * window[n]
- envelope[p] += window_sq[n]
-
- audio /= np.maximum(envelope, 1e-10)
- pad = N_FFT // 2
- return audio[pad:pad + (T - 1) * HOP]
-
-
-def compare(name, ref, test):
- ref = np.asarray(ref, dtype=np.float32).flatten()
- test = np.asarray(test, dtype=np.float32).flatten()
- if len(ref) != len(test):
- print(f" [{name}] SIZE MISMATCH: ref={ref.shape} test={test.shape}")
- return
- diff = np.abs(ref - test)
- sig = np.mean(np.abs(ref)) + 1e-10
- cos = np.dot(ref, test) / (np.linalg.norm(ref) * np.linalg.norm(test) + 1e-10)
- print(f" [{name}] max_err={diff.max():.2e} rel_err={diff.mean()/sig:.2e} cos_sim={cos:.6f}")
-
-
-def cmd_save_test_data():
- """Generate test mel and save PT/ONNX reference outputs."""
- import torch
- sys.path.insert(0, REPO_DIR)
- from scripts.local_vocos import LocalVocos
- import onnxruntime as ort
-
- # Load models
- vocoder = LocalVocos()
- sd = torch.load(f'{REPO_DIR}/resources/vocos-mel-24khz/pytorch_model.bin',
- weights_only=True, map_location='cpu')
- sd = {k: v for k, v in sd.items() if k.startswith(('backbone.', 'head.'))}
- vocoder.load_state_dict(sd)
- vocoder.eval()
-
- sess_f = ort.InferenceSession(f'{ONNX_DIR}/vocos_full_B1_T620.onnx')
-
- # Load real mel or generate random
- mel_bin = os.path.join(REPO_DIR, 'cpp', 'output_mel.bin')
- if os.path.exists(mel_bin):
- real_mel = np.fromfile(mel_bin, dtype=np.float32).reshape(-1, 100) # [T, 100]
- T = real_mel.shape[0]
- # Undo feat_scale, transpose to [1, 100, T]
- mel_input = (real_mel / FEAT_SCALE).T[np.newaxis, :, :].astype(np.float32) # [1, 100, T]
- print(f"Using real mel: shape={mel_input.shape}, range=[{mel_input.min():.3f}, {mel_input.max():.3f}]")
- else:
- T = 200
- mel_input = np.random.RandomState(42).randn(1, 100, T).astype(np.float32) * 3.0
- print(f"Using random mel: shape={mel_input.shape}")
-
- # Pad to 620 for ONNX
- T_pad = 620
- mel_onnx = np.zeros((1, 100, T_pad), dtype=np.float32)
- mel_onnx[:, :, :T] = mel_input[:, :, :T]
-
- # PT inference
- mel_pt = torch.from_numpy(mel_input)
- with torch.no_grad():
- features_pt = vocoder.backbone(mel_pt)
- audio_pt = vocoder.head(features_pt).squeeze().numpy()
- h = vocoder.head.out(features_pt)
- mag, phase = h.chunk(2, dim=-1)
- mag = torch.exp(mag).clamp(max=1e2)
- real_pt = (mag * torch.cos(phase)).numpy()
- imag_pt = (mag * torch.sin(phase)).numpy()
-
- # ONNX inference
- onnx_out = sess_f.run(None, {'mel': mel_onnx})
- real_onnx = onnx_out[0][:, :T, :]
- imag_onnx = onnx_out[1][:, :T, :]
- audio_onnx = irfft_overlap_add(real_onnx, imag_onnx)
-
- # Save everything
- np.save(f'{TEST_DIR}/mel_input.npy', mel_input)
- np.save(f'{TEST_DIR}/mel_onnx_padded.npy', mel_onnx)
- np.save(f'{TEST_DIR}/pt_real.npy', real_pt)
- np.save(f'{TEST_DIR}/pt_imag.npy', imag_pt)
- np.save(f'{TEST_DIR}/pt_audio.npy', audio_pt)
- np.save(f'{TEST_DIR}/onnx_real.npy', real_onnx)
- np.save(f'{TEST_DIR}/onnx_imag.npy', imag_onnx)
- np.save(f'{TEST_DIR}/onnx_audio.npy', audio_onnx)
- np.save(f'{TEST_DIR}/T_frames.npy', np.array([T], dtype=np.int32))
-
- # Meta
- with open(f'{TEST_DIR}/info.txt', 'w') as f:
- f.write(f"T={T}\n")
- f.write(f"feat_scale={FEAT_SCALE}\n")
- f.write(f"mel_range=[{mel_input.min():.4f}, {mel_input.max():.4f}]\n")
- f.write(f"pt_real_range=[{real_pt.min():.4f}, {real_pt.max():.4f}]\n")
- f.write(f"pt_audio_len={len(audio_pt)}\n")
-
- # Verify PT vs ONNX
- print("\n=== PT vs ONNX (dev machine) ===")
- compare('real_spectrum', real_pt, real_onnx)
- compare('imag_spectrum', imag_pt, imag_onnx)
- compare('audio', audio_pt, audio_onnx)
-
- # Also write audio files for listening
- import soundfile as sf
- sf.write(f'{TEST_DIR}/pt_audio.wav', audio_pt, 24000)
- sf.write(f'{TEST_DIR}/onnx_audio.wav', audio_onnx, 24000)
-
- print(f"\nTest data saved to {TEST_DIR}/")
- print("Copy to board and run: python3 compare_vocoder.py --run-axmodel")
-
-
-def cmd_run_axmodel():
- """Run axmodel on board with the same test mel, save output."""
- import onnxruntime as ort
- from axengine import InferenceSession
-
- T = int(np.load(f'{TEST_DIR}/T_frames.npy')[0])
- mel_onnx = np.load(f'{TEST_DIR}/mel_onnx_padded.npy')
-
- # Run axmodel
- model_path = f'{ONNX_DIR}/axmodel/vocos_full.axmodel'
- if not os.path.exists(model_path):
- print(f"ERROR: {model_path} not found")
- return
-
- print(f"Loading axmodel: {model_path}")
- sess = InferenceSession(model_path)
-
- print(f"Running inference (mel shape={mel_onnx.shape})...")
- outputs = sess.run(None, {'mel': mel_onnx})
- print(f"Output keys: {list(outputs.keys()) if isinstance(outputs, dict) else type(outputs)}")
-
- # Extract real/imag
- if isinstance(outputs, dict):
- real_ax = outputs['real'][:, :T, :]
- imag_ax = outputs['imag'][:, :T, :]
- elif isinstance(outputs, (list, tuple)):
- real_ax = outputs[0][:, :T, :]
- imag_ax = outputs[1][:, :T, :]
- else:
- real_ax = outputs[:, :T, :] # guess
- imag_ax = None
-
- audio_ax = irfft_overlap_add(real_ax, imag_ax)
-
- # Save
- np.save(f'{TEST_DIR}/ax_real.npy', real_ax)
- np.save(f'{TEST_DIR}/ax_imag.npy', imag_ax)
- np.save(f'{TEST_DIR}/ax_audio.npy', audio_ax)
- import soundfile as sf
- sf.write(f'{TEST_DIR}/ax_audio.wav', audio_ax, 24000)
-
- # Compare with ONNX reference
- onnx_real = np.load(f'{TEST_DIR}/onnx_real.npy')
- onnx_imag = np.load(f'{TEST_DIR}/onnx_imag.npy')
- onnx_audio = np.load(f'{TEST_DIR}/onnx_audio.npy')
-
- print("\n=== axmodel vs ONNX (board) ===")
- compare('real_spectrum', onnx_real, real_ax)
- compare('imag_spectrum', onnx_imag, imag_ax)
- compare('audio', onnx_audio, audio_ax)
-
- print(f"\nResults saved to {TEST_DIR}/")
- print("Copy back to dev machine and run: python3 compare_vocoder.py --compare")
-
-
-def cmd_compare():
- """Compare all outputs (dev machine, after copying ax_*.npy from board)."""
- pt_audio = np.load(f'{TEST_DIR}/pt_audio.npy')
- onnx_audio = np.load(f'{TEST_DIR}/onnx_audio.npy')
- ax_audio = np.load(f'{TEST_DIR}/ax_audio.npy')
-
- pt_real = np.load(f'{TEST_DIR}/pt_real.npy')
- onnx_real = np.load(f'{TEST_DIR}/onnx_real.npy')
- ax_real = np.load(f'{TEST_DIR}/ax_real.npy')
-
- pt_imag = np.load(f'{TEST_DIR}/pt_imag.npy')
- onnx_imag = np.load(f'{TEST_DIR}/onnx_imag.npy')
- ax_imag = np.load(f'{TEST_DIR}/ax_imag.npy')
-
- print("=== Full Comparison ===")
- print("\n--- Spectrum ---")
- compare('real: PT vs ONNX', pt_real, onnx_real)
- compare('real: PT vs axmodel', pt_real, ax_real)
- compare('real: ONNX vs axmodel', onnx_real, ax_real)
- print()
- compare('imag: PT vs ONNX', pt_imag, onnx_imag)
- compare('imag: PT vs axmodel', pt_imag, ax_imag)
- compare('imag: ONNX vs axmodel', onnx_imag, ax_imag)
-
- print("\n--- Audio ---")
- compare('audio: PT vs ONNX', pt_audio, onnx_audio)
- compare('audio: PT vs axmodel', pt_audio, ax_audio)
- compare('audio: ONNX vs axmodel', onnx_audio, ax_audio)
-
-
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument('--save-test-data', action='store_true')
- parser.add_argument('--run-axmodel', action='store_true')
- parser.add_argument('--compare', action='store_true')
- args = parser.parse_args()
-
- if args.save_test_data:
- cmd_save_test_data()
- elif args.run_axmodel:
- cmd_run_axmodel()
- elif args.compare:
- cmd_compare()
- else:
- print("Usage: --save-test-data | --run-axmodel | --compare")
- print("\nWorkflow:")
- print(" 1. Dev machine: python3 compare_vocoder.py --save-test-data")
- print(" 2. Copy TEST_DIR to board, run: python3 compare_vocoder.py --run-axmodel")
- print(" 3. Copy ax_*.npy back to dev, run: python3 compare_vocoder.py --compare")
-
-
-if __name__ == '__main__':
- main()
diff --git a/cpp/scripts/export_vocos_onnx.py b/cpp/scripts/export_vocos_onnx.py
deleted file mode 100644
index e85da9e289650d4c26169a4870bca7a371f55912..0000000000000000000000000000000000000000
--- a/cpp/scripts/export_vocos_onnx.py
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/usr/bin/env python3
-"""
-Export Vocos ONNX models with onnxsim optimization.
-
-Static shapes (B=1, T=620):
- vocos_backbone_B1_T620.onnx mel [1,100,620] → features [1,620,512]
- vocos_head_linear_B1_T620.onnx features [1,620,512] → (real, imag) [1,620,513]
- vocos_full_B1_T620.onnx mel [1,100,620] → (real, imag) [1,620,513]
-
-IRFFT + window + overlap-add is handled in C++ (simple, ~50 lines with existing FFT).
-"""
-import sys, os, math
-import numpy as np
-import torch
-import torch.nn as nn
-import onnx
-from onnxsim import simplify
-
-REPO_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-sys.path.insert(0, REPO_DIR)
-from scripts.local_vocos import LocalVocos, ISTFTHead
-
-OUT_DIR = os.path.join(REPO_DIR, 'cpp', 'vocoder_onnx')
-os.makedirs(OUT_DIR, exist_ok=True)
-
-
-class HeadLinearOnly(nn.Module):
- """Linear(512→1026) + mag/phase → real/imag spectrum. No ISTFT."""
- def __init__(self, head: ISTFTHead):
- super().__init__()
- self.out = head.out # Linear(512, 1026)
- def forward(self, x): # x: [B, T, 512]
- h = self.out(x); mag, phase = h.chunk(2, dim=-1)
- mag = torch.exp(mag).clamp(max=1e2)
- return mag * torch.cos(phase), mag * torch.sin(phase)
-
-
-class FullModel(nn.Module):
- def __init__(self, backbone, head_linear):
- super().__init__()
- self.backbone = backbone
- self.head_linear = head_linear
- def forward(self, mel):
- return self.head_linear(self.backbone(mel))
-
-
-def export_onnx(model, dummy, path, in_names, out_names, dyn=None):
- tmp = path + '.tmp'
- torch.onnx.export(model, dummy, tmp,
- input_names=in_names, output_names=out_names,
- dynamic_axes=dyn, opset_version=17, do_constant_folding=True)
- model_simp, check = simplify(tmp)
- assert check, f"onnxsim verification failed for {path}"
- onnx.save(model_simp, path)
- os.remove(tmp)
- size_mb = os.path.getsize(path) / 1024 / 1024
- print(f" {os.path.basename(path):50s} {size_mb:6.1f} MB")
-
-
-def verify(name, pt_list, onnx_list):
- for i, (pt, onnx_val) in enumerate(zip(pt_list, onnx_list)):
- diff = np.abs(pt - onnx_val)
- sig = max(np.mean(np.abs(pt)), 1e-10)
- print(f" [{name}/{i}] max_err={diff.max():.2e} rel_err={diff.mean()/sig:.2e} "
- f"shape={pt.shape}")
-
-
-def main():
- print("Loading Vocos...")
- vocoder = LocalVocos()
- sd = torch.load(f'{REPO_DIR}/resources/vocos-mel-24khz/pytorch_model.bin',
- weights_only=True, map_location='cpu')
- sd = {k: v for k, v in sd.items() if k.startswith(('backbone.', 'head.'))}
- vocoder.load_state_dict(sd)
- vocoder.eval()
-
- backbone = vocoder.backbone
- head_linear = HeadLinearOnly(vocoder.head).eval()
-
- B, T = 1, 620
- dummy_mel = torch.randn(B, 100, T)
-
- with torch.no_grad():
- bb_out = backbone(dummy_mel)
- pt_real, pt_imag = head_linear(bb_out)
-
- print(f"PT output: real={pt_real.shape}, imag={pt_imag.shape}")
-
- # --- Export static (B=1, T=620) ---
- print("\n=== Static models (B=1, T=620) ===")
- export_onnx(backbone, dummy_mel,
- f'{OUT_DIR}/vocos_backbone_B1_T620.onnx',
- ['mel'], ['features'])
- export_onnx(head_linear, bb_out,
- f'{OUT_DIR}/vocos_head_linear_B1_T620.onnx',
- ['features'], ['real', 'imag'])
- export_onnx(FullModel(backbone, head_linear).eval(), dummy_mel,
- f'{OUT_DIR}/vocos_full_B1_T620.onnx',
- ['mel'], ['real', 'imag'])
-
- # --- Verify with onnxruntime ---
- print("\n=== Verification ===")
- import onnxruntime as ort
-
- for tag, model_file, input_dict, pt_expected in [
- ('backbone', 'vocos_backbone_B1_T620.onnx',
- {'mel': dummy_mel.numpy()}, [bb_out.numpy()]),
- ('head_linear', 'vocos_head_linear_B1_T620.onnx',
- {'features': bb_out.numpy()}, [pt_real.numpy(), pt_imag.numpy()]),
- ('full', 'vocos_full_B1_T620.onnx',
- {'mel': dummy_mel.numpy()}, [pt_real.numpy(), pt_imag.numpy()]),
- ]:
- sess = ort.InferenceSession(f'{OUT_DIR}/{model_file}')
- onnx_out = sess.run(None, input_dict)
- verify(tag, pt_expected, onnx_out)
-
- print("\nDone! All exported and verified.")
- for f in sorted(os.listdir(OUT_DIR)):
- if 'B1_T620' in f:
- size = os.path.getsize(f'{OUT_DIR}/{f}') / 1024 / 1024
- print(f" {f} ({size:.1f} MB)")
-
-
-if __name__ == '__main__':
- main()
diff --git a/cpp/scripts/gen_cat_tokens.py b/cpp/scripts/gen_cat_tokens.py
deleted file mode 100644
index 3144469c2c24269b9cd3ef90515453adb2b879d4..0000000000000000000000000000000000000000
--- a/cpp/scripts/gen_cat_tokens.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python3
-"""Generate cat_tokens binary for C++ ZipVoice inference. Works for any language.
-
-Usage:
- python3 gen_cat_tokens.py --prompt "prompt text" --text "target text"
- python3 gen_cat_tokens.py --prompt-file prompt.txt --text-file target.txt
-"""
-import sys, os, argparse
-import numpy as np
-
-REPO_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # cpp/scripts → repo root
-sys.path.insert(0, REPO_DIR)
-
-from scripts.local_tokenizer import LocalEmiliaTokenizer
-from scripts.text_processing import normalize_punctuation
-
-parser = argparse.ArgumentParser()
-parser.add_argument('--prompt', default='')
-parser.add_argument('--text', default='')
-parser.add_argument('--prompt-file', default='')
-parser.add_argument('--text-file', default='')
-parser.add_argument('--output', default='cat_tokens.bin')
-parser.add_argument('--max-tokens', type=int, default=384)
-args = parser.parse_args()
-
-prompt = args.prompt or (open(args.prompt_file).read().strip() if args.prompt_file else '')
-text = args.text or (open(args.text_file).read().strip() if args.text_file else '')
-
-if not prompt or not text:
- print("ERROR: provide --prompt/--prompt-file and --text/--text-file")
- sys.exit(1)
-
-token_file = os.path.join(REPO_DIR, 'resources', 'zipvoice_hf', 'zipvoice', 'tokens.txt')
-tokenizer = LocalEmiliaTokenizer(token_file=token_file)
-
-pids = tokenizer.texts_to_token_ids([normalize_punctuation(prompt)])[0]
-tids = tokenizer.texts_to_token_ids([normalize_punctuation(text)])[0]
-
-cat = pids + tids + [tokenizer.pad_id]
-ct = np.full((args.max_tokens,), tokenizer.pad_id, dtype=np.int32)
-ct[:len(cat)] = np.array(cat, dtype=np.int32)
-ct.tofile(args.output)
-
-print(f'prompt_tokens_len={len(pids)} text_tokens_len={len(tids)} saved: {args.output}')
diff --git a/cpp/scripts/gen_pinyin_table.py b/cpp/scripts/gen_pinyin_table.py
deleted file mode 100644
index 057af1a70464fe0e0d515f88dc1a66a96be65b37..0000000000000000000000000000000000000000
--- a/cpp/scripts/gen_pinyin_table.py
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/env python3
-"""Generate C++ header with Chinese character → pinyin token mapping."""
-import sys, os
-REPO_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-sys.path.insert(0, REPO_DIR)
-
-from pypinyin.pinyin_dict import pinyin_dict
-from pypinyin.contrib.tone_convert import to_initials, to_finals_tone3
-
-TOKEN_FILE = os.path.join(REPO_DIR, 'resources', 'zipvoice_hf', 'zipvoice', 'tokens.txt')
-OUTPUT = os.path.join(REPO_DIR, 'cpp', 'src', 'pinyin_table.hpp')
-
-# Load token2id
-token2id = {}
-with open(TOKEN_FILE) as f:
- for line in f:
- if '\t' in line:
- t, tid = line.rstrip().split('\t')
- token2id[t] = int(tid)
-
-# Build char → token IDs
-char_entries = []
-for codepoint, pinyins in pinyin_dict.items():
- ch = chr(codepoint)
- py = pinyins.split(',')[0]
- initial = to_initials(py, strict=False)
- final = to_finals_tone3(py, strict=False, neutral_tone_with_five=True)
- if not final: continue
-
- ini_token = initial + '0' if initial else ''
- tokens = []
- if ini_token and ini_token in token2id:
- tokens.append(token2id[ini_token])
- if final in token2id:
- tokens.append(token2id[final])
-
- if tokens:
- char_entries.append((codepoint, tokens))
-
-# Sort by codepoint for binary search
-char_entries.sort(key=lambda x: x[0])
-
-# Generate C++ header
-with open(OUTPUT, 'w') as f:
- f.write('''// Auto-generated Chinese character → token ID mapping
-// Source: pypinyin.pinyin_dict, tokens.txt
-// Generated by gen_pinyin_table.py
-
-#pragma once
-#include
-#include
-#include
-
-struct PinyinEntry {
- uint32_t codepoint;
- int16_t token1;
- int16_t token2; // -1 if only one token
-};
-
-// Sorted by codepoint, use binary search
-static const PinyinEntry PINYIN_TABLE[] = {
-''')
-
- for codepoint, tokens in char_entries:
- t1 = tokens[0]
- t2 = tokens[1] if len(tokens) > 1 else -1
- f.write(f' {{0x{codepoint:04X}, {t1}, {t2}}}, // {chr(codepoint)}\n')
-
- f.write(f'''}};
-
-static const int PINYIN_TABLE_SIZE = {len(char_entries)};
-
-// Lookup tokens for a Chinese character. Returns empty vector if not found.
-inline std::vector pinyin_lookup(uint32_t codepoint) {{
- // Binary search
- int lo = 0, hi = PINYIN_TABLE_SIZE - 1;
- while (lo <= hi) {{
- int mid = (lo + hi) / 2;
- if (PINYIN_TABLE[mid].codepoint == codepoint) {{
- std::vector result;
- result.push_back(PINYIN_TABLE[mid].token1);
- if (PINYIN_TABLE[mid].token2 >= 0)
- result.push_back(PINYIN_TABLE[mid].token2);
- return result;
- }}
- if (PINYIN_TABLE[mid].codepoint < codepoint)
- lo = mid + 1;
- else
- hi = mid - 1;
- }}
- return {{}};
-}}
-''')
-
-print(f"Generated {OUTPUT}: {len(char_entries)} entries")
diff --git a/cpp/scripts/generate_vocoder_calib.py b/cpp/scripts/generate_vocoder_calib.py
deleted file mode 100644
index 7f22b6b3588ad461ad69696413e036be1127be60..0000000000000000000000000000000000000000
--- a/cpp/scripts/generate_vocoder_calib.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/env python3
-"""
-Generate vocoder calibration data on dev machine (no axengine needed).
-
-Collects mel features from:
- 1. Real mel output files (output_mel.bin from previous C++ runs)
- 2. Random mel features in the expected value range
- 3. Zero/silence mel features
-Then runs them through ONNX to get intermediate features for head_linear calibration.
-
-Usage:
- python3 generate_vocoder_calib.py --output-dir ./calib_data_vocoder
-"""
-import sys, os, argparse, json, glob
-from pathlib import Path
-import numpy as np
-import onnxruntime as ort
-
-SCRIPT_DIR = Path(__file__).resolve().parent
-REPO_DIR = SCRIPT_DIR.parent.parent # scripts/ → cpp/ → repo root
-ONNX_DIR = SCRIPT_DIR.parent / "vocoder_onnx" # cpp/vocoder_onnx
-
-
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument("--output-dir", default=str(ONNX_DIR / "calib_data"))
- parser.add_argument("--num-samples", type=int, default=16)
- parser.add_argument("--seed", type=int, default=42)
- args = parser.parse_args()
-
- out_dir = Path(args.output_dir)
- out_dir.mkdir(parents=True, exist_ok=True)
- rng = np.random.RandomState(args.seed)
-
- T = 620
- mel_samples = []
-
- # --- Source 1: Real mel features if available (undo feat_scale to match vocoder input) ---
- feat_scale = 0.1
- for pattern in ["output_mel.bin", "output_mel_debug.bin"]:
- for p in [REPO_DIR / pattern, SCRIPT_DIR / pattern]:
- if p.exists():
- mel = np.fromfile(str(p), dtype=np.float32).reshape(-1, 100).T[np.newaxis, :, :] / feat_scale # [1, 100, frames]
- gen_frames = min(mel.shape[2], T)
- padded = np.zeros((1, 100, T), dtype=np.float32)
- padded[0, :, :gen_frames] = mel[0, :, :gen_frames]
- mel_samples.append(padded)
- print(f"Real mel from {p}: shape={mel.shape}")
-
- # --- Source 2: Random mel in vocoder input range (after /feat_scale) ---
- # Python: features / 0.1 before vocoder → range ~[-8.6, 4.0]
- # So calibration mel should be in [feat_scaled] range, divided by feat_scale
- # to match the actual vocoder input distribution
- feat_scale = 0.1
- for i in range(max(0, args.num_samples - len(mel_samples))):
- length = rng.randint(100, T + 1)
- # Generate in feat_scaled range, then undo feat_scale
- mel = (rng.randn(1, 100, T).astype(np.float32) * 0.3 - 0.04) / feat_scale
- mel[0, :, length:] = 0.0
- mel_samples.append(mel)
-
- # --- Source 3: Edge cases (with feat_scale undo) ---
- mel_samples.append(np.zeros((1, 100, T), dtype=np.float32))
- mel_samples.append(np.ones((1, 100, T), dtype=np.float32) * 0.5 / feat_scale)
- mel_samples.append(rng.randn(1, 100, T).astype(np.float32) * 0.1 / feat_scale)
- mel_samples.append(rng.randn(1, 100, T).astype(np.float32) / feat_scale)
-
- print(f"\nTotal mel samples: {len(mel_samples)}")
-
- # --- Run ONNX to get backbone outputs (for head_linear calibration) ---
- bb_path = ONNX_DIR / "vocos_backbone_B1_T620.onnx"
- hl_path = ONNX_DIR / "vocos_head_linear_B1_T620.onnx"
-
- if not bb_path.exists():
- print(f"ERROR: {bb_path} not found. Run export_vocos_onnx.py first.")
- return
-
- sess_bb = ort.InferenceSession(str(bb_path))
- print(f"Loaded backbone: {bb_path}")
-
- # --- Save backbone calibration data ---
- bb_dir = out_dir / "vocos_backbone" / "mel"
- bb_dir.mkdir(parents=True, exist_ok=True)
- bb_entries = []
- backbone_outputs = []
-
- for i, mel in enumerate(mel_samples):
- np.save(bb_dir / f"{i:04d}.npy", mel)
- bb_entries.append({"file": f"mel/{i:04d}.npy", "shape": list(mel.shape)})
-
- # Run ONNX to get head_linear input
- feat = sess_bb.run(None, {'mel': mel})[0]
- backbone_outputs.append(feat)
-
- print(f"Backbone calibration: {len(bb_entries)} samples")
-
- # --- Save head_linear calibration data ---
- hl_dir = out_dir / "vocos_head_linear" / "features"
- hl_dir.mkdir(parents=True, exist_ok=True)
- hl_entries = []
-
- for i, feat in enumerate(backbone_outputs):
- np.save(hl_dir / f"{i:04d}.npy", feat)
- hl_entries.append({"file": f"features/{i:04d}.npy", "shape": list(feat.shape)})
-
- print(f"Head_linear calibration: {len(hl_entries)} samples")
-
- # --- Verify head_linear ONNX with calibration data ---
- if hl_path.exists():
- sess_hl = ort.InferenceSession(str(hl_path))
- for i in range(min(3, len(backbone_outputs))):
- r, im = sess_hl.run(None, {'features': backbone_outputs[i]})
- print(f" Verify head[{i}]: real range=[{r.min():.3f},{r.max():.3f}], "
- f"imag range=[{im.min():.3f},{im.max():.3f}]")
-
- # --- Manifest ---
- manifest = {
- "description": "Vocoder ONNX calibration data",
- "backbone": {
- "model": "vocos_backbone_B1_T620.onnx",
- "input": "mel", "shape": [1, 100, 620], "dtype": "float32",
- "num_samples": len(bb_entries),
- "files": bb_entries,
- },
- "head_linear": {
- "model": "vocos_head_linear_B1_T620.onnx",
- "input": "features", "shape": [1, 620, 512], "dtype": "float32",
- "num_samples": len(hl_entries),
- "files": hl_entries,
- },
- }
- with open(out_dir / "calib_manifest.json", "w") as f:
- json.dump(manifest, f, indent=2, ensure_ascii=False)
-
- print(f"\nDone! Output: {out_dir}")
- print(f" vocos_backbone/mel/ : {len(bb_entries)} .npy files")
- print(f" vocos_head_linear/features/: {len(hl_entries)} .npy files")
-
-
-if __name__ == "__main__":
- main()
diff --git a/cpp/scripts/py_daemon.py b/cpp/scripts/py_daemon.py
deleted file mode 100644
index 82e27859734e36c45a85c7426989359680d4f73b..0000000000000000000000000000000000000000
--- a/cpp/scripts/py_daemon.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python3
-"""
-ZipVoice Python daemon: loads tokenizer once, handles C++ requests via stdin/stdout.
-Protocol (tab-separated lines to preserve spaces in text paths):
- count\t\t
- -> prints "COUNT "
- tokenize\t\t\t\t
- -> prints "TOKENS "
- quit
- -> exits
-"""
-import sys, os
-import numpy as np
-
-REPO_DIR = sys.argv[1]
-sys.path.insert(0, REPO_DIR)
-
-from scripts.local_tokenizer import LocalEmiliaTokenizer
-from scripts.text_processing import normalize_punctuation
-
-TOKEN_FILE = os.path.join(REPO_DIR, "resources", "zipvoice_hf", "zipvoice", "tokens.txt")
-tokenizer = LocalEmiliaTokenizer(token_file=TOKEN_FILE)
-
-print("READY", flush=True)
-
-for line in sys.stdin:
- line = line.rstrip("\n")
- if not line:
- continue
- parts = line.split("\t")
- cmd = parts[0]
-
- if cmd == "count":
- prompt_file, text_file = parts[1], parts[2]
- pt = normalize_punctuation(open(prompt_file).read().strip())
- tt = normalize_punctuation(open(text_file).read().strip())
- pids = tokenizer.texts_to_token_ids([pt])[0]
- tids = tokenizer.texts_to_token_ids([tt])[0]
- print(f"COUNT {len(pids)} {len(tids)}", flush=True)
-
- elif cmd == "tokenize":
- prompt_file, text_file, max_tokens, output_bin = parts[1], parts[2], int(parts[3]), parts[4]
- pt = normalize_punctuation(open(prompt_file).read().strip())
- tt = normalize_punctuation(open(text_file).read().strip())
- pids = tokenizer.texts_to_token_ids([pt])[0]
- tids = tokenizer.texts_to_token_ids([tt])[0]
- cat = pids + tids + [tokenizer.pad_id]
- if len(cat) > max_tokens:
- print(f"ERROR too_many_tokens {len(cat)}>{max_tokens}", flush=True)
- continue
- ct = np.full((max_tokens,), tokenizer.pad_id, dtype=np.int32)
- ct[:len(cat)] = np.array(cat, dtype=np.int32)
- ct.tofile(output_bin)
- print(f"TOKENS {len(pids)} {len(tids)}", flush=True)
-
- elif cmd == "quit":
- break
diff --git a/cpp/scripts/quantize_vocoder.sh b/cpp/scripts/quantize_vocoder.sh
deleted file mode 100644
index a913101bf3d23def97a7b269ad28187ce70c8983..0000000000000000000000000000000000000000
--- a/cpp/scripts/quantize_vocoder.sh
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env bash
-# Quantize vocoder ONNX models to axmodel using pulsar2.
-#
-# Prerequisites:
-# 1. export_vocos_onnx.py (generates vocoder_onnx/*.onnx)
-# 2. generate_vocoder_calib.py (generates vocoder_onnx/calib_data/)
-# 3. source (activates pulsar2, e.g. $HOME/npu-codebase/script/npu_dev)
-#
-# Usage:
-# bash quantize_vocoder.sh
-
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-PARENT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
-cd "${PARENT_DIR}"
-
-ONNX_DIR="${PARENT_DIR}/vocoder_onnx"
-CALIB_DIR="${ONNX_DIR}/calib_data"
-BUILD_DIR="${ONNX_DIR}/pulsar2_build"
-AXMODEL_DIR="${ONNX_DIR}/axmodel"
-
-# --- Config ---
-TARGET_HARDWARE="${TARGET_HARDWARE:-AX650}"
-NPU_MODE="${NPU_MODE:-NPU3}"
-CHECK_LEVEL="${CHECK_LEVEL:-0}"
-DEFAULT_DATA_TYPE="${DEFAULT_DATA_TYPE:-U16}"
-CALIBRATION_SIZE="${CALIBRATION_SIZE:--1}"
-
-FULL_MODEL="${ONNX_DIR}/vocos_full_B1_T620.onnx"
-CALIB_DIR_BB="${CALIB_DIR}/vocos_backbone"
-
-if [ ! -f "${FULL_MODEL}" ]; then
- echo "ERROR: ${FULL_MODEL} not found. Run export_vocos_onnx.py first."
- exit 1
-fi
-
-if [ ! -d "${CALIB_DIR_BB}" ]; then
- echo "ERROR: ${CALIB_DIR_BB} not found. Run generate_vocoder_calib.py first."
- exit 1
-fi
-
-# Activate pulsar2 if not already available
-if ! command -v pulsar2 >/dev/null 2>&1; then
- echo "Activating pulsar2 environment..."
- set +u
- source "${NPU_DEV_ENV:-$HOME/npu-codebase/script/npu_dev}"
- set -u
-fi
-
-mkdir -p "${BUILD_DIR}" "${AXMODEL_DIR}"
-
-# --- Step 1: Package calibration data as tar.gz ---
-echo "=== Packaging calibration data ==="
-
-# Calibration for full model: mel -> (real, imag)
-# Input tensor is "mel", calibration data in vocos_backbone/mel/
-FULL_CALIB_TAR="${CALIB_DIR}/vocos_full_mel.tar.gz"
-INPUT_DIR="${CALIB_DIR_BB}/mel"
-
-if [ ! -f "${FULL_CALIB_TAR}" ]; then
- echo "Creating ${FULL_CALIB_TAR}..."
- cd "${INPUT_DIR}"
- tar czf "${FULL_CALIB_TAR}" --transform 's|.*/||' *.npy
- cd "${SCRIPT_DIR}"
-fi
-echo " ${FULL_CALIB_TAR} ($(du -h "${FULL_CALIB_TAR}" | cut -f1))"
-
-# --- Step 2: Build pulsar2 config ---
-echo ""
-echo "=== Quantizing vocos_full ==="
-
-CONFIG="${BUILD_DIR}/config_vocos_full.json"
-
-cat > "${CONFIG}" << EOF
-{
- "model_type": "ONNX",
- "npu_mode": "${NPU_MODE}",
- "input": "${FULL_MODEL}",
- "output_name": "vocos_full.axmodel",
- "output_dir": "${BUILD_DIR}",
- "target_hardware": "${TARGET_HARDWARE}",
- "onnx_opt": {"disable_onnx_optimization": false, "enable_onnxsim": true},
- "quant": {
- "input_configs": [
- {"tensor_name": "mel", "calibration_dataset": "${FULL_CALIB_TAR}", "calibration_format": "Numpy", "calibration_size": ${CALIBRATION_SIZE}}
- ],
- "layer_configs": [
- {"op_type": "Pow", "data_type": "U8"},
- {"start_tensor_names": ["DEFAULT"], "end_tensor_names": ["DEFAULT"], "data_type": "${DEFAULT_DATA_TYPE}"}
- ],
- "calibration_method": "MinMax",
- "enable_smooth_quant": true,
- "conv_bias_data_type": "FP32",
- "precision_analysis": true,
- "precision_analysis_method": "EndToEnd",
- "disable_auto_refine_scale": true,
- "transformer_opt_level": 0
- },
- "input_processors": [{"tensor_name": "DEFAULT"}],
- "compiler": {"check": ${CHECK_LEVEL}, "enable_slice_mode": false}
-}
-EOF
-
-echo "Config: ${CONFIG}"
-echo "Input shapes: mel:1x100x620"
-
-# --- Step 3: Run pulsar2 ---
-echo ""
-echo "=== Running pulsar2 build ==="
-pulsar2 build --config "${CONFIG}" --input_shapes "mel:1x100x620" 2>&1 | tee "${BUILD_DIR}/build_vocos_full.log"
-
-# --- Step 4: Copy output ---
-BUILD_OUTPUT="${BUILD_DIR}/vocos_full.axmodel"
-if [ -f "${BUILD_OUTPUT}" ]; then
- cp "${BUILD_OUTPUT}" "${AXMODEL_DIR}/"
- echo ""
- echo "=== Done! ==="
- ls -lh "${AXMODEL_DIR}/vocos_full.axmodel"
-else
- echo "ERROR: Build failed, ${BUILD_OUTPUT} not found"
- exit 1
-fi
diff --git a/cpp/src/EngineWrapper.cpp b/cpp/src/EngineWrapper.cpp
deleted file mode 100644
index 15c96b321633adeb58cd36c411a60d7b8ba284ac..0000000000000000000000000000000000000000
--- a/cpp/src/EngineWrapper.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-/**************************************************************************************************
- * ZipVoice C++ — Unified EngineWrapper implementation (AXERA & AXCL)
- *
- * Conditionally includes the platform-specific implementation.
- **************************************************************************************************/
-
-#if defined(AX650) || defined(AX630C) || defined(AX620Q)
- #include "EngineWrapper_axera.cpp"
-#elif defined(AXCL)
- #include "EngineWrapper_axcl.cpp"
-#else
- #error "Unknown platform. Define AX650, AX630C, AX620Q, or AXCL."
-#endif
diff --git a/cpp/src/EngineWrapper.hpp b/cpp/src/EngineWrapper.hpp
deleted file mode 100644
index 9228e16fc6c12fcea4a4e9601808ed332acb6710..0000000000000000000000000000000000000000
--- a/cpp/src/EngineWrapper.hpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/**************************************************************************************************
- * ZipVoice C++ — Unified EngineWrapper (AXERA & AXCL)
- *
- * Supports both AXERA (demo board) and AXCL (compute card) via conditional compilation.
- * AX650 / AX630C / AX620Q → AXERA path (ax_engine_api)
- * AXCL → AXCL path (middleware::runner)
- *
- * Interface is identical — callers don't need to know which backend is active.
- **************************************************************************************************/
-
-#pragma once
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#if defined(AX650) || defined(AX630C) || defined(AX620Q)
- #include "ax_engine_api.h"
-#elif defined(AXCL)
- #include "middleware/axcl_runtime_runner.hpp"
-#endif
-
-class EngineWrapper {
-public:
- EngineWrapper();
- ~EngineWrapper();
-
- /**
- * Initialize and load a model.
- * @param strModelPath Path to .axmodel file
- * @param nNpuType AXERA: VNPU type (0=default); AXCL: device_index (0=first card)
- * @param axclConfig AXCL: path to axcl.json (nullptr → /usr/local/axcl/axcl.json). Ignored on AXERA.
- */
- int Init(const char* strModelPath, uint32_t nNpuType = 0, const char* axclConfig = nullptr);
-
- // Index-based I/O
- int SetInput(void* pInput, int index);
- int RunSync();
- int GetOutput(void* pOutput, int index);
-
- // Name-based I/O
- int SetInputByName(const char* name, void* pInput);
- int GetOutputByName(const char* name, void* pOutput);
-
- int GetInputSize(int index);
- int GetOutputSize(int index);
- int GetInputSizeByName(const char* name);
- int GetOutputSizeByName(const char* name);
-
- int GetInputIndex(const char* name);
- int GetOutputIndex(const char* name);
- int GetInputCount() const { return m_input_num; }
- int GetOutputCount() const { return m_output_num; }
- const char* GetInputName(int index) const;
- const char* GetOutputName(int index) const;
-#if defined(AX650) || defined(AX630C) || defined(AX620Q)
- const char* GetInputDtypeStr(int index) const;
- const char* GetOutputDtypeStr(int index) const;
-#endif
-
- bool HasInit() const { return m_hasInit; }
- int Release();
-
-private:
- bool m_hasInit;
- int m_input_num, m_output_num;
-
- std::unordered_map m_input_name_to_idx;
- std::unordered_map m_output_name_to_idx;
-
-#if defined(AX650) || defined(AX630C) || defined(AX620Q)
- AX_ENGINE_HANDLE m_handle;
- AX_ENGINE_IO_INFO_T *m_io_info;
- AX_ENGINE_IO_T m_io;
-#elif defined(AXCL)
- std::unique_ptr m_runner;
-#endif
-};
diff --git a/cpp/src/EngineWrapper_axcl.cpp b/cpp/src/EngineWrapper_axcl.cpp
deleted file mode 100644
index 25207c32341b99db7a6e04817dc92925632efe5f..0000000000000000000000000000000000000000
--- a/cpp/src/EngineWrapper_axcl.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/**************************************************************************************************
- * ZipVoice AXCL C++ Port
- *
- * EngineWrapper implementation using middleware::runner (AXCL Runtime API).
- *
- * Key differences from AXERA:
- * - Uses axclrtMemcpy for host↔device data transfer
- * - No CMM (contiguous memory) allocation
- * - Runner manages device-side memory and NPU execution
- **************************************************************************************************/
-
-#include "EngineWrapper.hpp"
-
-#include
-#include
-#include
-
-#include
-
-EngineWrapper::EngineWrapper()
- : m_hasInit(false), m_input_num(0), m_output_num(0) {}
-
-EngineWrapper::~EngineWrapper() {
- Release();
-}
-
-int EngineWrapper::Init(const char* strModelPath,
- uint32_t nNpuType,
- const char* axclConfig) {
- const char* config = axclConfig ? axclConfig : "/usr/local/axcl/axcl.json";
- uint32_t device_index = nNpuType; // nNpuType = device_index on AXCL
- uint32_t npu_kind = 0; // AXCL_VNPU_DISABLE (default)
-
- // 1. Create runtime runner
- m_runner = std::make_unique();
-
- // 2. Initialize runner (handles axclrtEngineInit internally)
- if (!m_runner->init(config, device_index, npu_kind)) {
- fprintf(stderr, "[ERROR] AXCL runner init failed for model: %s\n", strModelPath);
- return -1;
- }
-
- // 3. Load model from file
- if (!m_runner->load(strModelPath)) {
- fprintf(stderr, "[ERROR] AXCL runner load failed for model: %s\n", strModelPath);
- return -1;
- }
-
- // 4. Prepare IO buffers (allocates device memory, sets up IO)
- if (!m_runner->prepare(true, true, 0, 0)) {
- fprintf(stderr, "[ERROR] AXCL runner prepare failed for model: %s\n", strModelPath);
- return -1;
- }
-
- // 5. Build name-to-index maps
- m_input_num = static_cast(m_runner->get_input_count());
- m_output_num = static_cast(m_runner->get_output_count());
-
- m_input_name_to_idx.clear();
- for (int i = 0; i < m_input_num; ++i) {
- std::string name = m_runner->get_input_name(i);
- m_input_name_to_idx[name] = i;
- }
-
- m_output_name_to_idx.clear();
- for (int i = 0; i < m_output_num; ++i) {
- std::string name = m_runner->get_output_name(i);
- m_output_name_to_idx[name] = i;
- }
-
- m_hasInit = true;
-
- printf("AXCL EngineWrapper loaded: %s (inputs=%d, outputs=%d)\n",
- strModelPath, m_input_num, m_output_num);
- for (int i = 0; i < m_input_num; ++i) {
- printf(" input[%d]: %s (%zu bytes)\n", i,
- m_runner->get_input_name(i).c_str(),
- (size_t)m_runner->get_input_size(i));
- }
- for (int i = 0; i < m_output_num; ++i) {
- printf(" output[%d]: %s (%zu bytes)\n", i,
- m_runner->get_output_name(i).c_str(),
- (size_t)m_runner->get_output_size(i));
- }
-
- return 0;
-}
-
-int EngineWrapper::SetInput(void* pInput, int index) {
- if (!m_hasInit || index < 0 || index >= m_input_num) return -1;
-
- uintmax_t size = m_runner->get_input_size(index);
- void* dev_ptr = m_runner->get_input_pointer(index);
-
- if (!dev_ptr || size == 0) {
- fprintf(stderr, "[ERROR] Invalid input pointer/size for index %d\n", index);
- return -1;
- }
-
- // Copy host data to device memory
- axclError ret = axclrtMemcpy(dev_ptr, pInput, size, AXCL_MEMCPY_HOST_TO_DEVICE);
- if (ret != 0) {
- fprintf(stderr, "[ERROR] axclrtMemcpy H2D failed for input %d: 0x%x\n", index, ret);
- return -1;
- }
-
- return 0;
-}
-
-int EngineWrapper::RunSync() {
- if (!m_hasInit) return -1;
-
- if (!m_runner->run(false)) {
- fprintf(stderr, "[ERROR] AXCL runner run failed\n");
- return -1;
- }
-
- return 0;
-}
-
-int EngineWrapper::GetOutput(void* pOutput, int index) {
- if (!m_hasInit || index < 0 || index >= m_output_num) return -1;
-
- uintmax_t size = m_runner->get_output_size(index);
- void* dev_ptr = m_runner->get_output_pointer(index);
-
- if (!dev_ptr || size == 0) {
- fprintf(stderr, "[ERROR] Invalid output pointer/size for index %d\n", index);
- return -1;
- }
-
- // Copy device data to host memory
- axclError ret = axclrtMemcpy(pOutput, dev_ptr, size, AXCL_MEMCPY_DEVICE_TO_HOST);
- if (ret != 0) {
- fprintf(stderr, "[ERROR] axclrtMemcpy D2H failed for output %d: 0x%x\n", index, ret);
- return -1;
- }
-
- return 0;
-}
-
-int EngineWrapper::SetInputByName(const char* name, void* pInput) {
- auto it = m_input_name_to_idx.find(std::string(name));
- if (it == m_input_name_to_idx.end()) {
- fprintf(stderr, "[ERROR] Input '%s' not found in model\n", name);
- return -1;
- }
- return SetInput(pInput, it->second);
-}
-
-int EngineWrapper::GetOutputByName(const char* name, void* pOutput) {
- auto it = m_output_name_to_idx.find(std::string(name));
- if (it == m_output_name_to_idx.end()) {
- fprintf(stderr, "[ERROR] Output '%s' not found in model\n", name);
- return -1;
- }
- return GetOutput(pOutput, it->second);
-}
-
-int EngineWrapper::GetInputSize(int index) {
- if (!m_hasInit || index < 0 || index >= m_input_num) return -1;
- return static_cast(m_runner->get_input_size(index));
-}
-
-int EngineWrapper::GetOutputSize(int index) {
- if (!m_hasInit || index < 0 || index >= m_output_num) return -1;
- return static_cast(m_runner->get_output_size(index));
-}
-
-int EngineWrapper::GetInputSizeByName(const char* name) {
- int idx = GetInputIndex(name);
- if (idx < 0) return -1;
- return GetInputSize(idx);
-}
-
-int EngineWrapper::GetOutputSizeByName(const char* name) {
- int idx = GetOutputIndex(name);
- if (idx < 0) return -1;
- return GetOutputSize(idx);
-}
-
-int EngineWrapper::GetInputIndex(const char* name) {
- auto it = m_input_name_to_idx.find(std::string(name));
- return (it != m_input_name_to_idx.end()) ? it->second : -1;
-}
-
-int EngineWrapper::GetOutputIndex(const char* name) {
- auto it = m_output_name_to_idx.find(std::string(name));
- return (it != m_output_name_to_idx.end()) ? it->second : -1;
-}
-
-int EngineWrapper::Release() {
- if (m_runner) {
- m_runner->final();
- m_runner.reset();
- }
- m_hasInit = false;
- m_input_name_to_idx.clear();
- m_output_name_to_idx.clear();
- m_input_num = 0;
- m_output_num = 0;
- return 0;
-}
-
-const char* EngineWrapper::GetInputName(int index) const {
- static thread_local std::string cached_name;
- if (!m_hasInit || index < 0 || index >= m_input_num) return nullptr;
- cached_name = m_runner->get_input_name(index);
- return cached_name.c_str();
-}
-
-const char* EngineWrapper::GetOutputName(int index) const {
- static thread_local std::string cached_name;
- if (!m_hasInit || index < 0 || index >= m_output_num) return nullptr;
- cached_name = m_runner->get_output_name(index);
- return cached_name.c_str();
-}
diff --git a/cpp/src/EngineWrapper_axera.cpp b/cpp/src/EngineWrapper_axera.cpp
deleted file mode 100644
index 0a4c24c297ad0527055c46d91f52cbe074fb4062..0000000000000000000000000000000000000000
--- a/cpp/src/EngineWrapper_axera.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-/**************************************************************************************************
- * ZipVoice AXERA C++ Port
- *
- * EngineWrapper implementation
- **************************************************************************************************/
-
-#include "EngineWrapper.hpp"
-#include "utils/io.hpp"
-
-#include
-
-#if !defined(AX630C)
-static const char *strAlgoModelType[AX_ENGINE_MODEL_TYPE_BUTT] = {"3.6T", "7.2T", "10.8T"};
-#endif
-
-// NPU type enum
-typedef enum axNPU_TYPE_E {
- AX_NPU_DEFAULT = 0,
- AX_STD_VNPU_1 = (1 << 0),
- AX_STD_VNPU_2 = (1 << 1),
- AX_STD_VNPU_3 = (1 << 2),
- AX_BL_VNPU_1 = (1 << 3),
- AX_BL_VNPU_2 = (1 << 4)
-} AX_NPU_TYPE_E;
-
-#if !defined(AX630C)
-static AX_S32 CheckModelVNpu(const std::string &strModel,
- const AX_ENGINE_MODEL_TYPE_T &eModelType,
- const AX_S32 &nNpuType, AX_U32 &nNpuSet) {
- AX_ENGINE_NPU_ATTR_T stNpuAttr;
- memset(&stNpuAttr, 0x00, sizeof(stNpuAttr));
-
- auto ret = AX_ENGINE_GetVNPUAttr(&stNpuAttr);
- if (ret == 0) {
- if (stNpuAttr.eHardMode == AX_ENGINE_VIRTUAL_NPU_DISABLE) {
- nNpuSet = 0x01;
- } else if (stNpuAttr.eHardMode == AX_ENGINE_VIRTUAL_NPU_STD) {
- if (eModelType == AX_ENGINE_MODEL_TYPE1 || eModelType == AX_ENGINE_MODEL_TYPE2)
- return -1;
- if (nNpuType == 0) nNpuSet = 0x02;
- else {
- if (nNpuType & AX_STD_VNPU_1) nNpuSet |= 0x01;
- if (nNpuType & AX_STD_VNPU_2) nNpuSet |= 0x02;
- if (nNpuType & AX_STD_VNPU_3) nNpuSet |= 0x04;
- }
- } else if (stNpuAttr.eHardMode == AX_ENGINE_VIRTUAL_NPU_BIG_LITTLE) {
- if (eModelType == AX_ENGINE_MODEL_TYPE2) return -1;
- if (nNpuType == 0) {
- nNpuSet = (eModelType == AX_ENGINE_MODEL_TYPE1) ? 0x01 : 0x02;
- } else {
- if (eModelType == AX_ENGINE_MODEL_TYPE1) {
- if (nNpuType & AX_BL_VNPU_2) return -1;
- if (nNpuType & AX_BL_VNPU_1) nNpuSet |= 0x01;
- } else {
- if (nNpuType & AX_BL_VNPU_1) nNpuSet |= 0x01;
- if (nNpuType & AX_BL_VNPU_2) nNpuSet |= 0x02;
- }
- }
- }
- }
- return ret;
-}
-#endif
-
-EngineWrapper::EngineWrapper()
- : m_hasInit(false), m_handle(nullptr), m_io_info(nullptr),
- m_input_num(0), m_output_num(0) {
- memset(&m_io, 0, sizeof(m_io));
-}
-
-EngineWrapper::~EngineWrapper() {
- Release();
-}
-
-int EngineWrapper::Init(const char* strModelPath, uint32_t nNpuType, const char* axclConfig) {
- (void)axclConfig; // unused on AXERA
- // 1. Load model
- AX_BOOL bLoadModelUseCmm = AX_TRUE;
- AX_CHAR *pModelBufferVirAddr = nullptr;
- AX_U64 u64ModelBufferPhyAddr = 0;
- AX_U32 nModelBufferSize = 0;
-
- if (bLoadModelUseCmm) {
- if (!utils::read_file(strModelPath, (AX_VOID **)&pModelBufferVirAddr,
- u64ModelBufferPhyAddr, nModelBufferSize)) {
- printf("Read model(%s) fail\n", strModelPath);
- return -1;
- }
- } else {
- std::vector model_buffer;
- if (!utils::read_file(strModelPath, model_buffer)) {
- printf("Read model(%s) fail\n", strModelPath);
- return -1;
- }
- pModelBufferVirAddr = model_buffer.data();
- nModelBufferSize = model_buffer.size();
- }
-
- auto freeModelBuffer = [&]() {
- if (bLoadModelUseCmm) {
- if (u64ModelBufferPhyAddr != 0)
- AX_SYS_MemFree(u64ModelBufferPhyAddr, &pModelBufferVirAddr);
- }
- };
-
- // 1.1 Get Model Type & Check VNPU (AX650 only)
-#if !defined(AX630C)
- AX_ENGINE_MODEL_TYPE_T eModelType = AX_ENGINE_MODEL_TYPE0;
- AX_S32 ret = AX_ENGINE_GetModelType(pModelBufferVirAddr, nModelBufferSize, &eModelType);
- if (0 != ret || eModelType >= AX_ENGINE_MODEL_TYPE_BUTT) {
- printf("%s AX_ENGINE_GetModelType fail ret=%x\n", strModelPath, ret);
- freeModelBuffer();
- return -1;
- }
-
- AX_U32 nNpuSet = 0;
- ret = CheckModelVNpu(strModelPath, eModelType, nNpuType, nNpuSet);
- if (0 != ret) {
- printf("CheckModelVNpu fail\n");
- freeModelBuffer();
- return -1;
- }
-#endif
-#if defined(AX630C)
- AX_S32 ret = 0;
-#endif
-
- // 2. Create handle
- AX_ENGINE_HANDLE handle = nullptr;
- ret = AX_ENGINE_CreateHandle(&handle, pModelBufferVirAddr, nModelBufferSize);
- freeModelBuffer();
-
- auto deinit_handle = [&handle]() {
- if (handle) { AX_ENGINE_DestroyHandle(handle); }
- return -1;
- };
-
- if (0 != ret || !handle) {
- printf("Create model(%s) handle fail\n", strModelPath);
- return deinit_handle();
- }
-
- // 3. Create context
- ret = AX_ENGINE_CreateContext(handle);
- if (0 != ret) return deinit_handle();
-
- // 4. Get IO info
- m_io_info = nullptr;
- ret = AX_ENGINE_GetIOInfo(handle, &m_io_info);
- if (0 != ret) return deinit_handle();
-
- m_input_num = m_io_info->nInputSize;
- m_output_num = m_io_info->nOutputSize;
-
- // Build name-to-index maps
- m_input_name_to_idx.clear();
- for (int i = 0; i < m_input_num; ++i) {
- m_input_name_to_idx[std::string(m_io_info->pInputs[i].pName)] = i;
- }
- m_output_name_to_idx.clear();
- for (int i = 0; i < m_output_num; ++i) {
- m_output_name_to_idx[std::string(m_io_info->pOutputs[i].pName)] = i;
- }
-
- // 5. Prepare IO buffers
- ret = utils::prepare_io("enc", m_io_info, m_io, utils::IO_BUFFER_STRATEGY_DEFAULT);
- if (0 != ret) {
- printf("prepare io failed!\n");
- utils::free_io(m_io);
- return deinit_handle();
- }
-
- m_handle = handle;
- m_hasInit = true;
- return 0;
-}
-
-int EngineWrapper::SetInput(void* pInput, int index) {
- if (!m_hasInit || index < 0 || index >= m_input_num) return -1;
- return utils::push_io_input(pInput, index, m_io);
-}
-
-int EngineWrapper::RunSync() {
- if (!m_hasInit) return -1;
- auto ret = AX_ENGINE_RunSync(m_handle, &m_io);
- if (0 != ret) {
- printf("AX_ENGINE_RunSync failed. ret=0x%x\n", ret);
- }
- return ret;
-}
-
-int EngineWrapper::GetOutput(void* pOutput, int index) {
- if (!m_hasInit || index < 0 || index >= m_output_num) return -1;
- return utils::push_io_output(pOutput, index, m_io);
-}
-
-int EngineWrapper::SetInputByName(const char* name, void* pInput) {
- auto it = m_input_name_to_idx.find(std::string(name));
- if (it == m_input_name_to_idx.end()) {
- printf("Input '%s' not found in model\n", name);
- return -1;
- }
- return SetInput(pInput, it->second);
-}
-
-int EngineWrapper::GetOutputByName(const char* name, void* pOutput) {
- auto it = m_output_name_to_idx.find(std::string(name));
- if (it == m_output_name_to_idx.end()) {
- printf("Output '%s' not found in model\n", name);
- return -1;
- }
- return GetOutput(pOutput, it->second);
-}
-
-int EngineWrapper::GetInputSize(int index) {
- if (index < 0 || index >= m_input_num) return -1;
- return m_io.pInputs[index].nSize;
-}
-
-int EngineWrapper::GetOutputSize(int index) {
- if (index < 0 || index >= m_output_num) return -1;
- return m_io.pOutputs[index].nSize;
-}
-
-int EngineWrapper::GetInputSizeByName(const char* name) {
- int idx = GetInputIndex(name);
- if (idx < 0) return -1;
- return GetInputSize(idx);
-}
-
-int EngineWrapper::GetOutputSizeByName(const char* name) {
- int idx = GetOutputIndex(name);
- if (idx < 0) return -1;
- return GetOutputSize(idx);
-}
-
-int EngineWrapper::GetInputIndex(const char* name) {
- auto it = m_input_name_to_idx.find(std::string(name));
- return (it != m_input_name_to_idx.end()) ? it->second : -1;
-}
-
-int EngineWrapper::GetOutputIndex(const char* name) {
- auto it = m_output_name_to_idx.find(std::string(name));
- return (it != m_output_name_to_idx.end()) ? it->second : -1;
-}
-
-const char* EngineWrapper::GetInputName(int index) const {
- if (index < 0 || index >= m_input_num) return nullptr;
- return m_io_info->pInputs[index].pName;
-}
-
-const char* EngineWrapper::GetOutputName(int index) const {
- if (index < 0 || index >= m_output_num) return nullptr;
- return m_io_info->pOutputs[index].pName;
-}
-
-static const char* dtype_str(AX_ENGINE_DATA_TYPE_T t) {
- switch (t) {
- case AX_ENGINE_DT_FLOAT32: return "float32";
- case AX_ENGINE_DT_FLOAT64: return "float64";
- case AX_ENGINE_DT_SINT8: return "sint8";
- case AX_ENGINE_DT_UINT8: return "uint8";
- case AX_ENGINE_DT_SINT16: return "sint16";
- case AX_ENGINE_DT_UINT16: return "uint16";
- case AX_ENGINE_DT_SINT32: return "sint32";
- case AX_ENGINE_DT_UINT32: return "uint32";
- default: return "unknown";
- }
-}
-
-const char* EngineWrapper::GetInputDtypeStr(int index) const {
- if (index < 0 || index >= m_input_num) return "?";
- return dtype_str(m_io_info->pInputs[index].eDataType);
-}
-
-const char* EngineWrapper::GetOutputDtypeStr(int index) const {
- if (index < 0 || index >= m_output_num) return "?";
- return dtype_str(m_io_info->pOutputs[index].eDataType);
-}
-
-int EngineWrapper::Release() {
- if (m_handle) {
- utils::free_io(m_io);
- AX_ENGINE_DestroyHandle(m_handle);
- m_handle = nullptr;
- }
- m_hasInit = false;
- m_input_name_to_idx.clear();
- m_output_name_to_idx.clear();
- return 0;
-}
diff --git a/cpp/src/cmdline.hpp b/cpp/src/cmdline.hpp
deleted file mode 100644
index ca0139ad105131ad333a205355bdc2e2501d9d72..0000000000000000000000000000000000000000
--- a/cpp/src/cmdline.hpp
+++ /dev/null
@@ -1,732 +0,0 @@
-/*
- Copyright (c) 2009, Hideyuki Tanaka
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY ''AS IS'' AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#pragma once
-
-#include
-
-#include
-#include
-#include
-#include
-#include