VoiceStudio 高级音频数据准备:Sidon 去噪与 Prompt 噪声增强完整实战
VoiceStudio 高级音频数据准备Sidon 去噪与 Prompt 噪声增强完整实战【免费下载链接】VoiceStudioVoiceStudio is the open-source, fully-local ElevenLabs alternative — voice cloning, voice design, video dubbing, dictation, transcription audiobook creation in 646 languages.项目地址: https://gitcode.com/GitHub_Trending/om/VoiceStudioVoiceStudio开源仓库README.md的训练数据采用自定义 WebDataset 格式音频被打包为 tar shard并配对齐的 JSONL 元数据文件。基础版管线见 docs/data_preparation.md完成原始音频 → 离散 token的转换而本文讲解的高级管线在其之上叠加了**去噪denoising**与Prompt 噪声增强prompt noise augmentation两个可选阶段用于提升模型在真实录音带背景噪声、房间混响场景下的鲁棒性。读完本文你将掌握如何用 Sidon 语音增强模型批量清洗训练音频、如何在分词阶段对参考音频prompt注入环境噪声与房间冲击响应RIR以做数据增强以及这些高级数据如何与训练数据配置正确衔接。高级管线整体概览高级管线在基础 tokenization 流程上增加两个阶段且每一阶段都是可选的Step 1 (可选): Denoise Raw audio → Sidon denoiser → clean audio Step 2: Tokenize (with optional noise augmentation) Clean audio noise augment on prefix → audio tokenizer → tokensStep 1使用 Sidon 语音增强模型去除原始音频中的背景噪声产出干净音频再以 WebDataset tar/jsonl shard 形式输出Step 2在基础 token 抽取omnivoice.scripts.extract_audio_tokens的基础上选择性地对**音频前缀prompt 区域**施加环境噪声与房间混响再做离散 token 化。两个阶段对应的可执行脚本位于仓库omnivoice/scripts/目录下阶段脚本作用去噪omnivoice/scripts/denoise_audio.py用 Sidon 模型去噪并打包 shard噪声增强分词omnivoice/scripts/extract_audio_tokens_add_noise.py对 prompt 加噪/加混响后抽取 8 层离散 token前置条件去噪阶段需要 Sidon 模型 checkpoint即feature_extractor_cuda.pt与decoder_cuda.pt两个 TorchScript 文件来自 sarulab-speech/sidon-v0.1 模型仓库。源码denoise_audio.py定义了 Sidon 的输入输出采样率常量SIDON_INPUT_SAMPLE_RATE 16_000、SIDON_OUTPUT_SAMPLE_RATE 48_000即模型内部以 16 kHz 输入、48 kHz 输出最终按你的--target_sample_rate重采样落盘。噪声增强阶段需要两份 WebDataset 格式的附加数据集且都要有data.lstmanifest噪声录音noise recordings环境噪声 tar shards房间冲击响应RIR房间混响脉冲响应 tar shards。Step 1使用 Sidon 对原始音频去噪基本用法export CUDA_VISIBLE_DEVICES0,1,2,3 python -m omnivoice.scripts.denoise_audio \ --input_jsonl data.jsonl \ --tar_output_pattern data/denoised/audios/shard-%06d.tar \ --jsonl_output_pattern data/denoised/txts/shard-%06d.jsonl \ --feature_extractor_path /path/to/sidon_feature_extractor_cuda.pt \ --decoder_path /path/to/sidon_decoder_cuda.pt \ --target_sample_rate 24000 \ --batch_duration 200.0脚本执行流程读取 JSONL manifest或data.lst对每个音频文件运行 Sidon 去噪器将去噪后的音频打包为自定义 WebDataset tar/jsonl shardstar 内存放.flac音频jsonl 存放原 metadata在data/denoised/下生成data.lstmanifest。提示如果已有自定义 WebDataset 格式的数据集可以改传--input_manifest /path/to/data.lst而不使用--input_jsonl。下一步即把生成的data.lst通过--input_manifest传给omnivoice.scripts.extract_audio_tokens进行 token 抽取。关键参数说明以源码 denoise_audio.py 为准参数默认值说明--input_manifestNoneWebDataset manifestdata.lst与--input_jsonl二选一--input_jsonlNone原始 JSONL 文件与--input_manifest二选一--tar_output_pattern必填tar shard 输出模式如data/denoised/audios/shard-%06d.tar--jsonl_output_pattern必填jsonl shard 输出模式如data/denoised/txts/shard-%06d.jsonl--feature_extractor_path必填feature_extractor_cuda.pt路径--decoder_path必填decoder_cuda.pt路径--samples_per_shard1000每个 tar shard 最多容纳的样本数--target_sample_rate24000去噪后输出音频的采样率Sidon 内部输出 48 kHz 后再重采样到此值--min_length0.0小于此时长秒的音频被跳过--max_length80.0大于此时长秒的音频被跳过--batch_duration200.0动态批处理的目标批时长秒--max_sample32动态批处理每批最大样本数--nj_per_gpu1每块 GPU 的 worker 进程数--loader_workers16DataLoader worker 线程数--num_machines/--machine_index1 / 0分布式预处理的机器总数与当前机器索引--shuffle/--shuffle_seedTrue / 42JSONL 模式下是否洗牌及随机种子--skip_errorsFalse处理失败时跳过该样本继续而不是中止任务源码级实现细节从denoise_audio.py可以看到去噪核心类SpeechDenoisingProcessor通过torch.jit.load加载 feature extractor 与 decoder 两个 TorchScript 模型在torch.inference_mode()下运行特征提取使用纯 Torch 实现的 SeamlessM4T fbank 特征extract_seamless_m4t_featuresdecoder 输出波形后按期望长度对齐/截断。写入阶段denoise_audio.py有两个值得注意的处理若target_sample_rate ! 48000会先对波形重采样写盘前执行峰值归一化waveform (waveform / (waveform.abs().max() 1e-7)) * 0.6即把峰值压到 0.6避免后续训练时削波音频以 16-bit FLAC 形式serialise_flac写入 tar元数据以 UTF-8 JSON 逐行写入配套 jsonl。另一个关键实现是GPU worker 子进程池denoise_audio.py由于 PyTorch ≥ 2.8 会在 import 时缓存 CUDA 设备状态脚本改为用subprocess.Popen为每个 worker 单独设置CUDA_VISIBLE_DEVICES后再import torch父子进程通过4 字节长度前缀 pickle的协议在 stdin/stdout 上通信从而保证每块 GPU 上的进程数精确可控。这也是为什么命令前需要export CUDA_VISIBLE_DEVICES0,1,2,3的原因。Step 2带噪声增强的 Token 抽取在分词阶段对prompt 音频即音频的前缀部分训练时作为参考音色条件注入环境噪声与房间混响使模型在推理时面对带噪声的参考音频也能稳定工作。需要说明的是模型只在较小比例的数据上做噪声增强以保证使用干净参考音频时同样能生成高质量音频。你需要两份额外的 WebDataset 数据集噪声录音Noise recordings环境噪声 tar shards含data.lstmanifest房间冲击响应RIRRIR tar shards含data.lstmanifest。基本用法export CUDA_VISIBLE_DEVICES0,1,2,4 python -m omnivoice.scripts.extract_audio_tokens_add_noise \ --input_jsonl data.jsonl \ --tar_output_pattern data/tokens/shard-%06d.tar \ --jsonl_output_pattern data/txts/shard-%06d.jsonl \ --tokenizer_path eustlb/higgs-audio-v2-tokenizer \ --noise_manifest data/noise_shards/data.lst \ --rir_manifest data/rir_shards/data.lst \ --nj_per_gpu 3提示同样支持--input_manifest /path/to/data.lst作为输入已有自定义 WebDataset 格式数据集时使用。参数说明以源码 extract_audio_tokens_add_noise.py 为准参数默认值说明--input_manifest/--input_jsonlNone输入二选一规则同基础脚本--tar_output_pattern/--jsonl_output_pattern必填shard 输出模式--samples_per_shard1000每个 tar shard 最大样本数--min_num_shards32最小输出 shard 数保证 shard 数 ≥ GPU 数 × worker 数源码会在样本数不足时自动下调samples_per_shard--tokenizer_patheustlb/higgs-audio-v2-tokenizer音频 tokenizer 的 HuggingFace 路径或本地路径--skip_errorsFalse失败样本跳过继续--min_length/--max_length0.0 / inf时长过滤秒--nj_per_gpu3每块 GPU 的 worker 进程数--loader_workers24流式IterableDataset的 DataLoader workers--shuffle/--shuffle-seedTrue / 42洗牌开关与种子--noise_manifestNone噪声 manifesttar 列表启用 prompt 噪声增强--rir_manifestNoneRIR manifesttar 列表启用 prompt 混响增强--num_machines/--machine_index1 / 0多机分布式预处理源码级实现细节prompt 增强如何发生增强逻辑位于extract_audio_tokens_add_noise.py的_augment_prompt函数逐条对应文档描述划分 prompt 区域先做峰值归一化* 0.6再取音频前ratio ∈ uniform(0.1, 0.3)的片段作为 prompt 部分加环境噪声配置了--noise_manifest时从噪声 shard 中随机截取与 prompt 等长的片段SimpleWorkerSampler.sample_segment支持短噪声循环拼接按SNR 随机 515 dB混合进 prompt加房间混响配置了--rir_manifest时以30% 概率对 prompt 做 RIR 卷积_convolve1d用 FFT 实现混响强度reverb_amt ∈ uniform(0.3, 1.0)并做能量对齐后与原信号混合回写与归一化把增强后的 prompt 拼回原音频再做一次峰值归一化* 0.9。关键元数据增强后脚本会把 prompt 结束位置换算成 token 索引写入 metadatametadata[clean_start_token_idx] math.ceil(clean_sample_idx / worker_tokenizer.config.hop_length)该字段在训练侧被omnivoice/data/processor.py消费带有clean_start_token_idx的样本会被打上|denoise|风格标记且prompt_length固定为该索引、不做条件丢弃drop_cond Falseprompt 区域不参与 loss 计算——即模型专门学习从被污染的 prompt 中恢复干净音频这正是文档所说让模型对带噪参考音频鲁棒的训练机制。输出 token 为形状[8, T]、int16的 NumPy 数组8 层离散 token通过np.save以.npy形式写入 tar。与基础流程的衔接输入格式与 data.lst manifest输入 JSONL 格式高级管线的两个脚本都接受与基础管线相同的 JSONL 输入一行一个 JSON 对象{id: sample_001, audio_path: /data/audio/001.wav, text: Hello world, language_id: en} {id: sample_002, audio_path: /data/audio/002.wav, text: 你好世界, language_id: zh}字段约定id唯一样本标识用于跨 shard 与标签文件匹配、audio_path音频绝对路径wav/flac/mp3会被重采样到 24 kHz、text转写文本、language_id可选多语言训练用。从原始音频直接构造 WebDataset若你的语料已经是原始音频 tar shards可用jsonl_to_webdataset.py先把 JSONL 打包成 WebDatasetpython -m omnivoice.scripts.jsonl_to_webdataset \ --input data.jsonl \ --output data/shards \ --sr 24000 \ --shard-size 1000该脚本把音频重采样到目标采样率、以 16-bit FLAC 写入 tar并生成配对的 jsonl 元数据自动附加audio_duration支持--workers进程数默认 16、--threads每进程线程数默认 4、--min-duration/--max-duration时长过滤注意max-duration为半开区间则剔除、--shuffle/--shuffle-seed等参数。输出结构与data.lst假设输出模式为--tar_output_pattern output/audios/shard-%06d.tar \ --jsonl_output_pattern output/txts/shard-%06d.jsonl则产物结构为output/ ├── audios/ # WebDataset tar shards去噪阶段为 .flac分词阶段为 .npy token │ ├── shard-000000.tar # 每个 tar 打包约 1000 个样本 │ ├── shard-000001.tar │ └── ... ├── txts/ # 与 tar 一一对应的 JSONL 标签 │ ├── shard-000000.jsonl # 每行对应 tar 中的一个样本 │ ├── shard-000001.jsonl │ └── ... ├── data.lst # 链接 tar ↔ jsonl 的 manifest └── errors.jsonl # 处理失败的样本如有data.lst与errors.jsonl写在与audios/、txts/相同的父目录下。data.lst每行描述一个 shard/path/to/shard-000000.tar /path/to/shard-000000.jsonl 1000 3600.500 /path/to/shard-000001.tar /path/to/shard-000001.jsonl 800 2880.200格式为tar_path jsonl_path num_samples total_duration_seconds路径为绝对路径.tar内含音频 token分词阶段为形状[8, T]、int16的.npy.jsonl保留原始 JSONL 元数据方便在不解压 tar 的前提下读取与修改元数据该 manifest 正是训练数据配置所引用的对象。解析侧可参考omnivoice/data/dataset.py的webdataset_manifest_reader每行按空格切分为 4 列若列数不符会直接抛出ValueError因此data.lst必须严格遵循上述格式。将高级数据接入训练配置完成去噪/噪声增强分词后编写引用这些 shard 的训练数据配置 JSON{ train: [ { language_id: en, manifest_path: [data/custom/tokens/train/data.lst], repeat: 1 } ], dev: [ { language_id: en, manifest_path: [data/custom/tokens/dev/data.lst], repeat: 1 } ] }字段语义manifest_path—data.lst文件列表每个 shard 目录一个repeat— 每个 epoch 中该数据集重复的次数用于平衡不同语言的数据量可选默认 1language_id— 不参与实际训练逻辑仅用于更好地组织多语言数据源码注释与文档一致。仓库提供了可直接参考的现成配置examples/config/data_config_emilia.json英中双语 train/dev 示例与 examples/config/data_config_finetune.json纯微调示例。训练侧由omnivoice/data/dataset.py的prepare_data_manifests_from_json解析读取train/dev数组对每个manifest_path调用webdataset_manifest_reader解析出 (tar, jsonl, num_items, num_seconds) 元组列表再按repeat次数扩展后交给 DataLoader。实战注意事项与最佳实践GPU 分配两个脚本都通过CUDA_VISIBLE_DEVICES控制参与计算的 GPUworker 数由nj_per_gpu决定去噪脚本默认 1噪声增强脚本默认 3。单卡环境下无需设置该环境变量。时长过滤去噪脚本--max_length默认 80 秒源码 denoise_audio.py噪声增强分词脚本默认inf可根据语料分布显式设置避免超长样本拉高批时长、拖慢处理。shard 数量下限噪声增强分词脚本通过--min_num_shards默认 32确保 shard 数 ≥ GPU 数 × worker 数样本不足时脚本会自动下调samples_per_shard见 extract_audio_tokens_add_noise.py无需手动干预。错误容忍默认任何一个样本失败都会中止整个任务对大规模清洗建议加--skip_errors失败样本会记录到errors.jsonl便于事后定位记录id与失败原因。增强比例克制如文档强调噪声增强只应作用于小比例数据否则会损害干净参考音频下的生成质量若想调整增强强度可修改源码_augment_prompt中的 prompt 比例0.1~0.3、SNR5~15 dB与 RIR 概率0.3等超参数后重新运行。端到端链路完整推荐流程为原始音频 →可选Sidon 去噪 →可选噪声增强分词 →data.lst→ 训练数据配置 JSON → 训练去噪与分词脚本均支持--input_manifest接力前一步的data.lst可直接作为后一步输入。【免费下载链接】VoiceStudioVoiceStudio is the open-source, fully-local ElevenLabs alternative — voice cloning, voice design, video dubbing, dictation, transcription audiobook creation in 646 languages.项目地址: https://gitcode.com/GitHub_Trending/om/VoiceStudio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考