claroche1 commited on
Commit
4fe3356
·
verified ·
1 Parent(s): eb0c70a

conv-hardened: add frame-by-frame streaming graphs (fp32 + signed int8, 17 FIFO states); document both NPU deploy paths (windowed 1.15 ms/frame PESQ 2.998; streaming 16 ms hop PESQ 2.982)

Browse files
README.md CHANGED
@@ -52,7 +52,8 @@ has (topology verified on Neural-ART).
52
  `feat_window (B,3,132,257) -> est_mag (B,64,257)`, window = receptive field
53
  68 + 64 emitted frames) that **compiles to Neural-ART** — the artifact handed
54
  to stedgeai. The hardened primitives also quantize far better (int8 drop
55
- −0.016 vs −0.115 for `conv/`).
 
56
  * **`conv-hardened-deep/`** is the **best model overall**: the hardened recipe,
57
  deeper (3 blocks) with an extra dilation stage (receptive field 196 frames ≈
58
  3.1 s) and **ReLU6** activations (bounded ranges quantize better; exports as
@@ -62,6 +63,33 @@ has (topology verified on Neural-ART).
62
  (int8 except the decoder's QDQ nodes, PESQ **3.052** — the int8 loss is
63
  decoder-localized; the decoder then runs as float epochs on the board).
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  Code + full write-up: [https://github.com/LarocheC/eco8-neaixt](https://github.com/LarocheC/eco8-neaixt) — see
66
  [RESULTS_LISENNET.md](https://github.com/LarocheC/eco8-neaixt/blob/main/RESULTS_LISENNET.md).
67
 
@@ -71,10 +99,12 @@ Code + full write-up: [https://github.com/LarocheC/eco8-neaixt](https://github.c
71
  and `g_best_int8_static.onnx` (whole-utterance mask sub-network,
72
  `feat (B,3,T,F) -> est_mag (B,T,F)`). `conv/` additionally has
73
  `g_best_streaming_fp32.onnx` and `g_best_streaming_int8_static.onnx` (single
74
- frame + explicit state I/O); `conv-hardened/` has `g_best_windowed_fp32.onnx`
75
- and `g_best_windowed_int8_static.onnx` (stateless windowed deploy graph, the
76
- stedgeai / Neural-ART target). The ONNX graphs are the mask sub-network only —
77
- STFT, feature build and phase recovery stay host-side.
 
 
78
 
79
  ## Loading (PyTorch)
80
 
@@ -108,14 +138,19 @@ feat_window = np.zeros((1, 3, 132, 257), np.float32) # last 68+64 feature fram
108
  est_mag = sess.run(["est_mag"], {"feat_window": feat_window})[0] # (1, 64, 257)
109
  ```
110
 
111
- ## Running the CPU streaming graph frame-by-frame (`conv/`)
 
 
 
 
 
112
 
113
  ```python
114
  import numpy as np, onnxruntime as ort
115
  from huggingface_hub import hf_hub_download
116
 
117
  sess = ort.InferenceSession(
118
- hf_hub_download("claroche1/LiSenNet", "conv/g_best_streaming_fp32.onnx"),
119
  providers=["CPUExecutionProvider"],
120
  )
121
  state_in = [i for i in sess.get_inputs() if i.name != "feat"] # FIFO states
 
52
  `feat_window (B,3,132,257) -> est_mag (B,64,257)`, window = receptive field
53
  68 + 64 emitted frames) that **compiles to Neural-ART** — the artifact handed
54
  to stedgeai. The hardened primitives also quantize far better (int8 drop
55
+ −0.016 vs −0.115 for `conv/`). It also ships a **frame-by-frame streaming**
56
+ graph — see below.
57
  * **`conv-hardened-deep/`** is the **best model overall**: the hardened recipe,
58
  deeper (3 blocks) with an extra dilation stage (receptive field 196 frames ≈
59
  3.1 s) and **ReLU6** activations (bounded ranges quantize better; exports as
 
63
  (int8 except the decoder's QDQ nodes, PESQ **3.052** — the int8 loss is
64
  decoder-localized; the decoder then runs as float epochs on the board).
65
 
66
+ ## Two deploy paths (`conv-hardened/`) — throughput vs latency
67
+
68
+ The hardened variant ships **both** NPU-deployable graphs. They are the same
69
+ trained weights; they differ only in how much audio each inference call consumes.
70
+ Both are measured on an STM32N6570-DK (STM32N657, MCU 800 MHz / NPU 1 GHz,
71
+ stedgeai 4.0.1); PESQ is the full 824-utterance VBD test split, int8 + noisy
72
+ phase.
73
+
74
+ | graph | shape | algorithmic latency | latency/frame | RTF | PESQ |
75
+ | ----- | ----- | ------------------- | ------------: | --: | ---: |
76
+ | `g_best_windowed_int8_static.onnx` | `feat_window (B,3,132,257) -> est_mag (B,64,257)` | 1.02 s block | **1.15 ms** | 0.072 | **2.998** |
77
+ | `g_best_streaming_int8_static.onnx` | `feat (B,3,1,257) + 17 states -> est_mag (B,1,257) + 17 states` | **one 16 ms hop** | 2.79 ms | 0.174 | **2.982** |
78
+
79
+ * the **windowed** graph is stateless and the throughput champion (1.15 ms per
80
+ emitted frame), but buffers 1.02 s of audio per call — use it when block
81
+ latency is acceptable;
82
+ * the **streaming** graph is true frame-by-frame — one 16 ms hop in, one enhanced
83
+ frame out, with 17 bounded FIFO state tensors carried on-device (47 KiB weights
84
+ + 147 KiB activations, entirely on-chip). It costs ~2.4× more compute per frame
85
+ but drops algorithmic latency by ~64×, which makes it the best-quality
86
+ *streaming* speech enhancer measured on this NPU.
87
+
88
+ Both are signed QInt8 (the Neural-ART recipe). The streaming graph is calibrated
89
+ by threading the real FIFO state through the trained model, so the state tensors
90
+ see realistic ranges; its int8 cost is −0.018 PESQ vs the same-protocol FP32
91
+ streaming reference (3.000).
92
+
93
  Code + full write-up: [https://github.com/LarocheC/eco8-neaixt](https://github.com/LarocheC/eco8-neaixt) — see
94
  [RESULTS_LISENNET.md](https://github.com/LarocheC/eco8-neaixt/blob/main/RESULTS_LISENNET.md).
95
 
 
99
  and `g_best_int8_static.onnx` (whole-utterance mask sub-network,
100
  `feat (B,3,T,F) -> est_mag (B,T,F)`). `conv/` additionally has
101
  `g_best_streaming_fp32.onnx` and `g_best_streaming_int8_static.onnx` (single
102
+ frame + explicit state I/O — CPU/onnxruntime reference only; this variant's
103
+ streaming graph does not compile to Neural-ART). `conv-hardened/` has **both**
104
+ NPU deploy graphs: `g_best_windowed_{fp32,int8_static}.onnx` (stateless windowed)
105
+ and `g_best_streaming_{fp32,int8_static}.onnx` (frame-by-frame, 17 FIFO states) —
106
+ see the two-deploy-paths table above. The ONNX graphs are the mask sub-network
107
+ only — STFT, feature build and phase recovery stay host-side.
108
 
109
  ## Loading (PyTorch)
110
 
 
138
  est_mag = sess.run(["est_mag"], {"feat_window": feat_window})[0] # (1, 64, 257)
139
  ```
140
 
141
+ ## Running the streaming graph frame-by-frame (`conv-hardened/`, `conv/`)
142
+
143
+ One 16 ms hop in, one enhanced frame out; the FIFO state tensors are threaded
144
+ from each call's outputs into the next call's inputs (start-of-stream = zeros).
145
+ Point it at `conv-hardened/` for the NPU-deployable graph (PESQ 2.982), or
146
+ `conv/` for the CPU-only reference.
147
 
148
  ```python
149
  import numpy as np, onnxruntime as ort
150
  from huggingface_hub import hf_hub_download
151
 
152
  sess = ort.InferenceSession(
153
+ hf_hub_download("claroche1/LiSenNet", "conv-hardened/g_best_streaming_int8_static.onnx"),
154
  providers=["CPUExecutionProvider"],
155
  )
156
  state_in = [i for i in sess.get_inputs() if i.name != "feat"] # FIFO states
conv-hardened/g_best_streaming_fp32.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a3e6ab2cf828f5f7f65d1b1e3f74ba9f8a19751152af114c620a3db83a5b55de
3
+ size 261749
conv-hardened/g_best_streaming_int8_static.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:10abffb4c1b00b8ee4de2ceb03dbcbbbd5a149dd27bb6e4adec96b668d017b55
3
+ size 363756