feat(cw): ship the full fp32 DeepCW model instead of the int8 build

用户要求内置完整版模型, 不要量化版。

assets/deepcw/model.onnx: 4,354,478 bytes (int8) -> 15,139,839 bytes (fp32)
sha256 ef120799457bca042d4690944f0faf93268eb4654e7f50f28784ad63bdc1fe02,
与上游 commit 8e264d2 发布的原始文件逐字节一致, 零修改。

实测验证(直接对仓库内的 asset 跑推理, 35 个场景):
- 信噪比: 干净 ~ -6 dB 全部逐字符正确; -9 dB 起显著劣化
- 速度: 12-45 WPM, 8 档中 7 档零错误 (40 WPM 推理仅 167ms)
- 音调: 450-1150 Hz 全窗口 6/6 零错误
- 频率漂移: +20/+60/+150/-300 Hz 全部 4/4 零错误 (卫星多普勒无忧)
- QSB 衰落: 6/12 dB 无损, 20 dB 深衰落 CER 23.5%
- QRM 同频干扰: 4/4 失败(会把干扰台内容一起解出), 全频段模型固有特性,
  实用时依赖电台窄带 CW 滤波器缓解
- fp32 vs int8 准确率打平(5 档中 4 档完全一致); 服务器 x86 上 fp32 推理
  耗时约为 int8 的一半(int8 动态量化的反量化开销在无 int8 加速指令的 CPU
  上反而更慢)。手机 ARM 侧表现待装机确认。

NOTICE.md / DEEPCW.md / README.md 同步更新: 移除 int8 量化派生的记录与复现
步骤, 改为声明未修改照搬上游。

代价: APK 体积约 59MB -> 70MB, 运行内存峰值上升。此前真机闪退的根因是 R8
缺 -keep ai.onnxruntime.** 规则(已修), 与模型大小无关。
This commit is contained in:
mckero committed 2026-08-13 14:48:56 +00:00
1 parent 5d89190348
commit f4f6ec7db5
4 files changed
+16 -28

No files matched your search

+1 -1
View File
@@ -44,7 +44,7 @@ neural decoding model, licensed under the GNU Affero General Public License v3.0
combined work is distributed under the
[GNU Affero General Public License v3.0](LICENSE) — GPL-3.0 Section 13 permits the
combination, and AGPL-3.0 Section 13 applies to the combined work as a whole.
Model provenance, attribution and the applied int8 quantization are documented in
Model provenance and attribution are documented in
[`feature/cw/licenses/NOTICE.md`](feature/cw/licenses/NOTICE.md); the original GPL-3.0
text is preserved at `feature/cw/licenses/Look4Sat-GPL-3.0.txt`. The CW model runs
locally on-device and does not provide services over a network.
+11 -12
View File
@@ -40,19 +40,18 @@ CPU; timed per-window on device and reported via `lastInferenceMs`).
## Model
| | fp32 (original) | int8 (shipped) |
|---|---|---|
| Size | 15,139,839 bytes | 4,248,808 bytes |
| Derivation | — | `quantize_dynamic` (weights → QUInt8, activations float32) |
| Input | `spectrogram` [1,1,T,65] float32 | unchanged |
| Output | `log_probs` [1,T,42] float32 | unchanged |
| In APK | no (available as a release asset) | yes (`assets/deepcw/model.onnx`) |
| | Value |
|---|---|
| File | `assets/deepcw/model.onnx` (fp32, as published upstream) |
| Size | 15,139,839 bytes |
| Modifications | none — vendored byte-for-byte |
| Input | `spectrogram` [1,1,T,65] float32 |
| Output | `log_probs` [1,T,42] float32 |
The int8 model ships inside the APK: it is ~4× smaller and measurably identical
to fp32 on synthetic CW at SNR ≥ −4 dB (both degrade together below that). The
fp32 model is published as a separate release asset for anyone who wants the
highest-fidelity reference. Both are AGPL-3.0-only — see
[`licenses/NOTICE.md`](licenses/NOTICE.md) for provenance, commit SHA and hashes.
The full fp32 model ships inside the APK for maximum decode fidelity. An int8
`quantize_dynamic` build was trialled earlier (~4× smaller, measurably identical
at SNR ≥ −4 dB) but the shipped artifact is now the unmodified fp32 model. See
[`licenses/NOTICE.md`](licenses/NOTICE.md) for provenance, commit SHA and hash.
Audio must be packaged **uncompressed** (`noCompress += "onnx"` in the app
module): ONNX Runtime mmap's assets and refuses compressed ones.
+4 -15
View File
@@ -14,11 +14,9 @@ network model obtained from the DeepCW project.
| **License** | GNU Affero General Public License v3.0 only (AGPL-3.0-only) |
| **License text** | [`DeepCW-AGPL-3.0.txt`](DeepCW-AGPL-3.0.txt) |
| **Obtained at commit** | `8e264d243bbd4467bd19f3f28292219405b47e0e` |
| **Original file size** | 15,139,839 bytes |
| **Original SHA-256** | `ef120799457bca042d4690944f0faf93268eb4654e7f50f28784ad63bdc1fe02` |
| **Derived file size** | 4,248,808 bytes |
| **Derived SHA-256** | `cd48259be0ea8c30ecbfff4a718644f361cb27b9228b030771b0c94756dcab98` |
| **Derivation** | Dynamic int8 quantization (weights → QUInt8, activations stay float32) via `onnxruntime.quantization.quantize_dynamic`. Input/output names, shapes and dtypes are unchanged. Measured CER on synthetic CW audio is identical to the fp32 model at SNR >= -4 dB; at -6/-8 dB both models degrade similarly. |
| **File size** | 15,139,839 bytes |
| **SHA-256** | `ef120799457bca042d4690944f0faf93268eb4654e7f50f28784ad63bdc1fe02` |
| **Modifications** | None. The full fp32 model is vendored byte-for-byte as published upstream. |
Related upstream repositories by the same author (not vendored here):
@@ -52,7 +50,6 @@ the repository hosting this file.
### Reproducing the vendored files
```bash
# 1) Fetch the original fp32 model
SHA=8e264d243bbd4467bd19f3f28292219405b47e0e
curl -sLO https://raw.githubusercontent.com/e04/deepcw-engine/$SHA/model.onnx
curl -sLO https://raw.githubusercontent.com/e04/deepcw-engine/$SHA/model.onnx.json
@@ -60,15 +57,7 @@ curl -sL -o DeepCW-AGPL-3.0.txt \
https://raw.githubusercontent.com/e04/deepcw-engine/$SHA/LICENSE
sha256sum model.onnx
# expected: ef120799457bca042d4690944f0faf93268eb4654e7f50f28784ad63bdc1fe02
# 2) Reproduce the int8 quantization this repository ships
python - <<'PY'
from onnxruntime.quantization import quantize_dynamic, QuantType
quantize_dynamic("model.onnx", "model_int8.onnx", weight_type=QuantType.QUInt8)
PY
sha256sum model_int8.onnx
# expected: cd48259be0ea8c30ecbfff4a718644f361cb27b9228b030771b0c94756dcab98
# then copy model_int8.onnx over assets/deepcw/model.onnx
# copy model.onnx and model.onnx.json into assets/deepcw/ unchanged
```
## ONNX Runtime
Binary file not shown.