xAI Voice (テキストから音声)

OCI Generative AIでText to Speechを使用して、xAI Voiceでテキストを音声オーディオに変換します。

テキストを音声に変換するには、次の2つの方法があります。

  • リクエストベースの音声生成用のOCI OpenAI互換オーディオ・スピーチAPI
  • テキスト入力およびオーディオ出力をストリーミングするためのWebSocketストリーミング

APIオプションを使用して、テキストを送信し、オーディオ・ファイルを受信します。WebSocketストリーミングを使用して、テキストを増分送信し、生成時にオーディオチャンクを受信します。

サポートされるモデル

ノート

Text to Speechモデルは、オンデマンド・モードでのみ使用できます。

モデル 摘要
xai.grok-tts テキストから音声を生成するためのテキスト読み上げモデル。

このモデルのリージョン

重要

このモデルのサポートされているリージョン、エンドポイント・タイプ(オンデマンドまたは専用AIクラスタ)およびホスティング(OCI生成AIまたは外部コール)については、リージョン別モデル・ページを参照してください。リージョンの詳細は、生成AIリージョンのページを参照してください。

音声

次の声が聞こえます。ボイス名では、大文字と小文字が区別されません。たとえば、araAraおよびARAが受け入れられます。

音声 摘要
ara 温かい会話
eve エネルギーとアップビート
leo 権威ある、強い
rex 明確で、専門
sal 滑らかでバランスのとれた

アクセス・オプション

OCI OpenAI互換のAudio Speech APIまたはWebSocketストリーミングを使用して、テキストを音声に変換できます。

「アクセス」オプション エンドポイント パラメータ・スタイル 使用条件
OCI OpenAI互換オーディオ・スピーチAPI https://inference.generativeai.{region}.oci.oraclecloud.com/openai/v1 OpenAI互換オーディオ音声リクエスト形式(extra_bodyのxAI固有オプションを使用) テキストを送信し、1つのリクエストでオーディオ・ファイルを受信します。
WebSocketストリーミング wss://inference.generativeai.{region}.oci.oraclecloud.com/xai/v1/tts xAIテキスト読み上げストリーミングパラメータ テキスト入力をストリーミングし、生成時にオーディオチャンクを受信します。

OCI OpenAI互換のAudio Speech APIは、リアルタイム・ストリーミングをサポートしていません。テキスト読み上げのストリーミングには、WebSocketエンドポイントを使用します。

OCI OpenAI互換オーディオスピーチAPI

OCI OpenAI互換のAudio Speech APIを使用して、単一のリクエストからオーディオを生成します。

OCI OpenAI互換エンドポイント
https://inference.generativeai.{region}.oci.oraclecloud.com/openai/v1

リクエストで、xai.grok-ttsモデルをコールし、このトピックにリストされているGrok Voice音声の1つを使用します。OpenAIテキスト読み上げモデル名やOpenAI音声名を使用しないでください。

標準のOpenAI互換音声要求で次の値を指定します。

  • model: xai.grok-tts
  • input: 音声に変換するテキスト
  • voice: サポートされているGrok Voice voicesの1つ(araeveleorexsalなど)
  • response_format: オーディオ・レスポンス形式(mp3など)

xAI固有のオプション(languageoutput_formatなど)をextra_bodyに配置します。

たとえば、次のような設定にはextra_bodyを使用します。

  • language
  • output_format.sample_rate
  • output_format.bit_rate
ノート

OCI OpenAI互換のAudio Speech APIを使用する場合は、OCIエンドポイントでOpenAI互換のリクエスト構造を使用しますが、xai.grok-ttsモデルとサポートされているxAI音声を使用します。OpenAI専用の音声、OpenAI TTSモデル名、またはOpenAIカスタム音声オブジェクトを使用しないでください。

WebSocketストリーミング

リアルタイムまたは対話型のテキスト読み上げワークフローにWebSocketストリーミングを使用します。このオプションでは、テキストをメッセージとしてサービスに送信し、base64でエンコードされたオーディオ・チャンクとしてオーディオを受信します。

OCI WebSocketエンドポイント:
wss://inference.generativeai.{region}.oci.oraclecloud.com/xai/v1/tts

xAIエンドポイントを直接使用しないでください。

次のようなxAIテキスト読み上げ問合せパラメータを使用して、WebSocket接続を設定します。

パラメータ 摘要
voice 音声生成に使用する音声。
language 自動言語検出用の言語コード(enautoなど)。
codec オーディオ・コーデック(mp3wavpcmmulawalawなど)。
sample_rate オーディオ・サンプリング・レート。
bit_rate MP3ビットレート。MP3出力に適用されます。
optimize_streaming_latency 有効にすると、最初のオーディオまでの時間を短縮するために最適化されます。
text_normalization 有効にすると、書き込まれたテキストを音声形式に正規化します。

WebSocket接続をオープンした後、text.deltaメッセージを使用してテキストを送信します。text.doneを送信して、現在の発話の終了を示します。

サービスは次のものを返します。

イベント 摘要
audio.delta Base64でエンコードされたオーディオ・チャンク。
audio.done 現在の発話のオーディオ生成が完了しました。
error サービスからのエラー・メッセージ。

WebSocket接続は、audio.doneの後に開いたままにできるため、再接続せずに別のtext.deltaおよびtext.doneシーケンスを送信できます。

ノート

WebSocketストリーミングの場合は、OCI WebSocketエンドポイントでxAIテキスト・ツー・スピーチ・ストリーミング・パラメータを使用します。

パラメータの使用方法

使用するパラメータは、アクセス・オプションによって異なります。

OCI OpenAI互換オーディオ・スピーチAPIの場合は、OpenAI互換オーディオ・スピーチ・リクエスト形式を使用します。modelxai.grok-ttsに設定し、サポートされているxAI音声を使用し、xAI固有の設定をextra_bodyに配置します。

WebSocketストリーミングの場合は、xAIテキスト・ツー・スピーチ・ストリーミング・パラメータを使用します。音声、言語、コーデック、サンプル・レートおよびビット・レートをWebSocket問合せパラメータとして構成します。text.deltaメッセージを含むテキストを送信し、text.doneを使用して各発話を終了します。

出力フォーマット

Text to Speechは、様々なユースケースで一般的なオーディオ形式をサポートしています。

フォーマット ユース・ケース
mp3 一般的な使用と幅広い互換性
wav 高い忠実度のオーディオおよび編集ワークフロー
pcm リアルタイム処理のための生のオーディオ
mulaw テレフォニーのワークフロー
alaw テレフォニーのワークフロー
ノート

OCI OpenAI互換オーディオ・スピーチAPIの場合、オーディオ形式をresponse_formatに設定し、サンプル・レートやビット・レートなどのxAIオーディオ設定をextra_body.output_formatに配置します。WebSocketストリーミングでは、接続を開くときに、オーディオ形式、サンプル・レートおよびビット・レートを問合せパラメータとして設定します。

ノート

ビットレートはMP3出力に適用されます。

言語

テキスト読み上げは多くの言語をサポートしています。enなどのサポートされている言語コードを使用するか、autoを使用して、アクセス・メソッドでサポートされている場合の自動言語検出を行います。

制限

テキスト読み上げの制限は、アクセスオプションによって異なります。

制限 OCI OpenAI互換オーディオ・スピーチAPI WebSocketストリーミング
文字の制限 リクエスト当たり最大15,000文字 text.deltaメッセージ当たり最大15,000文字
長いコンテンツ コンテンツを小さなリクエストに分割し、オーディオ出力を結合します コンテンツを複数のtext.deltaメッセージまたは個別の発話に分割します。
レート限度 600リクエスト/分または10リクエスト/秒 600リクエスト/分または10リクエスト/秒
同時リクエストまたはセッション 最大100件の同時リクエスト 最大50の同時セッション
セッション許可TTL 該当なし 600秒

長いテキストの場合は、内容を段落や文などの論理セグメントに分割します。これにより、各リクエストまたはテキスト・チャンクを文字制限内に保持し、生成されたオーディオを順番に簡単に結合できます。

WebSocketストリーミングの場合は、text.deltaメッセージを使用してテキストを送信し、現在の発話が完了したらtext.doneを送信します。各text.deltaメッセージは、文字制限内にとどまる必要があります。

次の例は、サポートされている2つのアクセスオプションを示しています。OCI OpenAI互換の例では、OCI OpenAI互換エンドポイントとxai.grok-ttsモデルを使用します。WebSocketの例では、OCI xAI WebSocketエンドポイントおよびxAIストリーミング・パラメータを使用しています。

OCI OpenAI互換オーディオ・スピーチAPI
from openai import OpenAI
from oci_openai import OciSessionAuth

client = OpenAI(
    api_key="<not-used>",
    base_url="https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/openai/v1",
    http_client=httpx.Client(
        auth=OciSessionAuth(profile_name=<profile>),
        headers={"CompartmentId": <compartment_id>}
    ),
)

speech = client.audio.speech.create(
    model="xai.grok-tts",
    input="hello",
    voice="ara",
    response_format="mp3",
    extra_body={
        "language": "en",
        "output_format": {
            "sample_rate": 44100,
            "bit_rate": 192000
        }
    }
)

audio_file = f"output.mp3"
with open(audio_file, "wb") as f:
    f.write(speech.content)
WebSocketストリーミング
import asyncio
import base64
import inspect
import json
from datetime import datetime, timezone
from pathlib import Path
from urllib.parse import urlencode

import websockets


CONFIG = {
    "endpoint": "wss://inference.generativeai.us-chicago-1.oci.oraclecloud.com/xai/v1/tts",
    "api_key": "<YOUR GENAI API KEY>",
    "text": "Hi, this is an audio sample.",
    "voice": "eve",
    "language": "en",
    "codec": "mp3",
    "sample_rate": 24000,
    "bit_rate": 128000,
    "output_dir": "./",
}


def tts_url():
    params = {
        "language": CONFIG["language"],
        "voice": CONFIG["voice"],
        "codec": CONFIG["codec"],
        "sample_rate": CONFIG["sample_rate"],
    }
    if CONFIG["codec"] == "mp3":
        params["bit_rate"] = CONFIG["bit_rate"]
    return "{}?{}".format(CONFIG["endpoint"], urlencode(params))


def output_file():
    folder = Path(CONFIG["output_dir"]).expanduser()
    folder.mkdir(parents=True, exist_ok=True)
    timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
    return folder / "grok_tts_{}.{}".format(timestamp, CONFIG["codec"])


async def main():
    if CONFIG["api_key"] == "<YOUR GENAI API KEY>":
        raise ValueError("Set api_key before running this sample.")

    path = output_file()
    headers = {"Authorization": "Bearer {}".format(CONFIG["api_key"])}
    header_arg = (
        "additional_headers"
        if "additional_headers" in inspect.signature(websockets.connect).parameters
        else "extra_headers"
    )

    async with websockets.connect(tts_url(), **{header_arg: headers}) as ws:
        await ws.send(json.dumps({"type": "text.delta", "delta": CONFIG["text"]}))
        await ws.send(json.dumps({"type": "text.done"}))

        with open(str(path), "wb") as audio_file:
            async for message in ws:
                event = json.loads(message)
                if event["type"] == "audio.delta":
                    audio_file.write(base64.b64decode(event["delta"]))
                elif event["type"] == "audio.done":
                    print("Saved audio to {}".format(path))
                    break
                elif event["type"] == "error":
                    raise RuntimeError(event.get("message", message))


if __name__ == "__main__":
    asyncio.run(main())