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 の利点は、言語横断的なクローンやきめ細かい感情制御が必要な場合に発揮されます。
ステップ 1: Novita API キーを取得する
Novita AI アカウントを作成し、Novita AI コンソール から API キーを生成します。環境変数として保存します。
export NOVITA_API_KEY="your_api_key_here"
キーはクライアントサイドコード、フロントエンドバンドル、パブリックリポジトリに保存しないでください。
ステップ 2: モデルとエンドポイントを確認する
Fish Audio S2 Pro TTS の Novita AI ドキュメントは、Fish Audio S2 Pro API リファレンス にあります。コーディングする前に、そこで現在のエンドポイントパスとモデル識別子を確認してください。ホスト型エンドポイントの URL とリクエストスキーマは、そのリファレンスで確認されています。
音声クローンの場合、ワークフロー全体で 3 つの 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 |
音声クローンでは、クローン作成ステップに TTS モデルとは別の fish-audio-voice-cloning モデルを使用します。
ステップ 3: 音声をクローンする
音声クローンには 3 つの 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."
}'
ステップ 4: TTS リクエストを送信する
ステップ 3 で voice_id を取得したら、それを TTS リクエストの reference_id として渡します。モデルはクローンされた音声で音声を生成します。
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
}'
レスポンスには、生成された音声ファイルを指す署名付き URL である audio_url が含まれます。
ステップ 5: 料金、制限、および一般的なエラーを確認する
料金(最新の料金は novita.ai/pricing で確認してください):
| 操作 | 価格 |
|---|---|
| TTS 生成 | 約 $15.00 / 100 万文字 |
| 音声クローン | 音声あたり $0.10(1 回限り) |
音声クローンはクローンごとに 1 回課金され、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 文字起こしを提供すると、音素アライメントが向上します。
ポーリング後に Audio URL が 404 を返す。 署名付き URL は期限切れになります。URL を受け取ったら、すぐに音声をダウンロードまたは処理してください。
感情タグが期待した効果を生み出さない。
タグの動作はトレーニングデータの分布に依存します。[quiet] の代わりに [very softly, barely audible] など、より説明的な言い回しを試してみてください。一部のタグは他のタグよりもうまく機能します。最初は短い入力でテストしてください。
クローンタスクのステータスが保留状態のままである。
タスク結果エンドポイントのレート制限を避けるために、ポーリング間隔(チェック間に 1~2 秒)を追加してください。タスクが 2 分以上保留状態が続く場合は、ファイルアップロード手順を確認してください。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 の音声クローン料金は、クローンごとの 1 回限りの料金です。作成後、TTS リクエストでその voice_id を使用する場合のコストは、文字単位の TTS レートのみです。
reference_id を省略するとどうなりますか?
現在のデフォルトの動作については、S2 Pro API リファレンス を確認してください。モデルはデフォルトの音声を使用するか、リファレンスを必要とする場合があります。
API キーを取得するにはどうすればよいですか? novita.ai にサインアップし、Novita AI コンソール からキーを生成してください。
