Skip to main content

CosyVoice Python SDK

DashScope Python SDK を使用して、非ストリーミング、一方向ストリーミング、または双方向ストリーミングモードで、CosyVoice のリアルタイム音声合成をアプリケーションに統合します。

サービスエンドポイント

SDK のインターフェースアドレスは、Client の構築パラメーター workspace/region で決まります(下記のアドレスに対応し、WorkspaceId を含みます)。他のリージョンに切り替えるには、Client の構築パラメーターを対応するリージョンの値に変更してください。
  • Singapore
  • China (Beijing)
wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference{WorkspaceId} を実際のワークスペース ID に置き換えます。
Alibaba Cloud Model Studio は、China (Beijing) および Singapore リージョン向けに、ワークスペース専用ドメインをリリースしました。新しい専用ドメインは、推論リクエストに対して優れたパフォーマンスと高い安定性を提供します。新しいドメインへの移行を推奨します:
  • China (Beijing): dashscope.aliyuncs.com から {WorkspaceId}.cn-beijing.maas.aliyuncs.com へ
  • Singapore: dashscope-intl.aliyuncs.com から {WorkspaceId}.ap-southeast-1.maas.aliyuncs.com へ

コアリソース(client.audio.tts)

リソースパス:client.audio.tts 機能:WebSocket ベースの音声合成で、一次性合成(synthesize)、ストリーミング合成(stream)、双方向ストリーミングセッション(connect)の 3 つの呼び出し形態を提供します。

呼び出しエントリ

# One-shot synthesis: returns the complete audio bytes
audio = client.audio.tts.synthesize(
    text,                      # text is required (positional argument)
    model="cosyvoice-v3-plus", # The model that the voice belongs to
    voice="longanyang",        # The voice
    format="mp3",              # Audio encoding format, default "mp3"
    sample_rate=22050,         # Sample rate, default 22050
)

# Streaming synthesis: yields audio bytes chunk by chunk (write/play while receiving)
for chunk in client.audio.tts.stream(text, model=..., voice=...):
    ...

# Bidirectional streaming session: send text in segments; the connection is established automatically when entering the with context
with client.audio.tts.connect(model=..., voice=...) as session:
    session.send_text(text)    # Can be called multiple times to append text
    session.stop()             # Notify the server that the input is complete
    for chunk in session.audio_chunks():
        ...

synthesize() - 非ストリーミング呼び出し

メソッドシグネチャ:
def synthesize(self, text: str, *, model: str = "cosyvoice-v1",
               voice: str = "longxiaochun", format: str = "mp3",
               sample_rate: int = 22050, volume: int = None,
               rate: float = None, pitch: float = None,
               language_hints: list = None, enable_ssml: bool = None,
               parameters: Dict = None, ...) -> bytes
パラメーター:
パラメーター型必須説明
textstrはい合成する全文テキスト。最大長: 20,000 文字。
戻り値: 完全な音声データを含む bytes。 説明: 非ストリーミング呼び出しで、ブロックして待機し、完全な音声データを一度に返します。短いテキストで、リアルタイム性の要件が厳しくないシナリオに適しています。synthesize と stream は呼び出しごとにセッションを自前で構築するため、インスタンスを再利用する必要はありません。

stream() - ストリーミング呼び出し

メソッドシグネチャ:
def stream(self, text: str, *, model: str, voice: str,
           format: str = "mp3", sample_rate: int = 22050, ...) -> Iterator[bytes]
パラメーター:
パラメーター型必須説明
textstrはい合成する全文テキスト。最大長: 20,000 文字。
戻り値: Iterator[bytes]、チャンクごとに産出される音声データ。 説明: ストリーミング合成で、完全なテキストを一度に送信し、音声をチャンクごとに産出します(Iterator[bytes])。リアルタイム性の要件が高い短いテキストの音声合成シナリオに適しています。テキストを分割して送信する必要がある場合は、双方向ストリーミングセッション(connect)を使用してください。

send_text() - ストリーミング入力(セッションメソッド)

双方向ストリーミングセッション(client.audio.tts.connect(...))でテキストを分割して送信します。 メソッドシグネチャ:
def send_text(self, text: str) -> None
パラメーター説明:text は現在合成対象のテキストセグメントです。send_text は複数回呼び出してテキストを追加できます。1 回の呼び出しあたりの最大長は 20,000 文字、累計の最大長は 200,000 文字です。テキストの送信と音声の受信は並行して行う必要があります(audio_chunks()/events() および stop と組み合わせて使用します)。

stop() - ストリーミング入力の終了(セッションメソッド)

メソッドシグネチャ:
def stop(self) -> None
説明: すべてのテキストの送信が完了したことをサーバーに通知します。呼び出し後は現在のスレッドをブロックせず、受信スレッドは残りのテキストの合成が完了してすべての音声データが返されるまで audio_chunks()/events() を消費し続ける必要があります。このメソッドを呼び出さないと、末尾のテキストが音声に変換されない場合があります。

cancel() - ストリーミング合成のキャンセル(セッションメソッド)

メソッドシグネチャ:
def cancel(self) -> None
説明: 現在のストリーミング音声合成のターンをキャンセルします。このメソッドを呼び出すと、SDK は現在のタスクをただちに終了します。キャンセル後の現在のセッションではテキストを送信できません。合成を続けるには新しいセッションを作成してください。
モデルの制限:
  • 中国 (北京):CosyVoice モデルは v2 以降が必要です。
  • シンガポール:CosyVoice モデルはこの機能をサポートしていません。

会話指標と応答(セッション属性)

session.first_package_delay
session.usage
session.last_response
  • first_package_delay:float。テキストを送信してから最初の音声データチャンクを受信するまでのレイテンシー(ミリ秒)。合成完了後に読み取る必要があります。
  • usage:dict。直近の合成タスクの使用量情報。
  • last_response:dict。直近の合成タスクの応答メッセージ(header/payload キーを含む)。直近のリクエストの request_id は session.last_response の header から取得でき、問題の切り分けやログとの関連付けに使用できます。

リクエストパラメーター

以下のパラメーターは client.audio.tts の synthesize/stream/connect メソッドで設定し、合成音声のモデル、音色、フォーマット、および音声特性を制御します(model、voice、format、sample_rate、volume、rate、pitch、language_hints、enable_ssml は具名パラメーターで、その他のパラメーターは parameters ディクショナリで渡します)。
パラメーター型必須説明
modelstrはいモデル名。
voicestrはい音声合成に使用する音声。
  • システム音声: 「CosyVoice 音声リスト」をご参照ください。
  • クローン音声: 音声クローニングによって作成されたカスタム音声
  • カスタム音声: 音声デザインによって作成されたカスタム音声
formatstrいいえ音声のエンコーディング形式。デフォルト値: mp3。mp3、wav、pcm などの形式をサポートします。サンプリングレートは sample_rate パラメーターで設定し、デフォルトは 22050 です。
volumeintいいえ音量レベル。デフォルト値: 50。有効な値: [0, 100]。
ratefloatいいえ話速。デフォルト値: 1.0。有効な値: [0.5, 2.0]。
pitchfloatいいえピッチ。デフォルト値: 1.0。有効な値: [0.5, 2.0]。
bit_rateintいいえkbps 単位のオーディオビットレート。オーディオ形式が mp3 または opus の場合は、bit_rate を使用してビットレートを調整します。デフォルト値: 32。有効な値: [6, 510]。bit_rate は parameters ディクショナリで設定します:
audio = client.audio.tts.synthesize(
    "待合成のテキスト",
    model="cosyvoice-v3-plus",
    voice="longanyang",
    parameters={"bit_rate": 128},
)
word_timestamp_enabledboolいいえ単語レベルのタイムスタンプを有効にするかどうかを指定します。デフォルト値: false。ストリーミング出力モードでのみ使用可能です。サポートされている音声は、cosyvoice-v3.5-plus、cosyvoice-v3.5-flash、cosyvoice-v3-flash、cosyvoice-v3-plus、cosyvoice-v2 のクローン音声、およびCosyVoice 音声リストでサポート対象として記載されているシステム音声です。他のモデルのクローン音声はこの機能をサポートしていません。word_timestamp_enabled は parameters ディクショナリで設定します:
audio = client.audio.tts.stream(
    "待合成のテキスト",
    model="cosyvoice-v3-flash",
    voice="your_voice",  # 単語レベルのタイムスタンプをサポートするシステム音声またはクローン音声
    parameters={"word_timestamp_enabled": True},
)
seedintいいえ合成出力のバリエーションを制御するためのランダムシード。モデルのバージョン、テキスト、音声、およびその他のパラメーターが変更されない場合、同じシードを使用すると同一の結果が生成されます。デフォルト値: 0。有効な値: [0, 65535]。
language_hintslist[str]いいえ
  • このパラメーターは配列ですが、現在のバージョンでは最初の要素のみが処理されます。単一の値を渡してください。
  • このパラメーターは音声合成のターゲット言語を指定します。これは、音声クローニングで使用される音声サンプルの言語とは無関係です。クローニングタスクのソース言語を設定するには、音声クローニング API リファレンスをご参照ください。
出力品質を向上させるために、音声合成のターゲット言語を指定します。数字の発音、略語の展開、記号の読み上げ、または少数言語の合成が期待どおりでない場合に、このパラメーターを使用します。例:
  • 予期しない数字の発音:「hello, this is 110」が、期待される中国語の発音ではなく「hello, this is one zero」と読まれる場合
  • 不正確な記号の発音:「@」が「at」ではなく、中国語の同等語で読まれる場合
  • 少数言語の合成品質が低く、不自然な結果になる場合
  • zh:中国語
  • en:英語
  • fr:フランス語
  • de:ドイツ語
  • ja:日本語
  • ko:韓国語
  • ru:ロシア語
  • pt:ポルトガル語
  • th:タイ語
  • id:インドネシア語
  • vi:ベトナム語
  • es:スペイン語
  • it:イタリア語
  • ms:マレーシア語
  • fil:フィリピン語
  • ar:アラビア語
instructionstrいいえ方言、感情、話し方などの合成特性を制御します。使用方法の詳細については、「Instruction control」をご参照ください。
enable_aigc_tagboolいいえ生成された音声に AIGC ウォーターマークを埋め込むかどうかを指定します。true に設定すると、サポートされている形式 (wav/mp3/opus) の音声ファイルにウォーターマークが埋め込まれます。デフォルト値: false。
cosyvoice-v3-flash、cosyvoice-v3-plus、cosyvoice-v2 のみがこの機能をサポートしています。
enable_aigc_tag、aigc_propagator、および aigc_propagate_id は、parameters ディクショナリで設定します:
audio = client.audio.tts.synthesize(
    "待合成のテキスト",
    model="cosyvoice-v3-plus",
    voice="longanyang",
    parameters={
        "enable_aigc_tag": True,
        "aigc_propagator": "your_propagator",
        "aigc_propagate_id": "your_propagate_id"
    },
)
aigc_propagatorstrいいえAIGC 透かしの ContentPropagator フィールドを設定してコンテンツプロパゲーターを識別するもので、enable_aigc_tag が true の場合にのみ有効になります。デフォルト値: Alibaba Cloud UID。
cosyvoice-v3-flash、cosyvoice-v3-plus、cosyvoice-v2 のみがこの機能をサポートしています。
parameters ディクショナリで設定します。enable_aigc_tag の例をご参照ください。
aigc_propagate_idstrいいえAIGC ウォーターマークの PropagateID フィールドを設定して、特定の伝播アクションを一意に識別します。enable_aigc_tag が true の場合にのみ有効になります。デフォルト値: 現在の音声合成リクエストのリクエスト ID。
cosyvoice-v3-flash、cosyvoice-v3-plus、cosyvoice-v2 のみがこの機能をサポートしています。
parameters ディクショナリで設定します。enable_aigc_tag の例を参照してください。
hot_fixdictいいえ合成前に適用される発音補正とテキスト置換を設定します。
この機能は cosyvoice-v2 ではサポートされていません。
パラメーター:
  • pronunciation:カスタム発音。不正確なデフォルトの発音を補正するために、単語のピンイン注釈を指定します。
  • replace:テキスト置換。合成前に指定された単語をターゲットテキストに置き換えます。置き換えられたテキストが実際の合成入力として使用されます。
例:
audio = client.audio.tts.synthesize(
    "待合成のテキスト",
    model="cosyvoice-v3.5-plus",
    voice="cosyvoice-v3.5-plus-vd-announcer-xxxxxx", # 音声
    parameters={
        "hot_fix": {
            "pronunciation": [{"weather": "tian1 qi4"}],
            "replace": [{"today": "gold day"}]
        }
    },
)
enable_markdown_filterboolいいえ
cosyvoice-v3-flash のクローン音声のみがこの機能をサポートしています。
Markdown フィルタリングを有効にするかどうかを指定します。有効にすると、システムは合成前に入力テキストから Markdown マークアップ記号を自動的に除去し、それらが読み上げられるのを防ぎます。デフォルト値: false。有効な値:
  • true: Markdown フィルタリングを有効にする
  • false: Markdown フィルタリングを無効にする
enable_markdown_filter は parameters ディクショナリで設定します:
audio = client.audio.tts.synthesize(
    "待合成のテキスト",
    model="cosyvoice-v3-flash",
    voice="your_voice",  # cosyvoice-v3-flash のクローン音声
    parameters={"enable_markdown_filter": True},
)

会話とイベント反復

ストリーミング合成ではコールバックインターフェイスを使用しなくなりました:音声とサーバーイベントはセッションの反復メソッドで受信します。stream()/synthesize() ではセッション管理は不要です。双方向ストリーミングセッション(client.audio.tts.connect(...))のライフサイクルは:with コンテキストに入ると自動的に接続を確立 → 複数回 send_text() → stop() → すべての結果を読み取る → コンテキストから抜けると自動的に閉じる、です。

audio_chunks() - 音声データの反復

メソッドシグネチャ:
def audio_chunks(self) -> Iterator[bytes]
戻り値:Iterator[bytes]。チャンクごとに産出される音声のバイナリデータフラグメントで、フォーマットは format パラメーターで指定されます。 説明:受信スレッドで反復処理し、音声データをチャンク単位で受信します。合成中は複数のチャンクが産出されます。データをファイルに書き込んだり、再生デバイスに送ったりできます。同一セッションで許可される events() または audio_chunks() の読み取り者は 1 つだけです。

events() - サーバーイベントの反復

メソッドシグネチャ:
def events(self) -> Generator[Union[Dict, bytes], None, None]
戻り値:サーバー応答イベント(dict、header(リクエスト情報)と payload(出力情報)を含む)と音声 bytes を同時に産出します。payload.output にはイベントタイプ、元テキストなどの情報が含まれます。詳細はevents() イベントの output フィールドをご参照ください。 説明:受信スレッドでサーバーからの返信を反復処理します。合成イベントの出力情報(イベントタイプ、元テキスト、文情報など)を含み、payload.output に直接アクセスして詳細を取得できます。

エラー処理

合成中にエラーが発生すると、ws 層は DashScopeError 例外としてスローされ、例外がトリガーされると接続は自動的に閉じられます。送信/受信処理で try/except で捕捉し、問題の切り分けに役立てるためエラーログを記録できます:
from dashscope.v2 import DashScopeError

try:
    ...
except DashScopeError as e:
    print(e.code, e.message, e.request_id)

セッションのライフサイクル

  • with コンテキストに入ると自動的に接続を確立します(この前に音声出力ストリームの初期化やファイルのオープンなどのリソースを準備できます)。
  • すべてのテキストの合成が完了し、すべての音声データが産出された後、events()/audio_chunks() の反復処理が終了します。その後 first_package_delay などのパフォーマンス指標を読み取れます。
  • with コンテキストから抜けると自動的に接続を閉じます(この後に音声再生デバイスなどのリソースを解放できます)。

events() イベントの output フィールド

セッションの events() が産出するイベント dict の payload.output には、合成イベントの出力情報が含まれており、合成の進捗の追跡や文ごとの詳細の取得に使用できます。output フィールドの構造は次のとおりです。
フィールド型説明
typestrイベントタイプ。値は、 sentence-begin (文の合成開始)、 sentence-synthesis (文の合成進行中)、または sentence-end (文の合成完了) のいずれかです。
original_textstr現在の文の元のテキスト。 sentence-begin および sentence-end イベントで返されます。
sentencedict文情報。 index (文のシーケンス番号) と words (単語リスト。 word_timestamp_enabled が有効な場合にタイムスタンプ情報を含む) が含まれます。
メッセージ例
{
  "header": {
    "task_id": "xxx",
    "event": "result-generated",
    "attributes": {}
  },
  "payload": {
    "output": {
      "type": "sentence-begin",
      "original_text": "How is the weather today?",
      "sentence": {
        "index": 0,
        "words": []
      }
    }
  }
}
解析例
def handle_event(event):
    output = (event.get('payload') or {}).get('output') or {}
    event_type = output.get('type', '')
    original_text = output.get('original_text', '')
    if event_type:
        print(f'Event type: {event_type}, Original text: {original_text}')

コード例

SDK は、次の合成モードをサポートしています:
  • ノンストリーミング呼び出し:ブロッキング型で、完全なテキストを一度に送信し、完全な音声を直接返します。短いテキストの音声合成シナリオに適しています。
  • 単方向ストリーミング呼び出し:ノンブロッキング型で、完全なテキストを一度に送信し、stream が返す音声チャンクを反復処理してデータを受信します。リアルタイム性の要件が高い短いテキストの音声合成シナリオに適しています。
  • 双方向ストリーミング呼び出し:ノンブロッキング型で、テキストセグメントを複数回に分けて送信し、セッションの audio_chunks()/events() の反復処理で増分合成された音声ストリームをリアルタイムに受信します。リアルタイム性の要件が高い長いテキストの音声合成シナリオに適しています。
  • ノンストリーミング
  • 単方向ストリーミング
  • 双方向ストリーミング
image
1 回の呼び出しで送信されるテキストは 20,000 文字を超えてはなりません。この制限を超えると DashScopeError 例外がトリガーされます。
synthesize と stream は呼び出しごとにセッションを自前で構築するため、インスタンスを再利用する必要はありません。
# coding=utf-8

import os

import dashscope

# Singapore リージョンと China (Beijing) リージョンの API キーは異なります。API キーの取得: https://www.alibabacloud.com/help/model-studio/get-api-key
# 環境変数が設定されていない場合は、次の行を実際の Model Studio API キーに置き換えてください:api_key="sk-xxx"
# 次の設定は Singapore リージョン用です。「{WorkspaceId}」を実際のワークスペース ID に置き換えてください。設定はリージョンによって異なります。
client = dashscope.Client(
    api_key=os.environ.get('DASHSCOPE_API_KEY'),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
)

# モデル
model = "cosyvoice-v3-plus"
# 音声
voice = "longanyang"

# テキストを送信して合成し、バイナリオーディオを取得します
audio = client.audio.tts.synthesize("How is the weather today?", model=model, voice=voice)

# 音声をローカルファイルに保存します
with open('output.mp3', 'wb') as f:
    f.write(audio)