Fish Audio S2 Pro 已在 Novita AI 上作为托管 TTS API 上线,无冷启动延时。本快速入门涵盖开发者路径:获取 API 密钥、确认端点、使用克隆声音发送第一个 TTS 请求、理解声音克隆和情感控制的关键参数。S2 Pro 基于双自回归架构,并在大规模多语言语料库上训练——它区别于通用 TTS 的特性在于:您克隆的每个声音都可在所有支持的语言中使用,无需重新训练。
何时使用本快速入门
如果您需要以下功能,请使用本指南:
- 使用自定义克隆声音,在多种支持的语言中将文本合成为语音。
- 从 10–30 秒的音频样本克隆声音,并在后续请求中重复使用,无需额外按次付费。
- 通过自然语言括号标签(
[whisper]、[excited])在线控制韵律和情感。 - 构建需要多语言 TTS 且无需单独集成每种语言的流水线。
如果您只需要基础英语 TTS 并使用内置声音、无需克隆,请先评估 Fish Audio S1 模型 或 GLM TTS——当您需要跨语言克隆或精细情感控制时,S2 Pro 的优势才会体现。
第一步:获取 Novita API 密钥
创建一个 Novita AI 账户,并从 Novita AI 控制台 生成 API 密钥。将其存储为环境变量:
export NOVITA_API_KEY="your_api_key_here"
确保密钥不要出现在客户端代码、前端 bundle 或公开仓库中。
第二步:确认模型与端点
Novita AI 上 Fish Audio S2 Pro TTS 的文档位于 Fish Audio S2 Pro API 参考。在编码前,请在该参考中确认当前的端点路径和模型标识符——托管端点的 URL 和请求模式在该参考中已确认。
对于声音克隆,整个工作流使用 Novita 的三个端点:
| 步骤 | 方法 | 端点 |
|---|---|---|
| 上传音频样本 | POST |
https://api.novita.ai/v1/files |
| 创建克隆(异步) | POST |
https://api.novita.ai/v1/async/voice-cloning |
| 轮询获取结果 | GET |
https://api.novita.ai/v1/async/task-result |
| 使用克隆声音进行 TTS | POST |
https://api.novita.ai/v4beta/txt2speech |
声音克隆在创建克隆步骤使用 fish-audio-voice-cloning 模型,与 TTS 模型不同。
第三步:克隆声音
声音克隆需要三次 API 调用:上传一段短音频样本、创建克隆、然后获取 voice_id。获得 voice_id 后,您可以在 TTS 请求中无限次重复使用它,无需额外费用。
音频样本要求:
- 时长:10–30 秒效果最佳
- 格式:MP3 或 WAV
- 内容:清晰的语音,背景噪音尽量少
- 文本转录:提供样本中准确的口语文本可提高克隆质量
Python:完整克隆工作流
import base64
import os
import time
import requests
API_KEY = os.environ["NOVITA_API_KEY"]
BASE_URL = "https://api.novita.ai"
# Step 1: Upload audio file
with open("voice_sample.mp3", "rb") as f:
encoded_audio = base64.b64encode(f.read()).decode("utf-8")
upload_response = requests.post(
f"{BASE_URL}/v1/files",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"file": encoded_audio,
"purpose": "voice-cloning",
},
)
upload_response.raise_for_status()
file_id = upload_response.json()["file_id"]
print(f"Uploaded file ID: {file_id}")
# Step 2: Create the voice clone
clone_response = requests.post(
f"{BASE_URL}/v1/async/voice-cloning",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"model": "fish-audio-voice-cloning",
"audio_file_id": file_id,
"text": "Text spoken in the audio sample goes here.",
},
)
clone_response.raise_for_status()
task_id = clone_response.json()["task_id"]
print(f"Clone task ID: {task_id}")
# Step 3: Poll for the voice_id
voice_id = None
while True:
result = requests.get(
f"{BASE_URL}/v1/async/task-result",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"task_id": task_id},
).json()
if result["status"].endswith("SUCCEED"):
voice_id = result["result"]["voice_id"]
print(f"Cloned voice ID: {voice_id}")
break
elif "FAILED" in result["status"]:
raise RuntimeError(f"Clone failed: {result}")
time.sleep(2)
保存 voice_id。您将在每次 TTS 调用中将其用作 reference_id。
cURL:创建克隆(文件上传后)
curl -s -X POST https://api.novita.ai/v1/async/voice-cloning \
-H "Authorization: Bearer $NOVITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "fish-audio-voice-cloning",
"audio_file_id": "YOUR_FILE_ID",
"text": "Text spoken in the audio sample goes here."
}'
第四步:发送 TTS 请求
获得第三步的 voice_id 后,将其作为 reference_id 传入 TTS 请求。模型会以克隆的声音生成语音。
Python
import os
import requests
API_KEY = os.environ["NOVITA_API_KEY"]
VOICE_ID = "your_cloned_voice_id" # from Step 3
response = requests.post(
"https://api.novita.ai/v4beta/txt2speech",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"text": "Welcome to the demo. This voice was cloned from a short audio sample.",
"reference_id": VOICE_ID,
"format": "mp3",
"sample_rate": 44100,
},
)
response.raise_for_status()
audio_url = response.json()["audio_url"]
print(f"Audio URL: {audio_url}")
cURL
curl -s -X POST https://api.novita.ai/v4beta/txt2speech \
-H "Authorization: Bearer $NOVITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Welcome to the demo. This voice was cloned from a short audio sample.",
"reference_id": "YOUR_CLONED_VOICE_ID",
"format": "mp3",
"sample_rate": 44100
}'
响应中包含 audio_url —— 一个指向生成的音频文件的预签名 URL。
第五步:查看定价、限制和常见错误
定价(请访问 novita.ai/pricing 确认当前费率):
| 操作 | 价格 |
|---|---|
| TTS 生成 | ~$15.00 / 1M 字符 |
| 声音克隆 | 每个声音 $0.10(一次性) |
声音克隆按每个克隆一次性收费,而非按每次 TTS 请求收费。克隆后,在 TTS 调用中使用该 voice_id 只产生基于字符的 TTS 费率。
每次请求限制:
| 限制 | 值 |
|---|---|
| 最大输入长度 | 10,000 字符 |
| 推荐克隆样本时长 | 10–30 秒 |
| 支持的输出格式 | mp3、opus、wav、pcm |
| 音频采样率 | 最高 44,100 Hz |
常见错误:
| 错误 | 原因 | 修复 |
|---|---|---|
401 Unauthorized |
API 密钥无效或缺失 | 检查 NOVITA_API_KEY 是否已设置且正确 |
文件上传时 400 Bad Request |
音频文件太大或格式错误 | 使用 MP3/WAV,保持文件在数 MB 以内 |
克隆任务状态 FAILED |
音频样本太短或噪音太大 | 使用 10–30 秒的清晰语音 |
| 音频为空或混乱 | text 字段为空或超过限制 |
保持输入在 10,000 字符以内 |
情感控制标签
S2 Pro 支持使用 [bracket] 标签来控制模型呈现特定词或短语的方式。这些标签在生成时被解释为自然语言指令——您不限于固定的令牌列表。
text_with_emotion = (
"[cheerful] Welcome back! [pause] "
"I'm really glad you're here. "
"[whisper] Just between us, this part is a secret. [normal] "
"Anyway, let's get started."
)
response = requests.post(
"https://api.novita.ai/v4beta/txt2speech",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"text": text_with_emotion,
"reference_id": VOICE_ID,
"format": "mp3",
"sample_rate": 44100,
},
)
模型可理解的括号标签示例:
| 标签 | 效果 |
|---|---|
[whisper] |
低语般的发音 |
[excited] |
更高能量、更快语速 |
[calm] |
缓慢、沉稳的语调 |
[laughs] |
在语音中嵌入笑声 |
[professional broadcast tone] |
新闻播报风格 |
[pitch up] |
提高后续文字的语调 |
[pause] |
短暂停顿 |
标签是自由形式的描述,而非固定的枚举值。模型从训练数据中学习了标签到声学特征的映射,因此描述性短语同样有效。请根据您的用例试验特定标签;使用不常见的措辞时效果可能有所差异。
关键参数
| 参数 | 类型 | 说明 |
|---|---|---|
text |
string | 必填。最多 10,000 字符。 |
reference_id |
string | 必填。声音模型 ID —— 克隆的 voice_id 或系统声音引用。 |
format |
string | 输出格式:mp3、opus、wav、pcm。默认:mp3。 |
sample_rate |
integer | 音频采样率(Hz)。建议 44100 以获得高保真度。 |
temperature |
number | 控制生成随机性。值越大,韵律变化越多。 |
top_p |
number | 核采样阈值。 |
有关完整的参数模式及任何额外的 S2 Pro 专属选项,请查阅 Novita AI Fish Audio S2 Pro API 参考。
故障排查
克隆的声音听起来机械或不一致。
样本可能太短或存在背景噪音。录制一段 20–30 秒的清晰片段,语速一致且无重叠。在克隆请求中提供样本的精确 text 文本转录可以提高音素对齐质量。
轮询后音频 URL 返回 404。 预签名 URL 有过期时间。收到 URL 后请尽快下载或处理音频。
情感标签未产生预期效果。
标签行为取决于训练数据分布。尝试更具描述性的措辞——例如使用 [very softly, barely audible] 而非 [quiet]。某些标签效果更好;先用短文本测试。
克隆任务状态保持为 pending。
增加轮询间隔(每次检查间隔 1–2 秒)以避免对任务结果端点进行限流。如果任务超过两分钟仍处于 pending 状态,请检查文件上传步骤——file_id 可能已过期。
需要在不同语言中使用同一声音。
将相同的 voice_id 与任何支持语言的文本一起传入即可。S2 Pro 会将克隆的声音音色应用于新语言,无需单独再克隆。请查看 S2 Pro API 参考 以获取当前支持的语言列表。
FAQ
S2 Pro 与 Fish Audio S1 有何不同? S2 Pro 使用更大的双自回归架构,并在大规模多语言语料库上训练。实际差异:更广泛的语言支持、通过括号标签实现的情感控制、以及 S1 不具备的多说话人合成能力。请参见 S2 Pro API 参考 了解当前语言列表。
我可以克隆一次声音并将其用于所有支持的语言吗?
可以。从英语样本克隆的声音可以使用相同的 voice_id 生成日语、西班牙语、阿拉伯语或任何其他支持语言的语音。模型无需额外训练即可跨语言迁移声音音色。
声音样本应该多长? 10–30 秒的清晰、一致的语音。较短的样本也可使用,但效果可能不稳定。超过 30 秒的样本不会显著提高克隆质量。
声音克隆是否按每次 TTS 请求收费?
不。$0.10 的声音克隆费是每个克隆的一次性费用。创建后,在 TTS 请求中使用该 voice_id 仅产生基于字符的 TTS 费率。
如果我省略 reference_id 会怎样?
请查看 S2 Pro API 参考 了解当前默认行为——模型可能使用默认声音或要求提供引用。
如何获取 API 密钥? 在 novita.ai 注册,并从 Novita AI 控制台 生成密钥。
