inoryQwQ commited on
Commit
f722fb4
·
verified ·
1 Parent(s): 819e690

merge AX650 + AX620E(SenseVoice 风格双芯布局)

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +0 -1
  2. NPU_ONLY_SDK.md +3 -1
  3. README.md +50 -41
  4. config.json +1 -1
  5. cpp/ax620e/CMakeLists.txt +37 -0
  6. cpp/ax620e/README.md +29 -0
  7. cpp/ax620e/examples/main.cpp +58 -0
  8. cpp/{include → ax620e/include}/model_runner.hpp +0 -0
  9. cpp/ax620e/include/rnnoise_ax.hpp +26 -0
  10. cpp/{src → ax620e/src}/model_runner.cpp +0 -0
  11. cpp/{src → ax620e/src}/rnnoise/_kiss_fft_guts.h +0 -0
  12. cpp/{src → ax620e/src}/rnnoise/arch.h +0 -0
  13. cpp/{src → ax620e/src}/rnnoise/celt_lpc.c +0 -0
  14. cpp/{src → ax620e/src}/rnnoise/celt_lpc.h +0 -0
  15. cpp/{src → ax620e/src}/rnnoise/common.h +0 -0
  16. cpp/{src → ax620e/src}/rnnoise/compile.sh +0 -0
  17. cpp/{src → ax620e/src}/rnnoise/cpu_support.h +0 -0
  18. cpp/{src → ax620e/src}/rnnoise/denoise.c +0 -0
  19. cpp/{src → ax620e/src}/rnnoise/denoise.h +0 -0
  20. cpp/{src → ax620e/src}/rnnoise/dump_features.c +0 -0
  21. cpp/{src → ax620e/src}/rnnoise/dump_rnnoise_tables.c +0 -0
  22. cpp/{src → ax620e/src}/rnnoise/kiss_fft.c +0 -0
  23. cpp/{src → ax620e/src}/rnnoise/kiss_fft.h +0 -0
  24. cpp/{src → ax620e/src}/rnnoise/nnet.c +0 -0
  25. cpp/{src → ax620e/src}/rnnoise/nnet.h +0 -0
  26. cpp/{src → ax620e/src}/rnnoise/nnet_arch.h +0 -0
  27. cpp/{src → ax620e/src}/rnnoise/nnet_default.c +0 -0
  28. cpp/{src → ax620e/src}/rnnoise/opus_types.h +0 -0
  29. cpp/{src → ax620e/src}/rnnoise/parse_lpcnet_weights.c +0 -0
  30. cpp/{src → ax620e/src}/rnnoise/pitch.c +0 -0
  31. cpp/{src → ax620e/src}/rnnoise/pitch.h +0 -0
  32. cpp/{src → ax620e/src}/rnnoise/rnn.c +0 -0
  33. cpp/{src → ax620e/src}/rnnoise/rnn.h +0 -0
  34. cpp/{src → ax620e/src}/rnnoise/rnn_train.py +0 -0
  35. cpp/{src → ax620e/src}/rnnoise/rnnoise.h +0 -0
  36. cpp/{src → ax620e/src}/rnnoise/rnnoise_data.c +0 -0
  37. cpp/{src → ax620e/src}/rnnoise/rnnoise_data.h +0 -0
  38. cpp/{src → ax620e/src}/rnnoise/rnnoise_tables.c +0 -0
  39. cpp/{src → ax620e/src}/rnnoise/vec.h +0 -0
  40. cpp/{src → ax620e/src}/rnnoise/vec_avx.h +0 -0
  41. cpp/{src → ax620e/src}/rnnoise/vec_neon.h +0 -0
  42. cpp/{src → ax620e/src}/rnnoise/write_weights.c +0 -0
  43. cpp/{src → ax620e/src}/rnnoise/x86/dnn_x86.h +0 -0
  44. cpp/{src → ax620e/src}/rnnoise/x86/nnet_avx2.c +0 -0
  45. cpp/{src → ax620e/src}/rnnoise/x86/nnet_sse4_1.c +0 -0
  46. cpp/{src → ax620e/src}/rnnoise/x86/x86_arch_macros.h +0 -0
  47. cpp/{src → ax620e/src}/rnnoise/x86/x86_dnn_map.c +0 -0
  48. cpp/{src → ax620e/src}/rnnoise/x86/x86cpu.c +0 -0
  49. cpp/{src → ax620e/src}/rnnoise/x86/x86cpu.h +0 -0
  50. cpp/{src → ax620e/src}/rnnoise_ax.cpp +0 -0
.gitattributes CHANGED
@@ -34,4 +34,3 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  *.axmodel filter=lfs diff=lfs merge=lfs -text
37
- python/sample_speech.pcm filter=lfs diff=lfs merge=lfs -text
 
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  *.axmodel filter=lfs diff=lfs merge=lfs -text
 
NPU_ONLY_SDK.md CHANGED
@@ -1 +1,3 @@
1
- 本交付包已通过端到端 NPU 验证,Python SDK 仅依赖 pyaxengine,不含 onnxruntime/torch/transformers 等运行时回退
 
 
 
1
+ 本交付包 rnnoise 双芯(AX650 / AX620E)合并仓库
2
+ AX650 已通过板端端到端 NPU 验证(C++ 2.91ms/帧,输出 cosine 0.9988);
3
+ AX620E 尚未上板验证(Pulsar2 仿真 gains cosine 0.9987),交付 SDK 保留 onnxruntime CPU 回退用于本机验证。
README.md CHANGED
@@ -4,62 +4,71 @@ pipeline_tag: audio-to-audio
4
  tags:
5
  - axmodel
6
  - axera
7
- - rnnoise-ax650
 
 
 
8
  ---
9
- # RNNoise AX650 实时降噪(AXMODEL 交付包)
10
 
11
- 48kHz 单声道实时降噪:原版 RNNoise 网络编译到 AX650 NPU3,前后处理 1:1 对齐
12
- 官方 C 管线。板端 C++ 每帧 2.85ms(10ms 帧预算内),输出与官方实现 cosine ≈ 0.98+;
13
- 模型 3.3MB,支持 U16 混合精度推理。
14
 
15
- ## 快速开始只需两步
 
16
 
17
- ### 1. 安装环境
18
 
19
- ```bash
20
- bash setup.sh
21
- ```
 
22
 
23
- ### 2. 跑推理(板端)
24
 
25
- ```bash
26
- bash run.sh
27
- ```
 
 
 
 
 
28
 
29
- `run.sh` 会处理自带的 1 秒演示音频(`python/sample_speech.pcm`),
30
- 输出去噪 PCM 到 `output/out.pcm`,并打印语音存在比例。
31
 
32
- ## 目录说明
33
 
34
- | 目录 | 用途 |
35
- |------|------|
36
- | `models/` | `model.axmodel`(AX650 NPU3)+ `model_meta.json` |
37
- | `python/` | Python SDK(pyaxengine,NPU 专用,仅依赖 numpy + pyaxengine)|
38
- | `cpp/` | C++ SDK(原版 C 信号处理 + AX Engine,实时路径)|
39
- | `model_convert/` | 模型导出 & 编译脚本(可复现)|
40
- | `reports/` | 导出/编译/仿真/上板报告 |
41
 
42
- ## 自己调用 SDK(核心 3
43
 
44
- ```python
45
- from rnnoise_ax650_sdk import RNNoiseDenoiser
46
- denoiser = RNNoiseDenoiser("models/model.axmodel") # 板端 pyaxengine
47
- out_frame, vad = denoiser.process_frame(pcm_frame_480) # 48k float32 帧
 
48
  ```
49
 
50
- 入帧为 16-bit PCM 等价 float±32768 量级,不做归一化,与官方 demo 一致);
51
- 模型逐帧 6 输入(features + 5 个状态)/ 7 输出gains/vad + 5 个新状态
52
- 状态由 SDK 内部维护。
 
 
 
 
 
 
53
 
54
- ## 常见问题
55
 
56
- **Q: import 报错找不到 pyaxengine?**
57
- A: 在 AX 板端运行 `bash setup.sh` 自动安装(交付版不做 CPU 回退)。
 
 
 
58
 
59
- **Q: Python 每帧要 60ms,能实时吗?**
60
- A: Python 版面向原型/离线批处理;实时降噪请用 `cpp/`(2.85ms/帧),
61
- 编译方法见 `cpp/README.md`。
62
 
63
- **Q: 想自己重新编译模型?**
64
- A: 进入 `model_convert/`,按 README 准备 Pulsar2 7.0 Docker 后运行
65
- `bash compile_pulsar2.sh`。
 
4
  tags:
5
  - axmodel
6
  - axera
7
+ - rnnoise
8
+ - audio-denoising
9
+ - ax650
10
+ - ax620e
11
  ---
 
12
 
13
+ # RNNoise(爱芯 NPU 版)
 
 
14
 
15
+ Xiph RNNoise 语音降噪在爱芯 NPU 上的部署包,支持 **AX650NPU3/ AX620E(NPU2)** 双芯。
16
+ 官方模型仓库:https://github.com/xiph/rnnoise
17
 
18
+ ## 特性
19
 
20
+ - 48kHz 单声道实时语音降噪(逐帧 10ms,16-bit 等价域 ±32768)
21
+ - 原版 rnnoise C 信号处理(特征分析 / 合成)+ AX Engine NPU 推理
22
+ - Python 与 C++ 双 SDK;官方未提供 ONNX,本仓库 ONNX 由官方 `rnnoise_data.c`
23
+ 权重 1:1 复刻导出(Tanh/Sigmoid 有理逼近对齐 C 端)
24
 
25
+ ## 支持平台与模型
26
 
27
+ | 芯片 | NPU | 模型目录 | gains cosine | 板端验证 |
28
+ |---|---|---|---|---|
29
+ | AX650 | NPU3 | `rnnoise_ax650/` | 0.9991(板端 198 帧) | ✅ C++ 2.91ms/帧,输出 cosine 0.9988 |
30
+ | AX620E | NPU2 | `rnnoise_ax620e/` | 0.9987(Pulsar2 仿真 100 帧) | 待上板 |
31
+
32
+ 每个模型目录内含 `model.axmodel` + `model_meta.json`。
33
+ 量化:U16 链路(MatMul/Conv/Add/Mul/Div/Sub/Concat/Clip/Slice,S8 权重),
34
+ MinMax,校准数据来自真实语音(speech/speech-echo/speech-reverb + 6dB 噪声)。
35
 
36
+ ## 快速开始
 
37
 
38
+ ### 1. 安装 Python 环境
39
 
40
+ ```bash
41
+ pip install -r python/requirements.txt
42
+ ```
 
 
 
 
43
 
44
+ ### 2. 板端运降噪
45
 
46
+ ```bash
47
+ # AX650
48
+ python3 python/demo.py --chip ax650
49
+ # AX620E
50
+ python3 python/demo.py --chip ax620e
51
  ```
52
 
53
+ `output/out.pcm`48k f32le+ `output/vad.npy`演示样本为
54
+ `python/sample_speech.pcm` 4 秒语音
55
+
56
+ ## C++ SDK
57
+
58
+ | 芯片 | 目录 | 说明 |
59
+ |---|---|---|
60
+ | AX650 | `cpp/ax650/` | cmake 链接 ax_engine/ax_sys,板端实测 2.91ms/帧 |
61
+ | AX620E | `cpp/ax620e/` | 同源码树,目标 AX620E BSP 交叉编译 |
62
 
63
+ ## 精度说明
64
 
65
+ | 张量 | AX650 板端 cosine | AX620E 仿真 cosine |
66
+ |---|---|---|
67
+ | gains | 0.9991 | 0.9987 |
68
+ | vad | 0.99996 | 0.99997 |
69
+ | GRU 状态 | 0.992–0.996 | 0.996+ |
70
 
71
+ ## 复现
 
 
72
 
73
+ 完整导出与编译流程(含双芯 Pulsar2 配置与校准数据)见
74
+ GitHub:https://github.com/ml-inory/rnnoise.axera
 
config.json CHANGED
@@ -1 +1 @@
1
- {}
 
1
+ {}
cpp/ax620e/CMakeLists.txt ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required(VERSION 3.15)
2
+ project(rnnoise_ax620e_sdk LANGUAGES CXX C)
3
+
4
+ set(CMAKE_CXX_STANDARD 14)
5
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
+
7
+ include_directories(include src/rnnoise)
8
+
9
+ # 原版 rnnoise 信号处理(denoise/pitch/FFT/LPC/表格)。
10
+ # 注意:不编译 rnn.c(其 compute_rnn 由 src/rnnoise_ax.cpp 用 AX Engine 替换)。
11
+ add_library(rnnoise_c STATIC
12
+ src/rnnoise/denoise.c
13
+ src/rnnoise/pitch.c
14
+ src/rnnoise/kiss_fft.c
15
+ src/rnnoise/celt_lpc.c
16
+ src/rnnoise/nnet.c
17
+ src/rnnoise/nnet_default.c
18
+ src/rnnoise/parse_lpcnet_weights.c
19
+ src/rnnoise/rnnoise_data.c
20
+ src/rnnoise/rnnoise_tables.c
21
+ )
22
+
23
+ add_library(rnnoise_ax620e_sdk STATIC
24
+ src/model_runner.cpp
25
+ src/rnnoise_ax.cpp
26
+ )
27
+ target_include_directories(rnnoise_ax620e_sdk PUBLIC include)
28
+ target_link_libraries(rnnoise_ax620e_sdk PRIVATE rnnoise_c)
29
+
30
+ add_executable(model_example examples/main.cpp)
31
+ target_link_libraries(model_example PRIVATE rnnoise_ax620e_sdk)
32
+
33
+ if(AX_RUNTIME_ROOT)
34
+ target_include_directories(rnnoise_ax620e_sdk PUBLIC ${AX_RUNTIME_ROOT}/include)
35
+ target_link_directories(rnnoise_ax620e_sdk PUBLIC ${AX_RUNTIME_ROOT}/lib)
36
+ target_link_libraries(rnnoise_ax620e_sdk PUBLIC ax_engine ax_sys pthread dl atomic)
37
+ endif()
cpp/ax620e/README.md ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # rnnoise-ax620e C++ SDK
2
+
3
+ 48kHz 单声道实时降噪,RNNoise 原版 C 信号处理 + AX Engine(NPU3)网络推理。
4
+
5
+ ## 编译(AX620E 板端/交叉环境)
6
+
7
+ ```bash
8
+ export AX_RUNTIME_ROOT=/path/to/axruntime # 含 include/ax_engine_api.h 与 lib/libax_engine.so
9
+ mkdir -p build && cd build
10
+ cmake .. -DAX_RUNTIME_ROOT=$AX_RUNTIME_ROOT
11
+ make -j$(nproc)
12
+ ```
13
+
14
+ ## 运行
15
+
16
+ ```bash
17
+ ./build/model_example model.axmodel in.pcm out.pcm
18
+ ```
19
+
20
+ 输入为 48kHz f32le PCM(16-bit 等价域 ±32768,不做归一化);
21
+ 输出为同格式去噪 PCM。每帧 480 采样(10ms),vad 打印均值。
22
+
23
+ ## 结构
24
+
25
+ - `include/rnnoise_ax.hpp`:`RNNoiseAX` 类(进程内单实例)
26
+ - `src/rnnoise_ax.cpp`:以 AX Engine 替换原版 `compute_rnn`(6 输入/7 输出逐帧状态化)
27
+ - `src/model_runner.cpp`:AX Engine 会话封装(按张量名映射,含缓存同步)
28
+ - `src/rnnoise/`:原版 rnnoise C 信号处理源码(denoise/pitch/FFT/LPC/表格,ISC 许可);
29
+ 网络权重已内嵌 AXMODEL,`rnnoise_data.c` 为最小 stub(空权重表 + 零初始化)
cpp/ax620e/examples/main.cpp ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // RNNoise AX620E 示例:处理 48k f32 PCM(16-bit 等价域),输出去噪 PCM。
2
+ // 用法: ./model_example model.axmodel in.pcm out.pcm
3
+ #include "rnnoise_ax.hpp"
4
+
5
+ #include <cstdio>
6
+ #include <cstdlib>
7
+ #include <chrono>
8
+ #include <vector>
9
+
10
+ int main(int argc, char** argv) {
11
+ if (argc != 4) {
12
+ std::fprintf(stderr, "用法: %s model.axmodel in.pcm out.pcm\n", argv[0]);
13
+ return 1;
14
+ }
15
+ FILE* in = std::fopen(argv[2], "rb");
16
+ if (!in) {
17
+ std::fprintf(stderr, "无法打开输入 %s\n", argv[2]);
18
+ return 1;
19
+ }
20
+ std::fseek(in, 0, SEEK_END);
21
+ long bytes = std::ftell(in);
22
+ std::fseek(in, 0, SEEK_SET);
23
+ std::vector<float> pcm(bytes / sizeof(float));
24
+ if (!pcm.empty()) {
25
+ std::fread(pcm.data(), sizeof(float), pcm.size(), in);
26
+ }
27
+ std::fclose(in);
28
+
29
+ const int frame = RNNoiseAX::FrameSize();
30
+ const int frames = static_cast<int>(pcm.size() / frame);
31
+ if (frames == 0) {
32
+ std::fprintf(stderr, "输入过短\n");
33
+ return 1;
34
+ }
35
+
36
+ RNNoiseAX denoiser(argv[1]);
37
+ std::vector<float> out(pcm.size());
38
+ double vad_sum = 0.0;
39
+ auto t0 = std::chrono::steady_clock::now();
40
+ for (int i = 0; i < frames; ++i) {
41
+ vad_sum += denoiser.ProcessFrame(
42
+ &out[i * frame], &pcm[i * frame]);
43
+ }
44
+ auto t1 = std::chrono::steady_clock::now();
45
+ double secs = std::chrono::duration<double>(t1 - t0).count();
46
+
47
+ FILE* of = std::fopen(argv[3], "wb");
48
+ if (!of) {
49
+ std::fprintf(stderr, "无法写入输出 %s\n", argv[3]);
50
+ return 1;
51
+ }
52
+ std::fwrite(out.data(), sizeof(float), out.size(), of);
53
+ std::fclose(of);
54
+
55
+ std::printf("frames=%d vad_mean=%.4f per_frame_ms=%.3f out=%s\n",
56
+ frames, vad_sum / frames, secs / frames * 1000.0, argv[3]);
57
+ return 0;
58
+ }
cpp/{include → ax620e/include}/model_runner.hpp RENAMED
File without changes
cpp/ax620e/include/rnnoise_ax.hpp ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #pragma once
2
+
3
+ #include <memory>
4
+ #include <string>
5
+
6
+ // RNNoise AX620E 实时降噪器:原版 rnnoise C 信号处理 + AX Engine 网络推理。
7
+ class RNNoiseAX {
8
+ public:
9
+ explicit RNNoiseAX(const std::string& model_path);
10
+ ~RNNoiseAX();
11
+
12
+ RNNoiseAX(const RNNoiseAX&) = delete;
13
+ RNNoiseAX& operator=(const RNNoiseAX&) = delete;
14
+
15
+ static int FrameSize() { return 480; }
16
+
17
+ void Reset();
18
+
19
+ // 处理一帧 48k PCM(16-bit 等价 float,±32768 域)。
20
+ // in/out 各至少 FrameSize() 个 float;返回 vad(0~1)。
21
+ float ProcessFrame(float* out, const float* in);
22
+
23
+ private:
24
+ struct Impl;
25
+ std::unique_ptr<Impl> impl_;
26
+ };
cpp/{src → ax620e/src}/model_runner.cpp RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/_kiss_fft_guts.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/arch.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/celt_lpc.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/celt_lpc.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/common.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/compile.sh RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/cpu_support.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/denoise.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/denoise.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/dump_features.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/dump_rnnoise_tables.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/kiss_fft.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/kiss_fft.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/nnet.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/nnet.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/nnet_arch.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/nnet_default.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/opus_types.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/parse_lpcnet_weights.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/pitch.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/pitch.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/rnn.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/rnn.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/rnn_train.py RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/rnnoise.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/rnnoise_data.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/rnnoise_data.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/rnnoise_tables.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/vec.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/vec_avx.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/vec_neon.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/write_weights.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/x86/dnn_x86.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/x86/nnet_avx2.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/x86/nnet_sse4_1.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/x86/x86_arch_macros.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/x86/x86_dnn_map.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/x86/x86cpu.c RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise/x86/x86cpu.h RENAMED
File without changes
cpp/{src → ax620e/src}/rnnoise_ax.cpp RENAMED
File without changes