跳转到主要内容
Qwen-Omni-Realtime

Qwen-Omni 声音复刻

声音复刻 API 参考:上传音频创建定制音色,用于 Qwen-Omni 对话

声音复刻依托大模型进行特征提取,无需训练即可复刻声音。仅需提供 10~20 秒的音频,即可生成高度相似且听感自然的定制音色。声音复刻与模型调用是前后关联的两个步骤。本文档聚焦于介绍声音复刻的参数和接口细节,模型调用请参见实时多模态语音非实时多模态语音 用户指南:关于模型介绍和选型建议请参见实时多模态语音非实时多模态语音
本文档专用于千问Omni和千问Omni-Realtime声音复刻接口;若您使用的是语音合成模型,请参见语音合成声音复刻

音频要求

高质量的输入音频是获得优质复刻效果的基础。
项目要求
支持格式WAV (16bit)、MP3、M4A
音频时长推荐 10~20 秒,最长不超过 60 秒
文件大小< 10 MB
采样率>= 24 kHz
声道单声道
内容音频必须包含至少 3 秒连续清晰朗读(无背景音),其余部分仅允许短暂停顿(<= 2 秒);整段音频应避免背景音乐、噪音或其他人声,确保核心朗读内容质量;请使用正常说话音频作为输入,不要上传歌曲或唱歌音频,以确保复刻效果准确和可用
语言中文(zh)、英文(en)、德语(de)、意大利语(it)、葡萄牙语(pt)、西班牙语(es)、日语(ja)、韩语(ko)、法语(fr)、俄语(ru)、泰语(th)、印尼语(id)、阿拉伯语(ar)、捷克语(cs)、丹麦语(da)、荷兰语(nl)、芬兰语(fi)、希伯来语(he)、印地语(hi)、冰岛语(is)、马来语(ms)、挪威语(no)、波斯语(fa)、波兰语(pl)、瑞典语(sv)、他加禄语(tl)、土耳其语(tr)、乌尔都语(ur)、越南语(vi)。中文方言:东北话(Dongbei)、陕西话(Shannxi)、四川话(Sichuan)、河南话(Henan)、长沙话(Changsha)、天津话(Tianjin)、杭州话(Hangzhou)、辽宁话(Liaoning)、沈阳话(Shenyang)、鞍山话(Anshan)

快速开始:复刻与使用音色

1. 工作流程

声音复刻与模型调用是紧密关联的两个独立步骤,遵循"先创建,后使用"的流程:
  1. 创建音色 调用创建音色接口,上传一段音频。系统会分析该音频,创建一个专属的复刻音色。此步骤必须指定 target_model,声明创建的音色将由哪个全模态模型驱动。 若已有创建好的音色(调用查询音色列表接口查看),可跳过这一步直接进行下一步。
  2. 使用音色进行对话 调用 Omni 接口(实时或非实时),传入上一步获得的音色。此步骤指定的全模态模型必须和上一步的 target_model 一致。

2. 模型配置与准备工作

选择合适的模型并完成准备工作。

模型配置

声音复刻时需要指定以下两个模型:
  • 声音复刻模型:qwen-voice-enrollment
  • 驱动音色的全模态模型:
    • qwen3.5-omni-plus-realtime
    • qwen3.5-omni-flash-realtime
    • qwen3.5-omni-plus
    • qwen3.5-omni-flash

准备工作

  1. 获取 API Key获取 API Key,为安全起见,推荐将 API Key 配置到环境变量。
  2. 安装 SDK:确保已安装最新版 DashScope SDK
  3. 准备待复刻音频:音频需符合音频要求

3. 端到端示例

以下示例演示了如何在对话中使用声音复刻生成的专属音色,实现与原音高度相似的输出效果。
  • 关键原则:声音复刻时,target_model(驱动音色的全模态模型)必须与后续调用 Omni 接口时指定的模型一致,否则会合成失败。
  • 示例使用本地音频文件 voice.mp3 进行声音复刻,运行代码时,请注意替换。
  • 实时
  • 非实时
适用于 Qwen-Omni-Realtime 系列模型,更多说明请参见实时多模态语音
# 依赖:dashscope >= 1.23.9,pyaudio
import os
import requests
import base64
import pathlib
import time
import pyaudio
from dashscope.audio.qwen_omni import MultiModality, OmniRealtimeCallback, OmniRealtimeConversation
import dashscope

# ======= 常量配置 =======
DEFAULT_TARGET_MODEL = "qwen3.5-omni-plus-realtime"  # 声音复刻、实时对话要使用相同的模型
DEFAULT_PREFERRED_NAME = "guanyu"
DEFAULT_AUDIO_MIME_TYPE = "audio/mpeg"
VOICE_FILE_PATH = "voice.mp3"  # 用于声音复刻的本地音频文件的相对路径


def create_voice(file_path: str,
                 target_model: str = DEFAULT_TARGET_MODEL,
                 preferred_name: str = DEFAULT_PREFERRED_NAME,
                 audio_mime_type: str = DEFAULT_AUDIO_MIME_TYPE) -> str:
  """
  创建音色,并返回 voice 参数
  """
  # 若没有配置环境变量,请用千问 AI 平台 API Key 将下行替换为:api_key = "sk-xxx"
  api_key = os.getenv("DASHSCOPE_API_KEY")

  file_path_obj = pathlib.Path(file_path)
  if not file_path_obj.exists():
    raise FileNotFoundError(f"音频文件不存在: {file_path}")

  base64_str = base64.b64encode(file_path_obj.read_bytes()).decode()
  data_uri = f"data:{audio_mime_type};base64,{base64_str}"

  url = "https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization"
  payload = {
    "model": "qwen-voice-enrollment",
    "input": {
      "action": "create",
      "target_model": target_model,
      "preferred_name": preferred_name,
      "audio": {"data": data_uri}
    }
  }
  headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json"
  }

  resp = requests.post(url, json=payload, headers=headers)
  if resp.status_code != 200:
    raise RuntimeError(f"创建 voice 失败: {resp.status_code}, {resp.text}")

  try:
    return resp.json()["output"]["voice"]
  except (KeyError, ValueError) as e:
    raise RuntimeError(f"解析 voice 响应失败: {e}")


class SimpleCallback(OmniRealtimeCallback):
  def __init__(self, pya):
    self.pya = pya
    self.out = None
  def on_open(self):
    self.out = self.pya.open(
      format=pyaudio.paInt16,
      channels=1,
      rate=24000,
      output=True
    )
  def on_event(self, response):
    if response['type'] == 'response.audio.delta':
      self.out.write(base64.b64decode(response['delta']))
    elif response['type'] == 'conversation.item.input_audio_transcription.completed':
      print(f"[User] {response['transcript']}")
    elif response['type'] == 'response.audio_transcript.done':
      print(f"[LLM] {response['transcript']}")


if __name__ == '__main__':
  # 若没有配置环境变量,请用千问 AI 平台 API Key 将下行替换为:dashscope.api_key = "sk-xxx"
  dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")
  url = "wss://dashscope.aliyuncs.com/api-ws/v1/realtime"

  # 1. 声音复刻:创建专属音色
  voice = create_voice(VOICE_FILE_PATH)
  print(f"声音复刻完成,音色: {voice}")

  # 2. 使用复刻音色进行实时对话
  pya = pyaudio.PyAudio()
  callback = SimpleCallback(pya)
  conv = OmniRealtimeConversation(model=DEFAULT_TARGET_MODEL, callback=callback, url=url)
  conv.connect()
  conv.update_session(
    output_modalities=[MultiModality.AUDIO, MultiModality.TEXT],
    voice=voice  # 使用复刻生成的专属音色
  )
  mic = pya.open(format=pyaudio.paInt16, channels=1