Qwen3-TTS-VC ・ Qwen3-TTS-VC-Realtime の音声クローンを試す
「Qwen3-TTS-VC」「Qwen3-TTS-VC-Realtime」の音声クローンを試したのでまとめました。
1. はじめに
「Qwen3-TTS-VC」「Qwen3-TTS-VC-Realtime」は、「Qwen API」で利用できる音声クローニング対応のTTSモデルです。
・Qwen3-TTS-VC
通常の音声生成。
音声ファイルをまとめて生成したい場合。
・Qwen3-TTS-VC-Realtime
低遅延のリアルタイム音声生成。
会話アプリや音声エージェント向け。
音声ファイルを作るだけなら「Qwen3-TTS-VC」、リアルタイム再生したいなら「Qwen3-TTS-VC-Realtime」を使います。
2. Qwen3-TTS-VC
「Qwen3-TTS-VC」は、音声クローニングに対応した通常版のTTSモデルです。参照音声をアップロードして声を登録し、その声でテキストを読み上げます。
主な用途は、次のとおりです。
・ナレーション音声の作成
・キャラクターボイスの生成
・動画用の音声作成
・音声サンプルの一括生成
・音声クローンの品質確認
リアルタイム性よりも、安定して音声ファイルを作りたい場合に使いやすいです。
3. Qwen3-TTS-VC-Realtime
「Qwen3-TTS-VC-Realtime」は、音声クローニングに対応したリアルタイム版のTTSモデルです。WebSocket経由でテキストをストリーミング入力し、生成された音声もストリーミングで受け取ります。
主な用途は、次のとおりです。
・音声対話アプリ
・AIキャラクターとの会話
・リアルタイム読み上げ
・カスタマーサポート音声
・ライブ配信向けの読み上げ
通常版より低遅延で返ってくるため、ユーザーとの会話体験を作る場合はこちらを使います。
4. 参照音声の準備
音声クローニングには、参照音声が必要です。
参照音声は次の条件を満たす必要があります。
・形式 : WAV / MP3 / M4A
・長さ : 10〜20秒推奨。最大60秒
・ファイルサイズ : 10MB未満
・サンプルレート : 24kHz以上
・チャンネル : モノラル
・内容 : 3秒以上の連続した明瞭な音声を含むこと。残り部分の短い無音は2秒以内にする
・対応言語 : 中国語、英語、ドイツ語、イタリア語、ポルトガル語、スペイン語、日本語、韓国語、フランス語、ロシア語
参照音声は、できるだけ静かな環境で録音します。
次のような音声は避けます。
・BGM入り
・ノイズが多い
・複数人の声が入っている
・歌声
・途中で長い無音が入る
・声が小さい
・早口すぎる
10〜20秒程度で、自然なスピードの文章を読むのがよさそうです。
5. APIキーの設定
「Qwen API」を使うには、「Alibaba Cloud Model Studio」でAPIキーを作成します。

作成したAPIキーは、環境変数に設定しておきます。
export DASHSCOPE_API_KEY="取得したAPIキー"6. Qwen3-TTS-VC を試す
(1) Codex で指示。
Qwen API の Qwen3-TTS-VC で、参照音声 voice.wav を使って音声クローニングで「こんにちは。今日は良い天気ですね」のwavを生成して
・qwen3_tts_vc_api.py
#!/usr/bin/env python3
import argparse, base64, json, os
from pathlib import Path
from urllib.request import Request, urlopen
BASE_URL = "https://dashscope-intl.aliyuncs.com/api/v1"
MODEL = "qwen3-tts-vc-2026-01-22"
CACHE = Path("qwen3_tts_vc_voice.txt")
def post(path, payload):
req = Request(
f"{os.getenv('DASHSCOPE_BASE_URL', BASE_URL).rstrip('/')}{path}",
data=json.dumps(payload, ensure_ascii=False).encode(),
headers={"Authorization": f"Bearer {os.environ['DASHSCOPE_API_KEY']}", "Content-Type": "application/json"},
)
return json.loads(urlopen(req, timeout=180).read())
# 音声登録
def get_voice(audio_path):
if CACHE.exists():
return CACHE.read_text().strip()
audio = base64.b64encode(Path(audio_path).read_bytes()).decode()
voice = post("/services/audio/tts/customization", {
"model": "qwen-voice-enrollment",
"input": {
"action": "create",
"target_model": MODEL,
"preferred_name": "voice",
"audio": {"data": f"data:audio/wav;base64,{audio}"},
},
})["output"]["voice"]
CACHE.write_text(voice + "\n")
return voice
def main():
p = argparse.ArgumentParser()
p.add_argument("--audio", default="voice.wav")
p.add_argument("--text", default="こんにちは。今日は良い天気ですね")
p.add_argument("--output", default="qwen3_tts_vc_output.wav")
args = p.parse_args()
# 音声再生
wav_url = post("/services/aigc/multimodal-generation/generation", {
"model": MODEL,
"input": {"text": args.text, "voice": get_voice(args.audio), "language_type": "Japanese"},
})["output"]["audio"]["url"]
Path(args.output).write_bytes(urlopen(wav_url, timeout=180).read())
print(args.output)
if __name__ == "__main__":
main()
・注意点
初回実行時は voice.wav をAlibaba Cloud側に音声登録し、取得した voice ID だけをローカルに保存します。登録済みのクローン音声本体はサーバー側にあり、2回目以降はそのIDを使って再利用するため、再登録は行いません。
・料金体系
2026-06-07時点の公式料金表では、このコードに関係する課金は2種類です。
・音声登録 : qwen-voice-enrollment は $0.01 / voice
・音声合成 : qwen3-tts-vc-2026-01-22 は $0.115 / 10,000文字、最大入力文字数 : 600文字
合成の出力音声自体は課金対象外で、入力テキスト文字数に課金
International では無料枠として、TTSは 10,000文字、音声登録は 1,000 voices/account が用意されています。ただし、いずれも Model Studio 有効化後90日間の無料枠です。
7. Qwen3-TTS-VC-Realtime を試す
(1) Codex で指示。
Qwen API の Qwen3-TTS-VC-Realtime で、先ほど音声登録した声を使って音声クローニングで「こんにちは。今日は良い天気ですね」を再生して
・qwen3_tts_vc_realtime_play.py
#!/usr/bin/env python3
import argparse, base64, json, os, threading, wave
from pathlib import Path
from urllib.request import Request, urlopen
import dashscope, pyaudio
from dashscope.audio.qwen_tts_realtime import AudioFormat, QwenTtsRealtime, QwenTtsRealtimeCallback
BASE = "https://dashscope-intl.aliyuncs.com/api/v1"
WS = "wss://dashscope-intl.aliyuncs.com/api-ws/v1/realtime"
MODEL = "qwen3-tts-vc-realtime-2026-01-15"
def post(path, body):
req = Request(
os.getenv("DASHSCOPE_BASE_URL", BASE).rstrip("/") + path,
json.dumps(body, ensure_ascii=False).encode(),
{"Authorization": f"Bearer {os.environ['DASHSCOPE_API_KEY']}", "Content-Type": "application/json"},
)
return json.loads(urlopen(req, timeout=180).read())
# 音声登録
def voice(audio, cache=Path("qwen3_tts_vc_realtime_voice.txt")):
if cache.exists():
return cache.read_text().strip()
b64 = base64.b64encode(Path(audio).read_bytes()).decode()
v = post("/services/audio/tts/customization", {"model": "qwen-voice-enrollment", "input": {
"action": "create", "target_model": MODEL, "preferred_name": "voice_rt",
"audio": {"data": f"data:audio/wav;base64,{b64}"},
}})["output"]["voice"]
cache.write_text(v + "\n")
return v
# 音声再生
class Player(QwenTtsRealtimeCallback):
def __init__(self, out):
self.done = threading.Event()
self.pa = pyaudio.PyAudio()
self.stream = self.pa.open(format=pyaudio.paInt16, channels=1, rate=24000, output=True)
self.wav = wave.open(out, "wb")
self.wav.setnchannels(1); self.wav.setsampwidth(2); self.wav.setframerate(24000)
def on_event(self, msg):
if msg["type"] == "response.audio.delta":
pcm = base64.b64decode(msg["delta"])
self.stream.write(pcm); self.wav.writeframes(pcm)
elif msg["type"] == "session.finished":
self.done.set()
def close(self):
self.stream.stop_stream(); self.stream.close(); self.pa.terminate(); self.wav.close()
p = argparse.ArgumentParser()
p.add_argument("--audio", default="voice.wav")
p.add_argument("--text", default="こんにちは。今日は良い天気ですね")
p.add_argument("--output", default="qwen3_tts_vc_realtime_output.wav")
a = p.parse_args()
dashscope.api_key = os.environ["DASHSCOPE_API_KEY"]
player = Player(a.output)
tts = QwenTtsRealtime(model=MODEL, callback=player, url=os.getenv("DASHSCOPE_WS_URL", WS))
tts.connect()
tts.update_session(voice=voice(a.audio), response_format=AudioFormat.PCM_24000HZ_MONO_16BIT, mode="server_commit")
tts.append_text(a.text)
tts.finish(); player.done.wait(); tts.close(); player.close()
print(a.output)・注意点
初回実行時は voice.wav をAlibaba Cloud側に音声登録し、取得した voice ID だけをローカルに保存します。登録済みのクローン音声本体はサーバー側にあり、2回目以降はそのIDを使って再利用するため、再登録は行いません。
Realtime APIから音声チャンクを受信すると、メモリにためずに PyAudio
で即再生し、同時にWAVファイルへ保存します。キャッシュファイルを削除すると、次回また音声登録が実行されます。
・料金体系
2026-06-07時点の公式料金表では、このRealtimeコードに関係する課金は2種類です。
・音声登録 : qwen-voice-enrollment は $0.01 / voice
・音声合成 : qwen3-tts-vc-realtime-2026-01-15 は $0.13 / 10,000文字
合成の出力音声自体は課金対象外で、入力テキスト文字数に課金
International では無料枠として、TTSは 10,000文字、音声登録は 1,000 voices/account が用意されています。ただし、いずれも Model Studio 有効化後90日間の無料枠です。
