news 2026/4/16 10:38:49

数据集格式转换工具:将普通文本转为TTS训练专用格式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数据集格式转换工具:将普通文本转为TTS训练专用格式

数据集格式转换工具:将普通文本转为TTS训练专用格式

📌 背景与需求:为何需要标准化TTS数据格式?

在语音合成(Text-to-Speech, TTS)任务中,尤其是基于深度学习的端到端模型如Sambert-Hifigan,训练数据的质量和格式直接影响模型收敛速度与生成语音的自然度。尽管原始语料可能只是简单的纯文本 + 音频文件,但大多数主流TTS框架(如 ESPnet、FastSpeech2、ModelScope 的 Sambert 系列)要求输入数据遵循特定结构化格式。

当前项目聚焦于中文多情感语音合成,目标是让模型不仅能准确发音,还能根据上下文表达喜怒哀乐等情绪。这就对训练数据提出了更高要求:不仅要包含文本与音频的对应关系,还需标注情感标签、说话人ID、文本归一化结果等元信息。

然而,现实中的原始数据往往是非结构化的: - 文本以.txt.csv形式存在 - 音频命名混乱,缺乏统一规则 - 情感标签分散在不同文件或未标注

因此,构建一个自动化、可复用的数据集格式转换工具,成为高效训练高质量TTS模型的前提。


🧩 核心任务:从普通文本到TTS专用格式的映射

1. 目标格式定义:Sambert-Hifigan 所需的标准结构

ModelScope 的 Sambert-Hifigan 模型推荐使用如下目录结构和文件组织方式:

dataset/ ├── train.txt # 训练样本列表(核心) ├── val.txt # 验证集列表 ├── audio/ │ ├── spk_001/ │ │ ├── utt_001.wav │ │ └── utt_002.wav │ └── spk_002/ │ └── ... └── text.json # 可选:全局文本字典或预处理配置

其中train.txtval.txt是关键,每行记录一条样本,格式如下:

<相对路径>|<原始文本>|<归一化后文本>|<说话人ID>|<情感标签>

示例:

audio/spk_001/utt_001.wav|今天天气真好啊!|jintian tianqi zhen hao a!|spk_001|happy

📌 关键字段说明: -相对路径:音频文件相对于数据集根目录的路径 -原始文本:用户输入的原始中文句子 -归一化文本:经过数字转汉字、缩写展开、标点标准化后的文本(用于声学模型输入) -说话人ID:支持多说话人建模 -情感标签:如happy,angry,sad,neutral等,驱动情感合成


2. 工具设计思路:模块化处理流程

我们设计了一个轻量级 Python 脚本,实现从“原始文本+音频”到上述标准格式的自动转换。整体流程分为五个阶段:

✅ 阶段一:输入数据清洗与对齐

假设原始数据结构如下:

raw_data/ ├── metadata.csv # 包含 text, emotion, speaker 字段 ├── wavs/ │ ├── 00001.wav │ ├── 00002.wav │ └── ...

metadata.csv内容示例:

| id | text | emotion | speaker | |--------|----------------|---------|---------| | 00001 | 你好,很高兴见到你 | happy | spk_001 |

脚本首先读取 CSV 并验证每个 ID 是否存在对应的 WAV 文件。

import pandas as pd import os def load_and_validate_metadata(csv_path, wav_dir): df = pd.read_csv(csv_path) valid_samples = [] for _, row in df.iterrows(): wav_file = os.path.join(wav_dir, f"{row['id']}.wav") if not os.path.exists(wav_file): print(f"⚠️ 跳过缺失音频: {row['id']}") continue valid_samples.append(row.to_dict()) return pd.DataFrame(valid_samples)

✅ 阶段二:中文文本归一化(Text Normalization)

中文TTS中,数字、单位、日期等需转换为可读形式。例如:

  • "2024年""二零二四年"
  • "3.14""三点一四"

我们采用开源库cn2an和正则规则进行处理:

import re import cn2an def normalize_chinese_text(text): # 数字转中文 text = re.sub(r'\d+(\.\d+)?', lambda m: cn2an.an2cn(m.group()), text) # 常见缩写替换 text = text.replace("Mr.", "先生").replace("Dr.", "博士") # 去除不可读符号 text = re.sub(r'[^\u4e00-\u9fa5,。!?;:a-zA-Z]', '', text) return text.strip()

💡 提示:对于高精度场景,建议使用 ModelScope 自带的text/frontend.py中的前端处理器。


✅ 阶段三:音频重采样与格式校验

Sambert-Hifigan 默认使用24kHz 采样率,且仅支持.wav格式。我们需要确保所有音频符合要求。

from scipy.io import wavfile from pydub import AudioSegment def resample_audio(input_wav, output_wav, target_sr=24000): try: sr, data = wavfile.read(input_wav) if sr == target_sr and data.dtype == 'int16': os.rename(input_wav, output_wav) return True # 使用 pydub 更稳定地处理重采样 audio = AudioSegment.from_wav(input_wav) audio = audio.set_frame_rate(target_sr).set_sample_width(2) # 16bit audio.export(output_wav, format="wav") return True except Exception as e: print(f"❌ 音频处理失败 {input_wav}: {e}") return False

✅ 阶段四:构建标准输出文件(train.txt / val.txt)

完成预处理后,按比例划分训练集与验证集(如 95%/5%),生成最终列表文件。

from sklearn.model_selection import train_test_split def generate_manifest(df, output_dir, wav_output_dir, val_ratio=0.05): # 划分数据集 train_df, val_df = train_test_split(df, test_size=val_ratio, random_state=42) def write_manifest(df, filepath): with open(filepath, 'w', encoding='utf-8') as f: for _, row in df.iterrows(): wav_name = f"{row['id']}.wav" src_wav = os.path.join('raw_data/wavs', wav_name) dst_wav = os.path.join(wav_output_dir, f"{row['speaker']}/{wav_name}") # 创建子目录 os.makedirs(os.path.dirname(dst_wav), exist_ok=True) resample_audio(src_wav, dst_wav) relative_path = os.path.relpath(dst_wav, output_dir) normalized_text = normalize_chinese_text(row['text']) line = f"{relative_path}|{row['text']}|{normalized_text}|{row['speaker']}|{row['emotion']}\n" f.write(line) write_manifest(train_df, os.path.join(output_dir, 'train.txt')) write_manifest(val_df, os.path.join(output_dir, 'val.txt')) print("✅ 数据清单生成完毕!")

✅ 阶段五:一键打包与版本管理

最后,提供build_dataset.sh脚本封装全流程:

#!/bin/bash python preprocess.py \ --csv raw_data/metadata.csv \ --wav-dir raw_data/wavs \ --output-dir dataset \ --val-ratio 0.05

同时生成README.mdconfig.yaml,便于后续训练直接调用。


⚙️ 实践建议:如何适配你的项目?

1. 多情感标签的扩展性设计

若新增情感类型(如fear,surprise),只需在metadata.csv中添加对应标签,并在模型配置中更新num_emotions参数即可。

2. 支持批量说话人

通过speaker字段区分不同录音者,可轻松构建多说话人模型。注意保持每位说话人的样本数均衡,避免偏差。

3. 自动化流水线集成

建议将该工具嵌入 CI/CD 流程,每次新增语料时自动触发格式转换与完整性检查:

# .github/workflows/dataset-build.yml on: [push] jobs: build-dataset: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Run Preprocessor run: bash build_dataset.sh - name: Upload Artifact uses: actions/upload-artifact@v3 with: path: dataset/

🔍 常见问题与解决方案(FAQ)

| 问题 | 原因分析 | 解决方案 | |------|--------|----------| | 合成语音断句异常 | 文本未归一化,含英文标点或特殊字符 | 强化正则清洗逻辑,增加日志输出 | | 情感控制不明显 | 情感标签分布不均或标注不准 | 统计标签频率,人工抽检修正 | | 音频播放有杂音 | 重采样过程引入失真 | 改用librosa.resample+ dithering 技术 | | 训练报错“shape mismatch” | 归一化文本与原始长度差异大 | 添加长度过滤:len(norm_text) < 200|


🎯 总结:构建高质量TTS数据的第一步

本文介绍了一套完整的从普通文本到TTS训练专用格式的转换方案,特别适用于基于ModelScope Sambert-Hifigan的中文多情感语音合成任务。该工具具备以下优势:

✨ 核心价值总结: -标准化输出:严格遵循 ModelScope 推荐格式,开箱即用 -全流程覆盖:涵盖清洗、归一化、重采样、切分、清单生成 -工程友好:支持脚本化运行,易于集成进训练 pipeline -可扩展性强:灵活适配新说话人、新情感、新领域文本

结合文中提到的Flask WebUI + API 服务,开发者不仅可以快速训练模型,还能立即部署在线体验系统,形成“数据→训练→服务”的完整闭环。


📚 下一步建议

  1. 进阶优化:引入 G2P(Grapheme-to-Phoneme)工具提升发音准确性
  2. 质量评估:添加 MOS(Mean Opinion Score)抽样机制,监控数据质量
  3. 可视化工具:开发简易界面上传CSV并预览转换结果
  4. 对接ModelScope:将数据集注册为 ModelScope Dataset,便于共享与复现

🚀 最终目标:让每一位开发者都能用“干净的数据”,训练出“有感情的声音”。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 8:24:28

LinkedHashMap vs HashMap:性能对比与选择指南

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个性能对比项目&#xff0c;包含&#xff1a;1) 实现相同的缓存功能分别用HashMap和LinkedHashMap&#xff1b;2) 设计基准测试比较插入、查询、删除操作在100万数据量下的表…

作者头像 李华
网站建设 2026/4/2 12:07:58

LaTeX零基础:用Overleaf写出第一篇学术论文

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 设计一个交互式新手教程项目&#xff0c;包含&#xff1a;1. 分步式LaTeX语法指导 2. 常见错误自动检测与修复 3. 可视化公式编辑器 4. 参考文献向导工具 5. 实时预览与PDF导出指引…

作者头像 李华
网站建设 2026/4/16 7:03:44

elasticsearch晦涩难懂概念大全的庖丁解牛

Elasticsearch&#xff08;ES&#xff09;的“晦涩”源于其将 分布式系统、信息检索、近实时处理 三大复杂领域融合于单一产品。 1. 倒排索引&#xff08;Inverted Index&#xff09; ≠ 数据库索引 数据库索引&#xff08;B树&#xff09;&#xff1a; 文档ID → 内容&#x…

作者头像 李华
网站建设 2026/4/16 7:03:29

中小企业降本利器:开源TTS模型+CPU推理成本省70%

中小企业降本利器&#xff1a;开源TTS模型CPU推理成本省70% &#x1f4cc; 背景与痛点&#xff1a;语音合成的高成本困局 在智能客服、有声阅读、教育课件、AI主播等应用场景中&#xff0c;高质量中文语音合成&#xff08;Text-to-Speech, TTS&#xff09; 已成为不可或缺的技术…

作者头像 李华
网站建设 2026/4/16 7:05:06

零基础教程:5分钟学会创建自定义分辨率

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 制作一个极简的自定义分辨率设置工具&#xff0c;专为电脑新手设计。界面只需三个滑块&#xff1a;宽度、高度和刷新率。包含预设按钮&#xff08;推荐、游戏、影视&#xff09;&a…

作者头像 李华
网站建设 2026/4/16 7:05:06

Llama Factory微调+FastAPI部署:打造企业级AI服务原型

Llama Factory微调FastAPI部署&#xff1a;打造企业级AI服务原型 在企业AI项目中&#xff0c;快速验证大模型微调效果并构建可演示的API服务是PoC阶段的核心需求。本文将介绍如何利用Llama Factory和FastAPI&#xff0c;在三天内完成从数据准备到服务部署的全流程&#xff0c;打…

作者头像 李华