🔊文本到语音 (TTS) 微调指南
了解如何使用 Unsloth 微调 TTS 与 STT 语音模型。
微调 TTS 模型可以让它们适应您特定的数据集、用例或期望的风格与语气。目标是定制这些模型以克隆声音、调整说话风格和语气、支持新语言、处理特定任务等。我们也支持 语音转文本 (STT) 模型,例如 OpenAI 的 Whisper。
使用 Unsloth,您可以微调 任何 TTS 模型(兼容 transformers )比其他使用 Flash Attention 2 的实现快 1.5 倍并节省 50% 内存。
⭐ Unsloth 支持任何 兼容 transformers 兼容的 TTS 模型。 即使我们还没有为其提供笔记本或上传,它仍然受支持,例如可以尝试微调 Dia-TTS 或 Moshi。
零样本克隆能捕捉音色但常常错过语速和表达,往往听起来机械且不自然。微调能提供更准确、更真实的语音复刻。 在此阅读更多信息.
微调 笔记本:
我们还将 TTS 模型(原始和量化版)上传到我们的 Hugging Face 页面.
如果您注意到输出时长最大为 10 秒,请将max_new_tokens = 125 提高到高于默认值 125。由于 125 个 token 对应约 10 秒音频,若需更长输出请设置更高的值。
选择并加载 TTS 模型
对于 TTS,通常偏好较小模型以降低延迟并为最终用户提供更快的推理速度。微调参数量低于 3B 的模型通常是理想的,我们的主要示例使用 Sesame-CSM(1B)和基于 Llama 的 Orpheus-TTS(3B)。
Sesame-CSM(1B) 详情
CSM-1B 是一个基础模型,而 Orpheus-ft 是在 8 位专业配音演员上微调的,使得语音一致性成为主要区别。CSM 在每个说话者需要音频上下文才能表现良好,而 Orpheus-ft 则内建了这种一致性。
从像 CSM 这样的基础模型微调通常需要更多计算,而从像 Orpheus-ft 这样的已微调模型开始则能开箱即用地获得更好结果。
为了帮助 CSM,我们增加了新的采样选项和示例,展示如何使用音频上下文以改善语音一致性。
Orpheus-TTS(3B) 详情
Orpheus 在大量语音语料上进行预训练,擅长生成逼真的语音并内建对笑声、叹息等情感提示的支持。其架构使其成为最容易使用和训练的 TTS 模型之一,并且可以通过 llama.cpp 导出,这意味着它在各种推理引擎中具有良好兼容性。对于不受支持的模型,您只能保存 LoRA 适配器的 safetensors。
加载模型
因为语音模型通常体积较小,您可以使用 LoRA 16 位或全量微调(FFT)来训练模型,这可能会带来更高的质量。要以 LoRA 16 位加载:
当这段运行时,Unsloth 会下载模型权重,如果您更喜欢 8 位,可以使用 load_in_8bit = True,或者若要进行完整微调设置 full_finetuning = True (确保您有足够的显存)。您也可以将模型名称替换为其他 TTS 模型。
注意: Orpheus 的分词器已经包含用于音频输出的特殊标记(稍后会详细说明)。您 不 需要单独的声码器——Orpheus 将直接输出音频标记,这些标记可以解码为波形。
准备您的数据集
至少,一个 TTS 微调数据集由 音频片段及其对应的转录文本 (文本)组成。我们来使用 Elise 数据集 该数据集是约 3 小时的单说话者英语语音语料。有两个变体:
MrDragonFox/Elise——一个增强版本,转录中嵌入了 情感标签 (例如 <sigh>、<laughs>)。这些尖括号中的标签表示表情(笑声、叹息等),并被 Orpheus 的分词器视为特殊标记Jinsaryko/Elise——基础版本,转录不含特殊标签。
数据集的组织方式是每条记录包含一个音频和对应的转录。在 Hugging Face 上,这些数据集有诸如 audio (波形), text (转录文本),以及一些元数据(说话者姓名、音高统计等)字段。我们需要向 Unsloth 提供一组音频-文本配对的数据集。
与其单纯关注音色、节奏和音高,优先事项应是确保您的数据集已完全注释并适当规范化。
对于某些模型,例如 Sesame-CSM-1B,您可能会注意到在使用说话者 ID 0 时生成结果存在语音差异,因为它是一个 基础模型——它没有固定的声音身份。说话者 ID 标记主要有助于保持 对话内一致性,而不是跨独立生成的一致性。
要获得一致的语音,请提供 上下文示例,例如一些参考音频片段或先前的发言。这有助于模型更可靠地模仿目标声音。没有这些,即使使用相同的说话者 ID,也会出现变化。
选项 1:使用 Hugging Face Datasets 库 ——我们可以使用 Hugging Face 的 datasets 库加载 Elise 数据集:
这将下载数据集(约 ~328 MB,约 1.2k 个样本)。每个条目 数据集 是一个至少包含以下项的字典:
"audio":音频片段(波形数组和诸如采样率的元数据),以及"text":转录字符串
Orpheus 支持类似于 <laugh>, <chuckle>, <sigh>, <cough>, <sniffle>, <groan>, <yawn>, <gasp>等标签。例如: "I missed you <laugh> so much!"。这些标签用尖括号括起,将被模型视为特殊标记(它们与 Orpheus 期望的标签 如 <laugh> 和 <sigh>相匹配)。在训练期间,模型会学会将这些标签与相应的音频模式关联。带标签的 Elise 数据集中已经有许多此类标签(例如卡片中列出有 336 次 “laughs”、156 次 “sighs” 等)。如果您的数据集中缺少这些标签但您想要加入它们,您可以在音频包含这些表情时手动为转录添加注释。
选项 2:准备自定义数据集 ——如果您有自己的音频文件和转录:
将音频片段(WAV/FLAC 文件)组织到一个文件夹中。
创建一个带有文件路径和转录列的 CSV 或 TSV 文件。例如:
使用
load_dataset("csv", data_files="mydata.csv", split="train")来加载它。您可能需要告诉数据集加载器如何处理音频路径。另一种方法是使用datasets.Audio特性以按需加载音频数据:然后
dataset[i]["audio"]将包含音频数组。确保转录文本已规范化 (没有分词器可能不认识的异常字符,若使用则除外情感标签)。同时确保所有音频具有一致的采样率(如有必要,请重新采样到模型期望的目标采样率,例如 Orpheus 的 24kHz)。
总之,对于 数据集准备:
您需要一个 (音频,文本) 的列表。
使用 HF
datasets库来处理加载和可选的预处理(例如重采样)。在文本中包含任何您希望模型学习的 特殊标签 (确保它们以
<angle_brackets>格式出现,以便模型将其视为独立标记)。(可选)如果是多说话者,您可以在文本中包含说话者 ID 标记或使用单独的说话者嵌入方法,但这超出了本基础指南的范围(Elise 是单说话者)。
使用 Unsloth 微调 TTS
现在,让我们开始微调!我们将通过 Python 代码来说明(可在 Jupyter 笔记本、Colab 等中运行)。
步骤 1:加载模型和数据集
在我们所有的 TTS 笔记本中,我们启用了 LoRA(16 位)训练并禁用了 QLoRA(4 位)训练,设置为: load_in_4bit = False。这样模型通常能更好地学习您的数据集并获得更高的准确性。
如果内存非常有限或数据集很大,您可以流式加载或分块加载。这里 3 小时的音频很容易放入内存。如果使用您自己的 CSV 数据集,也以类似方式加载。
步骤 2:高级 - 训练前对数据进行预处理(可选)
我们需要为 Trainer 准备输入。对于文本到语音,一种方法是以因果方式训练模型:将文本和音频 token ID 连接为目标序列。然而,由于 Orpheus 是一个仅解码器的 LLM,会输出音频,我们可以将文本作为输入(上下文)并将音频 token id 作为标签。实际上,如果模型配置将其识别为文本到语音,Unsloth 的集成可能会自动完成此操作。如果没有,我们可以做类似:
以上是简化说明。实际上,要正确微调 Orpheus,您需要 将音频 token 作为训练标签的一部分。Orpheus 的预训练很可能涉及将音频转换为离散 token(通过某种音频编码器)并训练模型在给定前文文本时预测这些 token。要在新语音数据上微调,您同样需要为每个片段获取音频 token(使用 Orpheus 的音频编码器)。Orpheus 的 GitHub 提供了一个数据处理脚本——它会将音频编码为一系列 <custom_token_x> token。
然而, Unsloth 可能会将此抽象化处理:如果模型是具有相关处理器的 FastModel,且该处理器知道如何处理音频,那么它可能会自动将数据集中的音频编码为 token。如果没有,您将不得不手动将每个音频片段编码为 token ID(使用 Orpheus 的码本)。这是超出本指南范围的高级步骤,但请记住仅使用文本 token 无法教会模型真实的音频模式——它需要匹配音频模式。
假设 Unsloth 提供了一种直接传入音频的方法(例如,通过设置 processor 并传入音频数组)。如果 Unsloth 还不支持自动音频分词,您可能需要使用 Orpheus 仓库的 encode_audio 函数来获取音频的 token 序列,然后将其用作标签。(数据集条目确实包含 phonemes 和一些声学特征,这表明存在一条处理流水线。)
步骤 3:设置训练参数和 Trainer
我们使用 60 步以加速,但您可以设置 num_train_epochs=1 以进行完整训练,并将 max_steps=None关闭。若使用 per_device_train_batch_size >1 在多 GPU 设置下可能导致错误;为避免问题,请确保将 CUDA_VISIBLE_DEVICES 设置为单个 GPU(例如 CUDA_VISIBLE_DEVICES=0)。根据需要调整。
步骤 4:开始微调
这将启动训练循环。您应该每 50 步看到一次损失日志(由 logging_steps设置)。训练可能需要一些时间,取决于 GPU——例如在 Colab 的 T4 GPU 上,对 3 小时数据训练几个 epoch 可能需 1-2 小时。Unsloth 的优化会比标准的 HF 训练更快。
步骤 5:保存微调后的模型
训练完成后(或在您觉得足够时中途停止),保存模型。此操作仅保存 LoRA 适配器,而不是完整模型。要保存为 16bit 或 GGUF,请向下滚动!
这会保存模型权重(对于 LoRA,若基础模型未完全微调,可能只会保存适配器权重)。如果您在 CLI 中使用了 --push_model 或调用了 trainer.push_to_hub(),则可以将其直接上传到 Hugging Face Hub。
现在您应该在目录中拥有一个微调后的 TTS 模型。下一步是测试它,如果支持,您可以使用 llama.cpp 将其转换为 GGUF 文件。
微调语音模型 vs. 零样本语音克隆
有人说使用像 XTTS 这样的模型只需 30 秒音频即可克隆声音,无需训练。这从技术上来说是真的,但这并未触及要点。
零样本语音克隆(在 Orpheus 和 CSM 等模型中也可用)是一种近似。它能捕捉说话者的总体 音色与音质 ,但不会再现完整的表达范围。您会失去诸如说话速度、措辞、语音习性以及韵律的微妙之处——这些构成了语音的 个性与独特性.
如果您只想要一个不同的声音并且对相同的表达模式无所谓,零样本通常足够。但语音仍会遵循 模型的风格,而不是说话者本身的风格。
对于任何更个性化或更具表现力的需求,您需要使用诸如 LoRA 之类的方法进行训练,以真正捕捉某人的说话方式。
最后更新于
这有帮助吗?

