text-to-speech について
text-to-speechは、PythonやJavaScript/TypeScriptからSarvam Bulbulの音声合成を組み込むためのSDKスキルです。モデルや音声の選択、リクエスト方法、制限事項を扱います。
主な機能
- 01Bulbul v4 Flashとv3の解説
- 02多言語音声の選び方
- 03RESTとストリーミングの例
- 04パラメーター制限と注意点
活用シーン
- 01アプリへの音声合成の組み込み
- 02HTTPストリーミングやWebSocketでの音声生成
- 03多言語テキストに合う音声の選択
MCP 対応
READMEによると、チャット内のTTSはsarvam-mcpの`sarvam_tools_tts_*`が担い、このスキルはSDKコードを扱います。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sarvamai/ skills --skill text-to-speechインストール後、Claude Code で/text-to-speechを入力して読み込まれたか確認します。
詳細
テキスト読み上げ — Bulbul
チャット内でのリアルタイム TTS → sarvam-mcp(
sarvam_tools_tts_*)。このスキルはSDK コードです。
重要
認証:
api-subscription-keyヘッダーを使用します。Authorization: Bearerではありません。ベース URL:https://api.sarvam.ai(/v1ではありません。このプレフィックスは OpenAI 互換チャットエンドポイント専用です) 以下のコードで必要な SDK の最低バージョン:Pythonsarvamai>=0.1.29、JSsarvamai@>=1.1.8。古いバージョンでは TTS パラメーターがtarget_language_codeです。詳しくは「注意点」を参照してください。
モデル
bulbul:v4-flash — 最新モデルです。新しい統合ではこちらを使用してください。v3 と同じ REST/HTTP ストリーム/WebSocket の仕様です。200 以上のペルソナ音声(222 個の ID)があります。
bulbul:v3 — model を省略したときに API が使用するモデルです。短い名前(shubh、priya)を使用します。v4 のペルソナがまだないマラヤーラム語とオディア語には、引き続き適したモデルです。
話者(v4 Flash)
ID は小文字の voice_language_style 形式です:aparna_hi_customer、simran_en_customer、shubh_enhi_ads。speaker を省略すると、デフォルトの shubh_enhi_ads が使われます。v2/v3 の短い名前(shubh、priya、ishita、anushka)を指定すると、400 エラーになります。
中央のトークンは言語タグ(hi、en、bn、gu、kn、mr、pa、ta、te)、または英語とヒンディー語のコードミックスを表す enhi です。1 つの発話が実際に混合言語の場合は _enhi_ のペルソナを使用してください。ヒンディー語の文字表記に英語の借用語が少し含まれる程度なら必要ありません。
language_code には、通常の BCP-47 値(hi-IN、en-IN など。ml-IN と od-IN も含む)を引き続き指定できます。ml または od のペルソナ ID はありません。これらの言語では、model="bulbul:v3" と v3 の短い名前を指定してください。
| 用途 | ヒンディー語 | 英語 |
|---|---|---|
| カスタマーケア | aparna_hi_customer | aparna_en_companion |
| セールス | aparna_hi_customer、shubh_hi_customer | simran_en_sales |
| 債権回収 | simran_hi_recovery | shubh_en_recovery |
| ヒングリッシュ(1 つの発話) | simran_enhi_customer | — |
Voices の「generate your own sample」スニペットから speaker="ishita" をコピーしないでください。これは v3 の短い名前で、v4-flash では失敗します。
言語別の対応状況(2026-10-06 にライブ環境で確認済み。各言語につき動作確認済みのペルソナを 1 つ掲載しています。ほかのペルソナはライブリストから選んでください):
| 言語 | ペルソナの例 | 言語 | ペルソナの例 |
|---|---|---|---|
en-IN | simran_en_customer、sunny_en_social | mr-IN | ishita_mr_conversational |
hi-IN | aparna_hi_customer、shubh_hi_customer | gu-IN | bhavik_gu_conversation |
hi-IN(ヒングリッシュ) | shubh_enhi_ads(デフォルト) | kn-IN | chaitra_kn_conversation |
bn-IN | roopa_bn_conversational、arnab_bn_conversation | pa-IN | anand_pa_conversation |
ta-IN | gokul_ta_narration、aravind_ta_ads | te-IN | kavitha_te_conversation |
ペルソナ一覧は変更されます。 Sarvam は 2026-10-06 に音声名を変更しました(bappa_bn_conversation → arnab_bn_conversation、vetri_ta_ads/vetri_ta_suspense → aravind_ta_*)。古い ID は現在 400 エラーになります。記憶や古いブログ記事にある ID をハードコードしないでください。不明な話者を指定すると、ライブリスト全体を含む 400 エラーが返されるため、一覧は不正なリクエストを 1 回送るだけで取得できます。API には、ドキュメントのカタログにないアッサム語のペルソナも 2 つ(_as_)掲載されています。
クイックスタート(Python)
from sarvamai import SarvamAI
from sarvamai.play import save
client = SarvamAI()
response = client.text_to_speech.convert(
text="नमस्ते, आप कैसे हैं?",
language_code="hi-IN",
model="bulbul:v4-flash",
speaker="aparna_hi_customer",
enable_preprocessing=True,
)
save(response, "output.wav")
# HTTP Stream (lower latency, binary audio)
chunks = []
for chunk in client.text_to_speech.convert_stream(
text="Hello from Sarvam AI",
language_code="en-IN",
model="bulbul:v4-flash",
speaker="simran_en_customer",
output_audio_codec="wav",
):
chunks.append(chunk)
audio = b"".join(chunks)
クイックスタート(JavaScript/TypeScript)
import { SarvamAIClient } from "sarvamai";
import { writeFile } from "fs/promises";
const client = new SarvamAIClient({ apiSubscriptionKey: "YOUR_SARVAM_API_KEY" });
// REST
const response = await client.textToSpeech.convert({
text: "नमस्ते, आप कैसे हैं?",
language_code: "hi-IN",
model: "bulbul:v4-flash",
speaker: "aparna_hi_customer",
enable_preprocessing: true,
});
// HTTP Stream (lower latency, returns BinaryResponse)
const streamResponse = await client.textToSpeech.convertStream({
text: "Hello from Sarvam AI",
language_code: "en-IN",
model: "bulbul:v4-flash",
speaker: "simran_en_customer",
output_audio_codec: "wav",
});
const bytes = await streamResponse.bytes();
await writeFile("output.wav", bytes);
WebSocket ストリーミング
import asyncio
from sarvamai import AsyncSarvamAI
async def tts_stream():
client = AsyncSarvamAI()
async with client.text_to_speech_streaming.connect(model="bulbul:v4-flash") as ws:
await ws.configure(
target_language_code="hi-IN",
speaker="aparna_hi_customer",
output_audio_codec="wav",
)
await ws.convert("Your text here")
await ws.flush()
async for message in ws:
pass # base64 audio chunks
asyncio.run(tts_stream())
文字数制限
| 方法 | 最大テキスト長 |
|---|---|
REST(convert) | 2,500 文字 |
HTTP Stream(convert_stream) | 3,500 文字 |
従来の inputs 配列(生の REST) | 1 項目あたり 500 文字。2,500 文字の制限にするには、代わりに text を送信してください |
| WebSocket | メッセージあたり 2,500 文字(最低レイテンシーにするには 500 文字未満にし、1 つの接続で複数のメッセージを送信してください) |
注意点
| 注意点 | 詳細 |
|---|---|
model を設定しないと v3 になります | model を省略すると bulbul:v3 が選択されます。v3 の短縮名は使用できますが、v4 のペルソナ ID は使用できません。新しいコードでは model="bulbul:v4-flash" を設定します。 |
| v4 では v3/v2 の短縮名を使用できません | shubh、priya、ishita、anushka などは拒否されます。voice_language_style を使用してください。不明な ID を指定すると、現在の話者リストとともに 400 が返されます。 |
language_code はバージョンによって異なります | Python の >=0.1.29 と JS の >=1.1.8(どちらも 2026-08-03)では language_code を使用します。それ以前のバージョンでは target_language_code を使用します。名称は完全に変更されており、別名や非推奨期間中の互換処理はありません。JSON 本文のキーも変わっているため、誤った名前を指定すると、リクエストを送信する前に TypeError が発生します。その場合は pip show sarvamai / npm ls sarvamai で確認してください。 |
| WebSocket の名称は変更されていません | Python の ws.configure() は引き続き target_language_code を受け取ります(通信時には language_code に変換されます)。ws.configure() に language_code= を渡すドキュメントの例は TypeError を発生させます。JS の configureConnection() は language_code を受け取ります。 |
| JS のメソッド名 | client.textToSpeech.convert({...}) と .convertStream({...}) です(キャメルケース)。ストリームは .stream()、.bytes()、.blob() を備えた BinaryResponse を返します。 |
pitch / loudness の範囲 | pitch は −0.5~0.5(デフォルトは 0)、loudness は 0.1~2.5(デフォルトは 1)、pace は 0.5~2.0 です。範囲外の値を指定すると 400 が返されます。Bulbul v3 では以前 pitch / loudness が拒否されていましたが、2026-10-06 時点ではこれらも受け付けます(実環境で検証済み)。モデルページの制限表にある v2 専用の範囲は適用されません。 |
| ストリーミングのコーデックのデフォルト | HTTP ストリームと WebSocket では、デフォルトで WAV は選択されません。output_audio_codec(wav または mp3。HTTP ストリームでは flac / aac も使用可能)を設定してください。スキーマに opus が含まれる場合がありますが、現在 /text-to-speech ではエラーになります。 |
| サンプルレート | v4-flash REST では 8000、16000、24000、48000 の speech_sample_rate を検証済みです(返される WAV は指定したレートと一致します)。 |
| 24 kHz を超えるサンプルレート | 32 kHz、44.1 kHz、48 kHz は REST でのみ使用でき、ストリーミングでは使用できません。省略すると 22050 Hz になります。 |
| REST のレスポンス | 音声は response.audios[0] に Base64 エンコードされて格納されます。sarvamai.play.save() または base64.b64decode() を使用してください。Base64 文字列をそのままファイルに書き込んでも、再生可能な音声にはなりません。 |
| 話者はモデルに合わせる必要があります | 不一致はいずれの場合も失敗します。bulbul:v4-flash に v3 の短縮名を指定した場合も、bulbul:v3 に v4 のペルソナを指定した場合も、400 が返されます。model と speaker を明示的に組み合わせてください。 |
| SSML は使用できません | SSML マークアップはサポートされていません。pace(v4 では pitch / loudness も)と、文の境界での分割を使用してください。 |
| ネイティブスクリプトを使用してください | ローマ字表記のインド系言語の入力("Aapka order confirm ho gaya hai")では品質が低下します。インド系言語の単語はネイティブスクリプトで記述し、英語由来の語はラテン文字のままにしてください("आपका order confirm हो गया है")。enable_preprocessing=true の場合、数値、日付、通貨を手動で展開しないでください。 |
ml-IN / od-IN には v4 のペルソナがありません | コードは受け付けられますが、カタログにマラヤーラム語またはオディア語の ID はありません。これらの言語には bulbul:v3 を使用してください。 |
| 発音辞書 | v4-flash でも v3 と同じ方法で dict_id を渡します(ユーザーあたり辞書 10 個、辞書あたり単語 100 個)。Python では client.pronunciation_dictionary.create(file=f) で作成します。JS SDK のアップロードは壊れており(マルチパートの Content-Type がありません)、明示的な Blob タイプを指定した FormData と生の fetch を使用してください。発音ページの「v3 のみ」と記載された制限行は古い情報です。そのページの例では bulbul:v4-flash に dict_id を渡しています。 |
ドキュメント全文
音声カタログ、おすすめのランキング、ストリーミングプロトコル、コーデックのオプションについては、以下をご覧ください。