CTC语音唤醒模型在VMware虚拟机中的训练环境配置
最近有不少朋友在尝试训练自己的语音唤醒模型,特别是那种能识别特定关键词的模型,比如“小云小云”这种。但问题来了,很多人的开发环境是Windows系统,而语音唤醒模型的训练通常需要在Linux环境下进行,这就有点尴尬了。
我最近正好在VMware虚拟机里折腾了一套CTC语音唤醒模型的训练环境,整个过程踩了不少坑,但也总结出了一些实用的经验。今天就跟大家分享一下,如何在VMware虚拟机里搭建一个完整的语音唤醒模型训练环境,包括GPU直通、数据共享、网络调优这些关键环节。
如果你也想在虚拟化环境里训练语音模型,但又担心性能损失或者配置复杂,那这篇文章应该能帮到你。我会尽量用大白话把每个步骤讲清楚,让你跟着做就能跑起来。
1. 为什么要在虚拟机里训练语音唤醒模型?
先说说为什么要在虚拟机里搞这个。其实原因挺简单的,很多人日常用的都是Windows系统,但很多AI开发工具和框架在Linux下跑得更顺畅。直接在Windows上装双系统吧,切换起来麻烦;用云服务器吧,成本又高,而且数据上传下载也不方便。
VMware虚拟机就提供了一个折中的方案:你可以在Windows里跑一个Linux虚拟机,既能享受Linux的开发环境,又能方便地访问Windows里的文件。更重要的是,现在VMware支持GPU直通,可以把主机的显卡直接分配给虚拟机用,这样训练速度就不会太慢。
语音唤醒模型训练对计算资源要求其实不算特别高,但有个GPU会快很多。特别是CTC这种模型,虽然参数量不大(大概75万左右),但训练过程中要处理大量音频数据,有GPU加速会省不少时间。
2. 虚拟机环境准备
2.1 选择Linux发行版
首先得选个合适的Linux系统。我推荐用Ubuntu 20.04 LTS或者22.04 LTS,这两个版本对AI开发支持比较好,社区资源也多。CentOS也可以,但有些软件包安装起来稍微麻烦点。
如果你用VMware Workstation Pro,创建虚拟机的时候直接选Ubuntu模板就行。内存建议至少分配8GB,硬盘空间给个50GB以上,因为后面要装不少东西。
2.2 安装VMware Tools
虚拟机装好系统后,第一件事就是安装VMware Tools。这个工具很重要,它能改善虚拟机的性能,特别是图形界面和文件共享方面。
在VMware菜单里选择“虚拟机” -> “安装VMware Tools”,然后虚拟机会挂载一个光盘镜像。你把里面的压缩包解压,然后运行安装脚本就行:
# 挂载光盘 sudo mount /dev/cdrom /mnt # 复制安装包 cp /mnt/VMwareTools-*.tar.gz /tmp/ cd /tmp # 解压 tar -xzf VMwareTools-*.tar.gz cd vmware-tools-distrib/ # 安装 sudo ./vmware-install.pl安装过程中基本上一直按回车用默认设置就行。装完后重启一下虚拟机。
2.3 配置GPU直通(如果有独立显卡)
如果你主机有NVIDIA独立显卡,而且想用GPU来加速训练,那需要配置GPU直通。这个功能需要主机BIOS支持VT-d/AMD-Vi,而且VMware Workstation Pro版本要够新。
首先在主机的VMware设置里,找到虚拟机的“.vmx”配置文件,用文本编辑器打开,添加这几行:
pciHole.start = "2048" pciHole.end = "3072" mks.enable3d = "TRUE" pciPassthru0.present = "TRUE" pciPassthru0.deviceId = "你的显卡设备ID" pciPassthru0.vendorId = "你的显卡厂商ID" pciPassthru0.systemId = "你的系统ID"设备ID和厂商ID可以在Windows设备管理器里查到,或者用GPU-Z这样的工具看。系统ID一般填“LOCAL”就行。
配置好后启动虚拟机,在Linux里安装NVIDIA驱动:
# 添加NVIDIA驱动仓库 sudo add-apt-repository ppa:graphics-drivers/ppa sudo apt update # 安装驱动(根据你的显卡型号选版本) sudo apt install nvidia-driver-535 # 重启 sudo reboot重启后运行nvidia-smi,如果能看到显卡信息,说明直通成功了。
3. 训练环境搭建
3.1 安装Python和基础工具
语音唤醒模型训练主要用Python,所以先装好Python环境。我建议用Python 3.8或3.9,兼容性比较好。
# 更新系统 sudo apt update sudo apt upgrade -y # 安装Python和相关工具 sudo apt install python3.9 python3.9-venv python3.9-dev python3-pip -y sudo apt install git wget curl build-essential cmake -y # 创建虚拟环境 python3.9 -m venv ~/venv/kws_train source ~/venv/kws_train/bin/activate3.2 安装PyTorch和ModelScope
CTC语音唤醒模型训练基于PyTorch和ModelScope,所以这两个必须装。
# 安装PyTorch(根据你的CUDA版本选) # 如果没有GPU或者CUDA版本低,可以用CPU版本 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装ModelScope语音相关包 pip install "modelscope[audio]" -f https://modelscope.oss-cn-beijing.aliyuncs.com/releases/repo.html # 安装其他依赖 pip install tensorboardX soundfile librosa kaldiio3.3 配置共享文件夹
训练数据通常放在Windows主机上,所以需要在虚拟机和主机之间共享文件夹。VMware Tools装好后,这个配置就简单了。
在VMware的虚拟机设置里,找到“选项” -> “共享文件夹”,添加你要共享的Windows目录。比如你可以创建一个“kws_data”文件夹,专门放训练数据。
在Linux虚拟机里,共享文件夹默认挂载在/mnt/hgfs/目录下。如果没看到,可能需要手动挂载:
# 查看可用的共享文件夹 vmware-hgfsclient # 创建挂载点 sudo mkdir -p /mnt/kws_data # 挂载共享文件夹 sudo vmhgfs-fuse .host:/kws_data /mnt/kws_data -o subtype=vmhgfs-fuse,allow_other为了让每次启动自动挂载,可以编辑/etc/fstab文件,添加一行:
.host:/kws_data /mnt/kws_data fuse.vmhgfs-fuse allow_other,defaults 0 04. 准备训练数据
4.1 数据格式要求
CTC语音唤醒模型训练需要两种数据:正样本(包含唤醒词的音频)和负样本(不包含唤醒词的音频)。数据格式有具体要求:
- 音频格式:16kHz采样率,单声道,WAV格式
- 标注格式:Kaldi风格的SCP文件和转录文件
举个例子,你的数据目录结构应该是这样的:
/mnt/kws_data/ ├── train/ │ ├── wav.scp │ └── transcripts.txt ├── cv/ # 交叉验证集 │ ├── wav.scp │ └── transcripts.txt └── test/ # 测试集 ├── wav.scp └── transcripts.txt4.2 创建数据列表文件
wav.scp文件是音频路径列表,格式是“音频ID TAB 音频文件路径”:
kws_pos_001 /mnt/kws_data/audio/pos_001.wav kws_pos_002 /mnt/kws_data/audio/pos_002.wav kws_neg_001 /mnt/kws_data/audio/neg_001.wavtranscripts.txt文件是标注文本,格式是“音频ID TAB 标注文本”:
kws_pos_001 小 云 小 云 kws_pos_002 小 云 小 云 kws_neg_001 今天 天气 不错注意标注文本要用空格分词,如果是中文的话。
4.3 数据量建议
根据官方文档的建议:
- 正样本(唤醒词音频)至少25小时以上
- 负样本比例在1:2到1:10之间比较合适
- 数据质量很重要,最好能覆盖多种场景和说话人
如果你数据不够,可以考虑用数据增强的方法,比如加噪、变速、混响等。
5. 模型训练配置
5.1 下载基线模型
ModelScope上有个现成的“小云小云”唤醒模型,我们可以在这个基础上做微调。先下载模型:
from modelscope.hub.snapshot_download import snapshot_download model_dir = snapshot_download('damo/speech_charctc_kws_phone-xiaoyun') print(f"模型下载到: {model_dir}")5.2 创建训练脚本
新建一个Python文件,比如train_kws.py,写入以下内容:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import sys from modelscope.utils.hub import read_config from modelscope.utils.hub import snapshot_download from modelscope.metainfo import Trainers from modelscope.trainers import build_trainer def main(): # 工作目录,保存所有训练文件 work_dir = './kws_training_output' os.makedirs(work_dir, exist_ok=True) # 模型ID model_id = 'damo/speech_charctc_kws_phone-xiaoyun' # 下载模型并读取配置 model_dir = snapshot_download(model_id) configs = read_config(model_id) # 修改训练配置 configs.train.max_epochs = 20 # 训练轮数 configs.preprocessor.batch_conf.batch_size = 64 # 批大小 configs.train.dataloader.workers_per_gpu = 4 # 数据加载线程数 configs.evaluation.dataloader.workers_per_gpu = 4 # 保存配置文件 config_file = os.path.join(work_dir, 'config.json') configs.dump(config_file) # 构建训练器 kwargs = dict( model=model_id, work_dir=work_dir, cfg_file=config_file, seed=42, # 随机种子 ) trainer = build_trainer( Trainers.speech_kws_fsm_char_ctc_nearfield, default_args=kwargs) # 训练数据路径(根据你的实际路径修改) train_scp = '/mnt/kws_data/train/wav.scp' cv_scp = '/mnt/kws_data/cv/wav.scp' test_scp = '/mnt/kws_data/test/wav.scp' trans_file = '/mnt/kws_data/transcripts.txt' # 开始训练 print("开始训练...") train_kwargs = dict( train_data=train_scp, cv_data=cv_scp, trans_data=trans_file, checkpoint='', # 从头开始训练 tensorboard_dir='tensorboard', seed_dump=True, ) trainer.train(**train_kwargs) # 测试(训练完成后自动进行) print("训练完成,开始测试...") keywords = '小云小云' # 你的唤醒词 test_dir = os.path.join(work_dir, 'test_results') test_kwargs = dict( test_dir=test_dir, test_data=test_scp, trans_data=trans_file, average_num=5, # 取最后5个checkpoint平均 gpu=0 if torch.cuda.is_available() else -1, keywords=keywords, batch_size=64, ) # 使用最好的checkpoint进行测试 best_checkpoint = os.path.join(work_dir, 'avg_5.pt') trainer.evaluate(best_checkpoint, None, **test_kwargs) if __name__ == '__main__': main()5.3 启动训练
在虚拟机的终端里,激活虚拟环境,然后运行训练脚本:
# 激活环境 source ~/venv/kws_train/bin/activate # 设置Python路径 export PYTHONPATH=. # 单GPU训练 python train_kws.py # 如果想用多GPU(如果虚拟机分配了多个GPU) # torchrun --standalone --nodes=1 --nproc_per_node=2 train_kws.py训练过程中,你可以用TensorBoard查看训练进度:
tensorboard --logdir ./kws_training_output/tensorboard然后在浏览器打开http://虚拟机IP:6006就能看到训练曲线了。
6. 分布式训练网络调优
如果你在虚拟机里做分布式训练(比如多GPU),网络配置很重要。VMware虚拟机的虚拟网络有时候会有性能瓶颈,需要优化一下。
6.1 使用VMXNET3网卡
VMXNET3是VMware性能最好的虚拟网卡,比默认的E1000快很多。在虚拟机设置里,把网络适配器类型改成VMXNET3。
然后在Linux里安装VMXNET3驱动:
# 安装编译工具 sudo apt install build-essential linux-headers-$(uname -r) # 驱动应该在VMware Tools里已经包含了 # 如果没有,可以手动安装 sudo apt install open-vm-tools6.2 调整网络参数
编辑/etc/sysctl.conf,添加以下参数优化网络性能:
# 增加TCP缓冲区大小 net.core.rmem_max = 134217728 net.core.wmem_max = 134217728 net.ipv4.tcp_rmem = 4096 87380 134217728 net.ipv4.tcp_wmem = 4096 65536 134217728 # 启用TCP窗口缩放 net.ipv4.tcp_window_scaling = 1 # 增加连接队列大小 net.core.somaxconn = 1024 net.ipv4.tcp_max_syn_backlog = 2048 # 启用TCP快速打开 net.ipv4.tcp_fastopen = 3保存后执行sudo sysctl -p生效。
6.3 NCCL网络优化(多GPU训练)
如果用多GPU训练,NCCL通信性能很关键。设置以下环境变量:
export NCCL_DEBUG=INFO export NCCL_SOCKET_IFNAME=ens33 # 你的网卡名,用ifconfig查看 export NCCL_IB_DISABLE=1 # 禁用InfiniBand,虚拟机里用不到 export NCCL_SHM_DISABLE=0 export NCCL_P2P_DISABLE=07. 常见问题解决
7.1 GPU内存不足
如果训练时报GPU内存不足,可以尝试:
- 减小
batch_size,比如从64降到32或16 - 使用梯度累积,模拟更大的batch size
- 使用混合精度训练,减少内存占用
在训练脚本里可以这样改:
# 启用混合精度训练 configs.train.fp16 = True configs.train.fp16_opt_level = 'O2'7.2 数据加载慢
如果数据加载成为瓶颈,可以:
- 增加
workers_per_gpu,比如从4增加到8 - 使用更快的存储,比如把数据放到虚拟机的本地SSD上
- 使用数据预加载,提前把数据加载到内存
7.3 模型不收敛
如果训练损失不下降或者波动很大:
- 检查学习率是否合适,可以尝试减小学习率
- 检查数据标注是否正确,特别是正样本的标注
- 增加正样本数据量,或者调整正负样本比例
- 尝试不同的优化器,比如AdamW
7.4 VMware虚拟机性能问题
如果感觉虚拟机性能不如物理机:
- 确保VMware Tools已安装并更新到最新版本
- 给虚拟机分配足够的内存和CPU核心
- 关闭虚拟机的3D加速,除非确实需要
- 使用VMware的“高性能”电源计划
8. 训练完成后的操作
8.1 模型导出
训练完成后,模型会保存在kws_training_output目录里。你需要把PyTorch模型转换成Kaldi格式,才能用在移动端:
# 进入工作目录 cd kws_training_output # 转换模型(假设已经生成了convert.kaldi.txt) # 如果没有,可能需要运行转换脚本 python convert_to_kaldi.py --checkpoint avg_5.pt --output convert.kaldi.txt8.2 模型打包
转换后的Kaldi文本模型还需要打包成二进制格式。ModelScope提供了打包脚本,一般在模型的runtime目录里:
# 复制转换后的模型到runtime目录 cp convert.kaldi.txt /path/to/model/runtime/ # 修改关键词配置 # 编辑runtime/kwsbpresource/keywords.json,设置你的唤醒词和阈值 # 运行打包脚本 cd /path/to/model/runtime/ bash run.sh打包完成后,会在output目录生成kwsbpresource_quant16.bin文件,这就是最终可以部署到移动端的模型文件。
8.3 性能测试
在部署前,最好在虚拟机上测试一下模型性能:
from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks # 加载训练好的模型 kws_pipeline = pipeline( task=Tasks.keyword_spotting, model='./kws_training_output', # 你的模型目录 model_revision='v1.0.0') # 测试单个音频 result = kws_pipeline(audio_in='test_audio.wav') print(f"检测结果: {result}") # 批量测试正负样本 results = kws_pipeline(audio_in=['pos_samples_dir', 'neg_samples_dir'])9. 总结
在VMware虚拟机里配置CTC语音唤醒模型的训练环境,整个过程虽然有些步骤,但跟着做下来其实不算太难。关键是要把几个环节配置好:GPU直通让训练有加速,共享文件夹方便数据管理,网络调优提升分布式训练效率。
我自己的体验是,用虚拟机训练最大的好处就是灵活。你可以在Windows主机上处理数据、写代码,然后在Linux虚拟机里训练模型,两边文件共享无缝衔接。而且虚拟机可以随时备份、克隆,环境配置一次就能重复使用。
当然,虚拟机性能肯定不如物理机,特别是GPU直通会有一些性能损失。但对于语音唤醒这种中等规模模型训练来说,完全够用了。如果你数据量特别大,或者模型特别复杂,可能还是需要考虑物理机或者云服务器。
训练过程中最花时间的其实是数据准备和标注,模型训练本身反而快一些。所以建议大家先把数据工作做扎实,标注要准确,数据要多样,这样训练出来的模型效果才会好。
最后提醒一点,训练好的模型在部署到移动端前,一定要充分测试。不同设备、不同环境下的表现可能会有差异,需要在各种场景下验证模型的唤醒率和误唤醒率,找到合适的阈值。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。