2026/10/10 11:51:42

不想撞音色?给 AuK 微调一条专属声线,从数据准备到部署的完整手记

不想撞音色?给 AuK 微调一条专属声线,从数据准备到部署的完整手记 不想撞音色给 AuK 微调一条专属声线从数据准备到部署的完整手记【免费下载链接】AuK项目地址: https://ai.gitcode.com/tencent_hunyuan/AuK开源语音生成模型在 2026 年迎来了一波集中爆发腾讯混元开源的 AuK 是其中最受关注的一个1.5B 参数、MIT 协议、16 类语音任务全部收进同一个自然语言指令接口。社区里的实测帖普遍给出同一个结论——零样本复刻惊艳但惊艳和稳定是两回事。靠参考音频克隆声线会随指令措辞、上下文和文本长度漂移而做电台主播、角色配音、语音助手这类需要固定人设的落地场景你必须把声线焊死进权重里。这正是 AuK 仓库里那条轻量微调管线存在的意义。本文不打算重复泛泛的如何微调大模型教程而是基于仓库内的真实代码src/auk/train/train.py、docs/FINETUNING.md、scripts/train.sh把准备数据 → 跑微调 → 部署专属声线的完整链路走一遍包括那些文档里没明说、但代码里写得很清楚的门道。先厘清一个事实零样本克隆与专属声线是两件事AuK 的定位是统一语音生成与编辑基础模型。它用一套 ChatML 风格的多模态消息格式承接所有任务user消息携带自然语言指令和可选的参考/源音频模型据此生成目标语音。架构上是三段式拼装——Qwen2.5-Omni-3B 作为指令编码器负责理解人话Flux2EditCFMEdit扩散主干负责在流匹配框架下生成声学表征BigVGANFlowVAE 负责把潜变量解码回 24kHz 波形生成主干仅 1.5B 参数零样本 TTS 的工作方式是现挂每次推理都喂一段参考音频模型在推理时条件化这条声线。它的优点是零成本缺点是三个声线不稳定参考音频与目标文本越长、越复杂音色保持越容易抖动社区实测中常见的说着说着换人就属于这一类依赖每次调用都携带参考音频接口、缓存、批处理都要多管理一类输入工程上繁琐人设不可固化你无法告诉模型这个人物的声音永远是这样只能反复给参考。微调解决的正是这个问题。AuK 的微调把目标声线的特征压进生成主干与条件融合层的权重里训练完成后一句指令就是一条声线不需要再带参考音频当然也可以继续带。仓库官方示例的默认数据集路径是agent_space/genshin_zh/train.jsonl——角色声线微调本来就是官方预期的头号场景。基线能力可以看官方基准图微调是在这套能力之上做专属化数据准备保住自然度的三条铁律微调效果的上限由数据决定超参只决定你能多接近这个上限。AuK 的微调数据格式只有一个但每条样本都有三条硬规则。铁律一一条样本 指令 音频对结构一个都不能错训练数据是JSONL每行一个 source→target 样本。核心字段是duration和messages{ duration: 5.66, messages: [ { role: user, content: [ {type: text, text: Say the following with the same voice: \你好这是一次语音合成测试。\}, {type: audio, audio_url: /abs/path/ref.wav} ] }, { role: assistant, content: [ {type: audio, audio_url: /abs/path/target.wav} ] } ] }逐条拆解duration是目标音频的秒数浮点数必填。它不只是一个统计字段而是直接驱动动态批处理的关键量后面会展开user消息装指令文本text需要条件时再挂一条audio/audio_url指参考或源音频assistant消息装目标音频即模型应当生成的结果音频路径推荐用绝对路径audio_url和audio两个 key 都认训练加载时自动转单声道并重采样到 24kHz所以源文件采样率随意。一个容易被忽略的细节藏在 src/auk/train/train.py 的AukJsonlDataset.__getitem__里对于没有参考音频的纯指令型任务如描述式 TTS代码会在指令文本末尾自动追加|no_prompt_audio|标记告诉条件编码器这次没有参考音频。这意味着你写训练 JSONL 时不需要手工加这个标记但如果你构造样本时混用了有无参考音频两种形态要意识到模型内部对它们的处理路径是不同的。铁律二音频质量决定上限长度有硬边界AukJsonlDataset.load_wav的处理管线是torchaudio.load→ 多声道降混为单声道 → 重采样到 24kHz。除此之外模型不做任何清洗。所以进训练集的音频必须你自己先保证干净目标音频assistant 侧必须是理想答案。有底噪、房间混响、削波爆音的 target模型会原样学进去合成时把这些缺陷当作声线的一部分复读出来利用 AuK 自己当清洗工这正好是它的主场。语料有底噪就用语音增强指令Preserve all speakers, remove noise and reverberation...过一遍混叠了伴奏就用音源分离把纯人声抽出来再当训练 target。用自家模型清洗自家训练集形成正循环长度有硬边界0.3s 到 30s。DynamicBatchSampler在构建批次时会把窗口外的样本直接丢弃——min_frame_length 0.3 × 24000 / 480max_frame_length 30 × 24000 / 480超出的样本静默跳过不会报错。如果你的duration字段填错样本可能整条被无声丢弃训练半天 loss 没动静还找不到原因。铁律三指令要像推理时那样写多样性要够微调的本质是让模型学会把你的指令映射到目标音频。因此训练指令的写法必须和推理时一致。AuK 的指令模板集中在 docs/COOKBOOK.md零样本 TTS 的官方模板就是一行Say the following with the same voice: {text}照着官方模板写训练数据是最稳的起点。但注意两件事多样性才是自然度的来源如果 500 条样本全是同一句式、同一情绪、同一语速模型会把这个窄分布当成声线的全部特征推理时稍微换一种措辞/情绪就露馅。为专属声线准备数据时应当覆盖目标声线会出现的真实场景——不同情绪、不同语速、不同文本风格甚至小声耳语与大声喊叫的对比duration必须逐条准确。它直接换算成 VAE 潜变量帧数参与批次打包误差大轻则浪费显存、重则把样本挤出 0.3s–30s 窗口留一份独立的val.jsonl最好包含推理时会遇到的真实样本形态比如一条更长、情绪更丰富的语音。训练脚本会用它做周期性验证和样本合成它是你判断自然度有没有保住的客观依据。微调流程与超参经验环境与启动一套 DDP bf16 的轻量管线微调依赖在基础安装之外多三个包ema-pytorch、tensorboard、matplotlib即 pyproject.toml 里的[train]extrapip install -e .[train]官方入口是 scripts/train.sh内部用accelerate launch拉起 DDP 训练bf16 混合精度。值得先讲清楚哪些参数参与训练默认只更新 AuK 生成主干扩散 Transformer和条件融合层的参数Qwen2.5-Omni 指令编码器与 VAE 全程冻结。这是刻意的设计——指令理解能力是通用知识不需要为一条声线重训VAE 是声码器更与声线无关。1.5B 主干 冻结编码器让单机多卡微调成为可能。启动前把 scripts/train.sh 顶部的路径改成你自己的train_jsonl/path/to/train.jsonl val_jsonl/path/to/val.jsonl configckpts/AuK/config.yaml init_ckptckpts/AuK/auk_base.safetensors output_dirckpts/auk_finetune num_gpus8然后bash scripts/train.sh即可。脚本会把本次运行的完整命令快照成output_dir/时间戳_run.sh方便事后回溯实验。动态批处理与显存账本AuK 微调没有固定 batch size这是它和普通 LLM 微调最大的区别。DynamicBatchSampler按潜变量帧长排序样本然后贪心打包直到达到frames_threshold每 GPU 每 batch 的帧数上限同时受max_samples硬顶约束。换算关系潜变量帧 ≈ 时长 × 24000 / 480VAE 对 24kHz 音频做了 480 倍下采样即 50Hz 潜变量帧率所以默认frames_threshold2700≈每 GPU 每 batch 打包约 54 秒音频。显存账本上有两组数字值得记住config.yaml 里已默认开启激活重计算checkpoint_activations: True每 4 层一个检查点注释标注的收益是峰值显存从约91G 降到约 75GOOM 时的处理顺序是先降--frames_threshold再降--max_samples批大小不足时用--gradient_accumulation_steps补。不要一上来就动 batch 概念里不存在的batch_size——这个管线里没有这个超参。推理侧的显存参考同样在 README 里A800-SXM4-80GB、bf16 推理基座峰值约 24.78 GiB开启--cpu_offload后降到约 16.75 GiB省约 32%。微调完推理可以无缝复用这套 offload 机制。超参速查表默认值全部来自 src/auk/train/train.py 的TrainConfig数据类超参默认值说明与经验--learning_rate2e-5AdamWbetas(0.9, 0.95)。微调一般不动收敛慢就先降它--max_grad_norm1.0梯度裁剪阈值0 表示关闭--num_train_epochs200小数据集要大幅下调几百条样本跑几十个 epoch 就够--warmup_steps100线性 warmup实际步数会乘 GPU 数--frames_threshold2700每 GPU 每 batch 的帧数≈54 秒音频显存主旋钮--max_samples8每 batch 样本数硬顶0 表示不限--ema_beta0.9999EMA 衰减系数--save_per_updates1000快照model_{update}.pt的保存间隔--val_per_updates200验证 样本合成的间隔需配val_jsonl--seed666随机种子也控制批次洗牌学习率调度是线性 warmup 到目标值再线性衰减回零。微调最常动的是--learning_rate、--num_train_epochs、--frames_threshold和验证/保存节奏其余保持默认即可。监控与续训EMA 才是你要部署的权重配了val_jsonl后训练每val_per_updates步会做两件事计算 per-t 验证损失在t ∈ {0.0, 0.1, …, 0.9}网格上逐点评估流匹配损失同一 batch 内共享噪声让曲线只反映 t 的影响输出到控制台、TensorBoard并画成val_curves/update_{N}.png合成一段样本从第一个验证 batch 取样本生成语音写入samples/update_{N}_gen.wav与_tgt.wav成对保存——这是最直接的自然度体检报告每个验证节点都能直接听。tensorboard --logdir ckpts/auk_finetune/tensorboard检查点与续训有几个必须知道的机制自动续训output_dir里一旦存在model_last.pt训练会自动从它恢复模型 EMA 优化器 调度器 步数并跳过init_ckpt冷启动。想要从基座权重全新开跑用一个新的空output_dirEMA 是部署权重整个训练过程维护一份指数滑动平均权重推理加载的是 EMA 而非在线权重missing text_encoder.*是预期行为检查点故意不含 Qwen 编码器和 VAE运行时单独加载日志里的这些 missing key 不是错误只有非text_encoder.前缀的缺失才值得警惕。部署与使用把专属声线接进推理管线换权重即换声线CLI 一行微调产物是.pt文件。部署时唯一的变化就是换 checkpoint 路径——推理代码 src/auk/infer/infer_auk.py 会自动从训练.pt里读取 EMA 权重剥离ema_model.前缀你完全不用关心权重格式差异auk-infer \ --ckpt ckpts/auk_finetune/model_last.pt \ --audio assets/ref.wav \ --instruction Say the following with the same voice: Ladies and gentlemen, its an honor to have the opportunity to address such a distinguished audience \ --output out.wav \ --gen_seconds 6.0VAE 会自动从 checkpoint 同目录探测探测不到才回退到 config.yaml 里的路径。Python API两行代码接入任意任务from auk.infer.infer_auk import AukInfer, save_audio engine AukInfer( ckpts/AuK/config.yaml, ckpts/auk_finetune/model_last.pt, ) messages [{ role: user, content: [ {type: text, text: Say the following with the same voice: 欢迎回来今天上班累不累呀}, {type: audio, audio: assets/ref.wav}, ], }] audio, sr engine.generate(messages, gen_seconds4.0) save_audio(audio, sr, out.wav)微调不会改变任务接口本身——换权重之后docs/COOKBOOK.md 里那 16 类任务零样本 TTS、内容编辑、音高/语速/音量编辑、情绪/音色/去口音、增强与分离……依然全部可用。专属声线微调的收益在推理侧体现为同类任务、同类指令输出声线从概率性地像变成确定性地是且不再强依赖参考音频。服务化与加速选项如果要把微调后的声线模型做成服务仓库生态已经给了从轻到重的选项Gradioauk-gradio一条命令起 Web 界面微调权重同样可以直接指定--base_ckpt ckpts/auk_finetune/model_last.ptSGLang-Omni官方 Day-0 支持python -m sglang_omni.cli serve --model-path即可社区在此基础上还推进了 AuK 的推理优化路线图vLLM-Omni把 AuK 与 AuK-Flash 拼成两阶段流水线官方配方在单张 H100 上可跑边缘/离线audio.cpp的 GGUF 离线推理、Apple Silicon 上的 MLX 支持都已经就位且仓库近期通过 PR 把编码器显存压了约 7.5 GiB——消费级显卡跑微调后的声线模型越来越现实。关于 AuK-Flash 的一个权衡Flash 是 4 步固定步数、CFG0 的蒸馏变体社区拆读实测相对基座可提速约 4.5 倍适合对延迟敏感的在线场景基座则保留可配置 NFE/CFG 的高质量上限。如果你的专属声线要的是极致一致性和音质优先基于基座微调要低延迟再评估在 Flash 上重复微调流程。效果验证与迭代闭环部署不是终点。基于训练产出的samples/合成音频做主观听感评估是微调迭代的核心反馈发现某类句子音色不稳就往train.jsonl里补这类句子再续训发现语速单一就补不同语速的样本。EMA 快照与自动续训机制让这个闭环成本很低——不用从头训接着跑就行。最后提醒两条社区实测里反复出现的边界一是单次输入存在约 30 秒的时长上限ComfyUI 集成还会校验源目标的总预算超长文本要分段二是情绪编辑的成功率仍偏低技术报告口径约 9.94%这类副语言能力属于模型通用能力的短板微调一条声线解决不了模型没学会的情绪表达。专属声线微调的职责边界很清楚把音色一致性从概率问题变成确定性事实剩下的能力边界交给模型本身。数据质量决定微调上限指令一致性决定迁移效率EMA 权重决定部署手感。把这三件事做扎实一条稳定的专属声线从数据到部署不过是一个train.sh加一个--ckpt的距离。【免费下载链接】AuK项目地址: https://ai.gitcode.com/tencent_hunyuan/AuK创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考