Mac下部署mlx架构的Qwen3 TTS语音克隆服务

1、创建项目文件夹并进入

mkdir Qwen3TTS && cd Qwen3TTS


2、创建虚拟环境并激活

uv venv --python 3.11 && source .venv/bin/activate


3、安装mls-audio服务

uv pip install -U mlx-audio


4、下载模型(停止翻墙)

hf download mlx-community/Qwen3-TTS-12Hz-0.6B-Base-bf16


5、测试服务

python -m mlx_audio.tts.generate --model mlx-community/Qwen3-TTS-12Hz-0.6B-Base-bf16 --text "Hello, this is a test."


如果在项目文件夹下生成了 audio_000.wav 文件则表明此服务和模型已成功部署/下载

6、编写项目依赖库文件

vi requirements.txt


gradio>=5.38.0

mlx>=0.28.0
mlx-lm>=0.28.0
mlx-audio

numpy>=2.0
soundfile>=0.13.1
scipy>=1.15
librosa>=0.11
huggingface_hub>=0.34
transformers>=4.53
sentencepiece

上述内容输入完成后,通过 :wq 保存文件

7、编写app.py文件

vi app.py    


-------------------------------------

import os
from datetime import datetime
from pathlib import Path

import gradio as gr

from mlx_audio.tts.generate import generate_audio
from mlx_audio.tts.utils import load_model


MODEL_ID = "mlx-community/Qwen3-TTS-12Hz-0.6B-Base-bf16"


#########################################################
# 模型加载(启动时仅加载一次)
#########################################################

print(f"正在加载 Qwen3-TTS 模型:{MODEL_ID}")
model = load_model(MODEL_ID)
print("模型加载完成!")


#########################################################
# 推理函数
#########################################################


def clone_voice(ref_audio, ref_text, text, output_dir):
    """使用参考音频及其准确原文进行零样本语音克隆。"""

    if not ref_audio:
        raise gr.Error("请上传参考音频")

    ref_text = (ref_text or "").strip()
    if not ref_text:
        raise gr.Error("请输入参考音频中实际说出的原文")

    text = (text or "").strip()
    if not text:
        raise gr.Error("请输入需要合成的文字")

    output_dir = (output_dir or "outputs").strip()
    output_path = Path(output_dir).expanduser().resolve()
    output_path.mkdir(parents=True, exist_ok=True)

    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
    file_prefix = f"clone_{timestamp}"
    expected_file = output_path / f"{file_prefix}.wav"

    print("\n开始语音克隆:")
    print(f"参考音频:{ref_audio}")
    print(f"参考原文:{ref_text}")
    print(f"合成文字:{text}")
    print(f"输出目录:{output_path}")

    # 关键修复:明确传入 ref_text,并关闭自动 Whisper 转写。
    # 这样不会再访问缺失的 multilingual.tiktoken 文件。
    generate_audio(
        model=model,
        text=text,
        ref_audio=ref_audio,
        ref_text=ref_text,
        stt_model=None,
        output_path=str(output_path),
        file_prefix=file_prefix,
        audio_format="wav",
        join_audio=True,
        verbose=True,
    )

    # join_audio=True 时通常生成 clone_xxx.wav。
    # 同时兼容部分旧版本生成 clone_xxx_000.wav 的情况。
    candidates = []
    if expected_file.exists():
        candidates.append(expected_file)

    candidates.extend(
        sorted(
            output_path.glob(f"{file_prefix}*.wav"),
            key=lambda p: p.stat().st_mtime,
            reverse=True,
        )
    )

    output_file = next((p for p in candidates if p.exists() and p.stat().st_size > 0), None)

    if output_file is None:
        raise gr.Error(
            "语音生成失败,未找到输出文件。请查看运行 app.py 的终端窗口,"
            "终端中会显示真正的模型错误。"
        )

    output_file_str = str(output_file)
    return "✅ 合成成功", output_file_str, output_file_str


#########################################################
# Gradio UI
#########################################################

with gr.Blocks(title="Qwen3-TTS 语音克隆") as demo:
    gr.Markdown(
        """
        # 🎤 Qwen3-TTS 本地语音克隆

        上传一段清晰的参考音频,并填写音频中**实际说出的准确原文**,
        再输入需要合成的新文字。
        """
    )

    with gr.Row():
        with gr.Column():
            ref_audio = gr.Audio(
                label="参考音频",
                type="filepath",
            )

            ref_text = gr.Textbox(
                label="参考音频原文(必填)",
                lines=3,
                placeholder="请逐字填写参考音频中实际说出的内容……",
                info="原文越准确,克隆效果通常越稳定。",
            )

            text = gr.Textbox(
                label="需要合成的文字",
                lines=6,
                placeholder="请输入需要用克隆声音朗读的内容……",
            )

            output_dir = gr.Textbox(
                label="输出目录",
                value="outputs",
            )

            btn = gr.Button(
                "🚀 立即转换",
                variant="primary",
            )

        with gr.Column():
            status = gr.Textbox(
                label="运行状态",
                interactive=False,
            )

            result_audio = gr.Audio(
                label="试听结果",
            )

            save_path = gr.Textbox(
                label="保存路径",
                interactive=False,
            )

    btn.click(
        fn=clone_voice,
        inputs=[
            ref_audio,
            ref_text,
            text,
            output_dir,
        ],
        outputs=[
            status,
            result_audio,
            save_path,
        ],
    )


demo.queue().launch(
    server_name="0.0.0.0",
    server_port=7860,
    share=False,
)

--------------------------------
上述内容输入完成后,通过 :wq 保存文件

8、安装依赖库

 uv pip install -r requirements.txt


9、运行主程序

python app.py        


浏览器访问:
http://127.0.0.1:7860/
即可!



评论

此博客中的热门博文

通过命令行在Github上发布项目的新版本

利用GitHub免费的静态页面托管空间发布网页

本地部署OpenAvatarChat实时交互数字人系统