说话人嵌入持久化——保存字符串复用同一音色
为什么要持久化
随机采样出的音色可能恰好很好听、很适合某个角色。下次跑脚本时如果不持久化,又会采样出完全不同的音色——之前的好结果就丢了。
保存到文件
rand_spk = chat.sample_random_speaker()
# 保存到 JSON 文件
import json
with open('speaker.json', 'w', encoding='utf-8') as f:
json.dump({'speaker': rand_spk}, f)
从文件加载
import json
with open('speaker.json', 'r', encoding='utf-8') as f:
data = json.load(f)
rand_spk = data['speaker']
# 直接复用
wavs = chat.infer(
"这段语音会和之前的音色完全一致。",
params_infer_code=ChatTTS.Chat.InferCodeParams(spk_emb=rand_spk)
)
为什么这样可行
sample_random_speaker() 返回的字符串是说话人嵌入向量的 JSON 序列化——它已经是一个确定的向量了,加载后直接喂给模型就行,不需要再"采样"。
典型应用场景
角色配音的一致性
# 第一次:为角色 A 采样并保存
alice_spk = chat.sample_random_speaker()
with open('characters/alice.json', 'w') as f:
f.write(alice_spk)
# 后续所有 alice 的台词都复用这个嵌入
for line in alice_dialogues:
wavs = chat.infer(line, params_infer_code=ChatTTS.Chat.InferCodeParams(
spk_emb=open('characters/alice.json').read()
))
批量生产复用
# 第一次运行:采样并保存
default_spk = chat.sample_random_speaker()
open('default_speaker.txt', 'w').write(default_spk)
# 后续运行:直接读取,不再采样
default_spk = open('default_speaker.txt').read()
注意
- 说话人嵌入字符串大约几百字节,存起来毫无压力
- 不同模型版本之间嵌入格式可能有差异——如果升级了 ChatTTS 版本,之前保存的字符串可能不再兼容(此时重新采样即可)
- 嵌入是在
sample_random_speaker()所在进程的模型上采样的——不同进程、不同设备上采样出的字符串可以跨设备复用