这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » max78000实现语音识别2--数据集训练量化和端侧部署

共1条 1/1 1 跳转至

max78000实现语音识别2--数据集训练量化和端侧部署

菜鸟
2026-07-27 21:51:44   被打赏 40 分(兑奖)     打赏


Google Speech Commands 在 MAX78000 上的训练、量化与部署

本文记录如何在 Windows + WSL 环境中,使用 Google Speech Commands v0.02 训练一个 12 类关键词识别模型,并将模型量化为 8 bit,生成 MAX78000 CNN 加速器代码,最后部署到 MAX78000FTHR 开发板。

本文使用原生命令逐步操作,不依赖项目私有的自动化脚本。读者可以根据自己的 目录结构替换示例中的路径。

1. 实验目标与最终结果

模型识别 10 个英语口令,并增加静音与未知语音两个拒识类别:

ID标签中文含义固件处理





0down接受
1go前进接受
2left左转接受
3no接受
4off关闭接受
5on开启接受
6right右转接受
7stop停止接受
8up接受
9yes接受
10_silence_静音拒绝
11_unknown_未知语音拒绝

本次实验结果如下:

项目结果



数据集Google Speech Commands v0.02
训练集87,829 条
验证集10,355 条
测试集4,891 条
网络ai85kws20netv3
参数量167,168
训练轮数200
QAT 开始轮次第 150 轮
最佳验证 Top-184.57%
测试 Top-190.98%
测试 Top-599.39%
权重位宽8 bit
CNN 推理时间约 1.849 ms
实时固件 FLASH230,144 字节,43.90%
实时固件 SRAM38,416 字节,29.31%

整体流程为:

环境安装 → 数据下载与处理 → 浮点训练与 QAT → 8-bit 量化
→ ai8xize 代码生成 → 麦克风固件集成 → 编译、烧录与串口验证

2. 硬件和软件准备

2.1 硬件

  • MAX78000FTHR 开发板;

  • USB 数据线;

  • 开发板板载数字麦克风;

  • 板载 DAPLink 下载器和调试串口。

开发板运行状态如下:

max78000fthr-running.jpg

图 1:MAX78000FTHR 通过 USB 连接并运行关键词识别固件。

2.2 本次使用的软件版本

软件版本



WSLUbuntu 22.04.5 LTS
Python3.11.8
PyTorch2.3.1+cpu
torchaudio2.3.1+cpu
NumPy1.26.4
ONNX1.16.1
AI8X Trainingdevelop 分支
AI8X Synthesisdevelop 分支
MSDK2024.02 系列

训练使用 CPU 完成。如果计算机具有可用的 NVIDIA GPU,可以根据 AI8X Training 的依赖要求安装对应 CUDA 版本的 PyTorch。

3. 搭建 WSL 和 AI8X 环境

3.1 安装 WSL

以管理员身份打开 PowerShell:

wsl --install -d Ubuntu-22.04

安装完成并重启后,打开 Ubuntu 终端,更新系统并安装编译、音频和 Python 构建依赖:

sudo apt update
sudo apt install -y \
  make build-essential git ca-certificates curl wget \
  libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \
  llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev \
  libffi-dev liblzma-dev libsndfile1-dev portaudio19-dev \
  libsox-dev sox libgdbm-dev libnss3-dev libdb-dev \
  libexpat1-dev uuid-dev

3.2 安装 Python 3.11.8

使用 pyenv 可以让训练环境与系统 Python 隔离:

git clone --depth 1 https://github.com/pyenv/pyenv.git ~/.pyenv

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"

pyenv install 3.11.8

为了让设置在下次启动终端时仍然有效,可将 PYENV_ROOT 和 PATH 两行加入~/.bashrc。

3.3 获取 AI8X Training 和 AI8X Synthesis

mkdir -p ~/max78000-ai
cd ~/max78000-ai

git clone --depth 1 --branch develop --recurse-submodules \
  https://github.com/analogdevicesinc/ai8x-training.git

git clone --depth 1 --branch develop \
  https://github.com/analogdevicesinc/ai8x-synthesis.git

分别建立虚拟环境:

~/.pyenv/versions/3.11.8/bin/python -m venv \
  ~/max78000-ai/ai8x-training/.venv

~/.pyenv/versions/3.11.8/bin/python -m venv \
  ~/max78000-ai/ai8x-synthesis/.venv

安装训练环境。以下示例使用 CPU 版 PyTorch:

cd ~/max78000-ai/ai8x-training

.venv/bin/python -m pip install --upgrade \
  pip wheel setuptools==80.9.0

.venv/bin/python -m pip install \
  torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1 \
  --index-url https://download.pytorch.org/whl/cpu

.venv/bin/python -m pip install --no-build-isolation visdom==0.2.4
.venv/bin/python -m pip install \
  -r requirements-base.txt -r requirements-distiller.txt

如果 requirements-datasets.txt 中已经下架的旧版 pyffmpeg 导致安装失败, 将 pyffmpeg==2.4.2.18.1 改为 pyffmpeg==2.5.2.3.2,再执行:

.venv/bin/python -m pip install \
  --constraint requirements-base.txt \
  -r requirements-datasets.txt

安装代码生成环境:

cd ~/max78000-ai/ai8x-synthesis

.venv/bin/python -m pip install --upgrade \
  pip wheel setuptools==80.9.0

.venv/bin/python -m pip install torch==2.3.1 \
  --index-url https://download.pytorch.org/whl/cpu

.venv/bin/python -m pip install -r requirements.txt

最后检查环境:

~/max78000-ai/ai8x-training/.venv/bin/python -c \
  "import torch, torchaudio; print(torch.__version__, torchaudio.__version__)"

~/max78000-ai/ai8x-synthesis/.venv/bin/python \
  ~/max78000-ai/ai8x-synthesis/ai8xize.py --help

4. 下载和处理 Google Speech Commands

4.1 数据来源和许可

本实验使用 Google Speech Commands v0.02:

数据集采用 CC BY 4.0。发布原始数据或衍生数据时,应保留来源、许可和署名。

4.2 手动下载

建立原始数据目录:

mkdir -p ~/max78000-ai/data/KWS/raw
mkdir -p ~/max78000-ai/data/KWS/raw_test

下载并解压训练与验证数据:

cd ~/max78000-ai/data/KWS/raw

wget -c \
  http://download.tensorflow.org/data/speech_commands_v0.02.tar.gz

tar -xzf speech_commands_v0.02.tar.gz

下载并解压官方测试数据:

cd ~/max78000-ai/data/KWS/raw_test

wget -c \
  http://download.tensorflow.org/data/speech_commands_test_set_v0.02.tar.gz

tar -xzf speech_commands_test_set_v0.02.tar.gz

主数据压缩包约 2.3 GiB,生成缓存后整个数据目录约占 7.6 GiB,建议至少预留 10 GiB 空间。

4.3 适配 AI8X 的 12 类数据加载

AI8X Training 已包含 KWS_12_benchmark 类别定义,可以以它为基础建立 12 类 加载入口。为了避免数据准备失败,本次做了三个调整:

  1. 只使用 Google Speech Commands,不下载后续会被过滤的 LibriSpeech;

  2. 关闭三倍静态速度复制,避免 WSL 在生成缓存时因内存不足退出;

  3. 保留动态随机平移与高斯噪声增强。

动态增强参数为:

augmentation = {
    "aug_num": 0,
    "shift": {"min": -0.1, "max": 0.1},
    "snr": {"min": -5.0, "max": 20.0},
}

Google 数据中的其他单词用于构造 _unknown_,背景噪声切片用于构造_silence_。由于原始 KWS 类别字典为 LibriSpeech 保留了内部 ID,还需要建立 一个空目录以保持标签顺序:

mkdir -p ~/max78000-ai/data/KWS/raw/librispeech

加载器首次读取数据时会生成:

~/max78000-ai/data/KWS/processed/dataset.pt

最终得到:

Training:   87,829
Validation: 10,355
Test:        4,891

_unknown_ 样本远多于单个目标词,因此训练时为它设置 0.056 的损失权重, 以避免该类别支配整体损失。

5. 模型与训练

5.1 网络配置

使用 ai85kws20netv3:

  • 输入尺寸:128 × 128;

  • 原始音频:16,384 个采样点,约 1.024 秒;

  • 8 个一维卷积层;

  • 9 个参数层;

  • 输出:12 类;

  • 参数量:167,168;

  • 无 bias;

  • 面向 MAX78000 CNN 加速器。

网络部署配置需要将最后一层输出数改为 12,并为各层设置处理器映射、输出偏移 和内存位置。该 YAML 配置在量化完成后由 ai8xize.py 读取。

5.2 训练参数

参数配置



Epoch200
Batch size64
优化器Adam
初始学习率0.001
Weight decay0
DataLoader workers0
确定性训练开启
QAT第 150 轮开始
量化位宽8 bit

学习率在第 100、140、180、190、195 轮乘以 0.5。前 149 轮完成常规训练, 第 150 轮开始量化感知训练,使网络提前适应部署时的整数运算误差。

5.3 启动训练

进入 AI8X Training 目录后执行:

cd ~/max78000-ai/ai8x-training

.venv/bin/python train.py \
  --epochs 200 \
  --batch-size 64 \
  --optimizer Adam \
  --lr 0.001 \
  --wd 0 \
  --deterministic \
  --compress policies/schedule_kws20.yaml \
  --qat-policy policies/qat_policy_late_kws20.yaml \
  --model ai85kws20netv3 \
  --dataset KWS_GOOGLE_12 \
  --data "$HOME/max78000-ai/data" \
  --confusion \
  --device MAX78000 \
  --compiler-mode none \
  --workers 0 \
  --cpu \
  --print-freq 100 \
  --name kws_google_12 \
  --out-dir "$HOME/max78000-ai/logs"

如果使用上游原始数据入口,应将数据集名称换成相应注册名称;如果使用前文的 Google-only 适配入口,则保持 KWS_GOOGLE_12。

训练期间重点观察:

  • 训练损失是否持续下降;

  • 验证 Top-1 是否稳定上升;

  • 第 150 轮进入 QAT 后是否出现明显精度骤降;

  • 混淆矩阵中 _silence_ 与 _unknown_ 是否大量误判为目标词。

5.4 训练结果

CPU 训练耗时约 3 小时 10 分钟:

检查项结果



最佳验证轮次195
最佳验证 Top-184.5678%
最佳验证 Top-599.5750%
最佳 QAT 模型测试 Top-190.9834%
最佳 QAT 模型测试 Top-599.3866%
最佳 QAT 模型测试损失0.2876

最佳模型应根据验证集选择,测试集只用于最终评估。后续量化应使用 QAT 阶段产生 的最佳检查点。

6. 8-bit 量化

6.1 为什么 QAT 后还要量化

QAT 检查点记录了训练阶段的量化状态,但部署仍需生成确定的整数权重。AI8X 量化工具会把参数转换为 MAX78000 可使用的 8-bit 表示,并保留各层量化信息。

进入 AI8X Synthesis 目录,将最佳检查点复制到模型工作目录:

mkdir -p ~/max78000-ai/models/kws_google_12
cp /path/to/kws_google_12_qat_best.pth.tar \
  ~/max78000-ai/models/kws_google_12/model-best.pth.tar

cd ~/max78000-ai/ai8x-synthesis

执行量化:

.venv/bin/python quantize.py \
  ~/max78000-ai/models/kws_google_12/model-best.pth.tar \
  ~/max78000-ai/models/kws_google_12/model-q8.pth.tar \
  --device MAX78000 \
  -v

检查输出中是否包含全部 9 个参数层,并确认权重位宽为 8 bit。本次量化后的权重 共 167,168 字节,无 bias 数据。

7. 使用 ai8xize 生成 MAX78000 代码

准备三项输入:

  1. 上一步得到的 8-bit 检查点;

  2. 12 类网络 YAML 配置;

  3. 一个形状正确的 128 × 128 样本输入。

执行:

cd ~/max78000-ai/ai8x-synthesis

.venv/bin/python ai8xize.py \
  --test-dir "$HOME/max78000-ai/generated" \
  --prefix kws_google_12 \
  --checkpoint-file \
    "$HOME/max78000-ai/models/kws_google_12/model-q8.pth.tar" \
  --config-file networks/kws_google_12.yaml \
  --sample-input tests/sample_kws_20.npy \
  --device MAX78000 \
  --timer 0 \
  --display-checkpoint \
  --verbose \
  --softmax

生成目录中主要包含:

cnn.c
cnn.h
weights.h
softmax.c
main.c
sampledata.h
sampleoutput.h
project.mk
Makefile

本次网络计算量如下:

项目数量



Hardware ops8,400,224
MACC8,343,040
Comparisons54,496
Additions2,688

先编译固定样本工程,确认网络配置、权重和 MSDK 工具链可以正常工作:

cd ~/max78000-ai/generated/kws_google_12

make -j2 BOARD=FTHR_RevA MAXIM_PATH=/path/to/msdk
arm-none-eabi-objcopy \
  -O ihex build/max78000.elf build/max78000.hex

固定样本工程的资源占用为:

  • FLASH:239,360 字节,45.65%;

  • SRAM:5,212 字节,3.98%。

该工程只用于验证固定输入,不是最终实时麦克风应用。

8. 集成实时麦克风固件

将生成的 cnn.c、cnn.h 和 weights.h 接入 MAX78000FTHR 麦克风示例工程, 并完成以下处理:

  1. 以 16 kHz 采集板载数字麦克风;

  2. 使用高通滤波移除直流分量;

  3. 根据平均能量判断语音起点和终点;

  4. 组成 16,384 点窗口,不足部分补零;

  5. 转置为 CNN 所需的 128 × 128 HWC 布局;

  6. 执行 CNN 推理和定点 Softmax;

  7. 对 silence 与 unknown 强制拒识;

  8. 对目标词应用置信度、类别差值和冷却时间;

  9. 仅在通过全部条件时产生口令事件。

本次使用的主要门限为:

#define THRESHOLD_HIGH 350
#define THRESHOLD_LOW 100
#define INFERENCE_THRESHOLD 95
#define INFERENCE_MARGIN_THRESHOLD 15

不同硬件修订版、麦克风距离和环境噪声可能需要不同能量门限。置信度门限也不应 只根据单次成功样本设置,应同时测试目标词、非目标语音、静音和背景噪声。

编译实时工程:

cd /path/to/msdk/Examples/MAX78000/CNN/kws_google_12_demo

make clean MAXIM_PATH=/path/to/msdk
make -j2 BOARD=FTHR_RevA MAXIM_PATH=/path/to/msdk
make build/max78000.hex MAXIM_PATH=/path/to/msdk

本次实时固件资源占用:

FLASH: 230,144 / 524,288 bytes = 43.90%
SRAM:   38,416 / 131,072 bytes = 29.31%

9. 手动烧录

MAX78000FTHR 的板载 DAPLink 可以像 U 盘一样烧录:

  1. 使用 USB 数据线连接开发板;

  2. 等待系统出现名为 DAPLINK 的磁盘;

  3. 找到实时工程生成的 build/max78000.hex;

  4. 将 HEX 文件复制到 DAPLINK 磁盘根目录;

  5. 等待复制结束和开发板自动复位;

  6. 检查 DAPLink 根目录是否出现 FAIL.TXT;

  7. 如果存在 FAIL.TXT,打开文件查看烧录失败原因。

不要烧录固定样本测试工程生成的 HEX;实时识别必须使用已经集成麦克风采集逻辑 的固件。

10. 串口运行与识别验证

在 Windows 设备管理器中查找 DAPLink 对应的 COM 端口,然后使用 PuTTY、 Tera Term、MobaXterm 或其他串口工具连接:

波特率:115200
数据位:8
校验位:None
停止位:1
编码:UTF-8

如果打开串口后没有启动信息,保持串口窗口开启并按开发板 SW4 RESET。

测试词 up 被识别为类别 8,置信度 99.9%,CNN 推理时间约 1,849 微秒:

runtime-up-detection.png

图 2:低置信度窗口被拒绝,随后 UP 以 99.9% 置信度被接受。

机器可读事件为:

KWS_EVENT,8,UP,99.9

从日志可以看到:

  • 91.0% 置信度低于 95% 门限,因此被拒绝;

  • 10.0% 的非语音窗口被拒绝;

  • UP 的类别差值为 99.8%,通过歧义检查;

  • 麦克风样本范围达到 -127~127;

  • 每次 CNN 推理约 1.849 ms。

11. 常见问题

11.1 数据处理出现退出码 137

通常表示 WSL 内存不足。关闭三倍静态速度复制,只保留训练时动态平移和噪声 增强;必要时提高 WSL 内存上限,然后删除旧的 dataset.pt 重新生成。

11.2 标签数量或顺序异常

确认 raw/librispeech 空目录存在。原始类别字典为该类别保留了内部 ID,直接 删除会导致之后的 Google 标签整体错位。

11.3 中文串口乱码

确认固件源文件、终端和串口接收工具都使用 UTF-8。串口参数应为 115200 8-N-1。若终端不支持 UTF-8,可以只输出 ASCII 机器事件,例如KWS_EVENT,8,UP,99.9。

11.4 识别准确率低或误触发多

  • 实际说出英语口令,而不是中文翻译;

  • 控制说话距离,避免声音过小;

  • 检查采样是否长期达到 -128/127,防止严重削波;

  • 在目标环境中采集板载麦克风数据用于微调;

  • 添加目标噪声环境下的 silence 和 unknown 样本;

  • 分别统计误接受率和误拒绝率,再调整置信度与类别差值门限;

  • 不要只依据单个成功样本降低门限。

11.5 烧录后没有运行

  • 检查 DAPLink 中的 FAIL.TXT;

  • 确认构建目标是 FTHR_RevA;

  • 确认烧录的是实时麦克风工程 HEX;

  • 重新插拔 USB,然后按 SW4 RESET;

  • 确认串口号没有因重新枚举而改变。

12. 总结

本流程完成了从公开语音数据到 MAX78000 实时端侧关键词识别的完整闭环:

  • 使用 Google Speech Commands 提高说话人和录音设备的多样性;

  • 加入 silence 与 unknown,降低非目标声音触发;

  • 进行 200 轮训练,并从第 150 轮开始 8-bit QAT;

  • 使用 quantize.py 生成 8-bit 权重;

  • 使用 ai8xize.py 生成 MAX78000 CNN 代码;

  • 集成麦克风采集、能量检测、Softmax 和拒识门限;

  • 通过 DAPLink 手动烧录并使用串口验证;

  • 实测 UP 达到 99.9% 置信度,单次 CNN 推理约 1.849 ms。

如果要用于真实产品,应继续采集实际安装环境中的板载麦克风数据,分别统计不同 说话人、距离、噪声和语速下的误接受率与误拒绝率,再决定是否微调模型或调整 门限。



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]