Closed5

「MLX-Audio」を試す

kun432kun432

GitHubレポジトリ。MLX公式ではないみたい。

https://github.com/Blaizzy/mlx-audio

MLX-Audio

AppleのMLXフレームワーク上に構築された、Text-to-Speech(TTS)およびSpeech-to-Speech(STS)ライブラリであり、Apple Silicon上で効率的な音声合成を提供します。

機能

  • Apple Silicon(Mシリーズチップ)上での高速な推論
  • 複数言語のサポート
  • 音声のカスタマイズオプション
  • 調整可能な話速制御(0.5倍〜2.0倍)
  • 3Dオーディオビジュアライゼーション付きのインタラクティブなWebインターフェース
  • TTS生成のためのREST API
  • 最適化されたパフォーマンスのための量子化サポート
  • Finder/Explorer統合による出力ファイルへの直接アクセス

なお、対応しているモデルについては

  • Kokoro-TTS
  • Sesami CSM

が記載されている。他のモデルはどうなんだろう?とりあえず上記でKokoro-TTSは日本語に対応している。

kun432kun432

インストール&Quick Start(CLI)

ローカルのMac(M2 Pro)でやる。

uvでPython仮想環境作成

uv init -p 3.12.9 mlx-audio-work && cd mlx-audio-work

mlx-audioのパッケージ追加

uv add mlx-audio
出力
(snip)
 + mlx-audio==0.2.1
(snip)

あと、WebインタフェースとAPIサーバを使う場合は、さらにパッケージインストールが必要になる。レポジトリの requirements.txt に記載されているパッケージを追加する。requirements.txt をダウンロード。

wget https://raw.githubusercontent.com/Blaizzy/mlx-audio/refs/heads/main/requirements.txt

日本語のために少しだけ修正。Kokoro-TTSがG2Pエンジンにmisakiというライブラリを使用するが、日本語を使う場合はextrasに追加が必要になる。

requirements.txt
misaki[en,ja]>=0.8.2
(snip)

ではrequirements.txtのパッケージを追加

uv add -r requirements.txt

Quick start。

uv run mlx_audio.tts.generate --text "Hello, world"

モデルがダウンロードされる。どうやら何も指定しなければデフォルトは mlx-community/Kokoro-82M-bf16 になる様子。

出力
Fetching 2 files:   0%|                                                                           | 0/2 [00:00<?, ?it/s]
config.json: 100%|█████████████████████████████████████████████████████████████████| 2.35k/2.35k [00:00<00:00, 6.55MB/s]
kokoro-v1_0.safetensors: 100%|██████████████████████████████████████████████████████| 327M/327M [00:34<00:00, 9.36MB/s]
Fetching 2 files: 100%|██████████████████████████████████████████████████████████████████| 2/2 [00:35<00:00, 17.90s/it]

おっとエラー・・・

出力
Model: mlx-community/Kokoro-82M-bf16
Text: Hello, world
Voice: None
Speed: 1.0x
Language: a
/Users/kun432/work/mlx-audio-work/.venv/bin/python: No module named pip

pipパッケージが必要っぽいので、追加。

uv add pip

再度実行

uv run mlx_audio.tts.generate --text "Hello, world"
出力
Fetching 2 files: 100%|███████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 17549.39it/s]

Model: mlx-community/Kokoro-82M-bf16
Text: Hello, world
Voice: None
Speed: 1.0x
Language: a
Collecting en-core-web-sm==3.8.0
  Downloading https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl (12.8 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.8/12.8 MB 9.9 MB/s eta 0:00:00
Installing collected packages: en-core-web-sm
Successfully installed en-core-web-sm-3.8.0
✔ Download and installation successful
You can now load the package via spacy.load('en_core_web_sm')
af_heart.pt: 100%|████████████████████████████████████████████████████████████████████████████████████████████████| 523k/523k [00:00<00:00, 8.10MB/s]
✅ Audio successfully generated and saving as: audio_000.wav

WAVファイルが生成されているので再生。"Hello, World"と音声が聞こえればOK。

afplay audio_000.wav

実際に生成されたもの

https://audio.com/kun432/audio/mlx-audio-sample-1

Usageを見ておく。

uv run mlx_audio.tts.generate --help
出力
usage: mlx_audio.tts.generate [-h] [--model MODEL] [--text TEXT] [--voice VOICE] [--speed SPEED]
                              [--gender GENDER] [--pitch PITCH] [--lang_code LANG_CODE]
                              [--file_prefix FILE_PREFIX] [--verbose] [--join_audio] [--play]
                              [--audio_format AUDIO_FORMAT] [--sample_rate SAMPLE_RATE]
                              [--ref_audio REF_AUDIO] [--ref_text REF_TEXT] [--stt_model STT_MODEL]
                              [--temperature TEMPERATURE] [--top_p TOP_P] [--top_k TOP_K]
                              [--repetition_penalty REPETITION_PENALTY] [--stream]
                              [--streaming_interval STREAMING_INTERVAL]

Generate audio from text using TTS.

options:
  -h, --help            show this help message and exit
  --model MODEL         Path or repo id of the model
  --text TEXT           Text to generate (leave blank to input via stdin)
  --voice VOICE         Voice name
  --speed SPEED         Speed of the audio
  --gender GENDER       Gender of the voice [male, female]
  --pitch PITCH         Pitch of the voice
  --lang_code LANG_CODE
                        Language code
  --file_prefix FILE_PREFIX
                        Output file name prefix
  --verbose             Print verbose output
  --join_audio          Join all audio files into one
  --play                Play the output audio
  --audio_format AUDIO_FORMAT
                        Output audio format
  --sample_rate SAMPLE_RATE
                        Audio sample rate in Hz
  --ref_audio REF_AUDIO
                        Path to reference audio
  --ref_text REF_TEXT   Caption for reference audio
  --stt_model STT_MODEL
                        STT model to use to transcribe reference audio
  --temperature TEMPERATURE
                        Temperature for the model
  --top_p TOP_P         Top-p for the model
  --top_k TOP_K         Top-k for the model
  --repetition_penalty REPETITION_PENALTY
                        Repetition penalty for the model
  --stream              Stream the audio as segments instead of saving to a file
  --streaming_interval STREAMING_INTERVAL
                        The time interval in seconds for streaming segments

ふむ、日本語の場合はこんな感じ?

uv run mlx_audio.tts.generate \
    --text "こんにちは、今日はいいお天気ですね。" \
    --lang_code j \
    --voice jf_alpha

エラー・・・

出力
(snip)

  File "fugashi/fugashi.pyx", line 391, in fugashi.fugashi.Tagger.__init__
  File "fugashi/fugashi.pyx", line 231, in fugashi.fugashi.GenericTagger.__init__
RuntimeError:
Failed initializing MeCab. Please see the README for possible solutions:

    https://github.com/polm/fugashi

If you are still having trouble, please file an issue here, and include the
ERROR DETAILS below:

    https://github.com/polm/fugashi/issues

issueを英語で書く必要はありません。
------------------- ERROR DETAILS ------------------------
arguments: [b'fugashi', b'-C', b'-r', b'/Users/kun432/work/mlx-audio-work/.venv/lib/python3.12/site-packages/unidic/dicdir/mecabrc', b'-d', b'/Users/kun432/work/mlx-audio-work/.venv/lib/python3.12/site-packages/unidic/dicdir']
param.cpp(69) [ifs] no such file or directory: /Users/kun432/work/mlx-audio-work/.venv/lib/python3.12/site-packages/unidic/dicdir/mecabrc
----------------------------------------------------------

あー、辞書のダウンロードを忘れていた。

uv run python -m unidic download
出力
download url: https://cotonoha-dic.s3-ap-northeast-1.amazonaws.com/unidic-3.1.0.zip
Dictionary version: 3.1.0+2021-08-31
Downloading UniDic v3.1.0+2021-08-31...
unidic-3.1.0.zip: 100%|████████████████████████████████████████████| 526M/526M [00:58<00:00, 9.02MB/s]
Finished download.
Downloaded UniDic v3.1.0+2021-08-31 to /Users/kun432/work/mlx-audio-work/.venv/lib/python3.12/site-packages/unidic/dicdir

再度実行

uv run mlx_audio.tts.generate \
    --text "こんにちは、今日はいいお天気ですね。" \
    --lang_code j \
    --voice jf_alpha

今度はいけたみたい

出力
Fetching 2 files: 100%|██████████████████████████████████████████████| 2/2 [00:00<00:00, 13336.42it/s]

Model: mlx-community/Kokoro-82M-bf16
Text: こんにちは、今日はいいお天気ですね。
Voice: jf_alpha
Speed: 1.0x
Language: j
✅ Audio successfully generated and saving as: audio_000.wav
afplay audio_000.wav

https://audio.com/kun432/audio/mlx-audio-sample-2

kun432kun432

Python

sample.py
from mlx_audio.tts.generate import generate_audio

text = (
  "いやー、今日のNHKマイルカップは熱いレースでしたね。"
  "ゴール前はかなりの接戦で、確定までハラハラしました!"
  "春のG1レースも折り返しまで来ました。今後も熱戦を期待できそうですね。"
)

generate_audio(
    text=text,
    model_path="mlx-community/Kokoro-82M-bf16",
    voice="jf_alpha",
    speed=1.2,
    lang_code="j",
    file_prefix="sample_ja",
    audio_format="wav",
    sample_rate=24000,
    join_audio=True,
    verbose=True
)

print("生成完了しました")
uv run sample.py
出力
Fetching 2 files: 100%|██████████████████████████████████████████████| 2/2 [00:00<00:00, 13797.05it/s]

Model: mlx-community/Kokoro-82M-bf16
Text: いやー、今日のNHKマイルカップは熱いレースでしたね。ゴール前はかなりの接戦で、確定までハラハラしました!春のG1レースも折り返しまで来ました。今後も熱戦を期待できそうですね。
Voice: jf_alpha
Speed: 1.2x
Language: j
==========
Duration:              00:00:11.775
Samples/sec:           0.7
Prompt:                212 tokens, 156.3 tokens-per-sec
Audio:                 1 samples, 0.7 samples-per-sec
Real-time factor:      0.12x
Processing time:       1.36s
Peak memory usage:     4.38GB
Joining 1 audio files
✅ Audio successfully generated and saving as: sample_ja.wav
生成完了しました
afplay sample_ja.wav

アルファベットを発話してくれないのはなんとなくモデル側の問題のような気がするなぁ、以前Kokoro-TTSを試したことはあるのだけど、そこまでしっかり確認できていない。

https://audio.com/kun432/audio/mlx-audio-sample-3

kun432kun432

WebインタフェースとAPIサーバ

Webインターフェース & APIサーバ

MLX-Audioには、音声周波数に反応する3Dビジュアライゼーション付きのWebインターフェースが含まれています。このインターフェースでは以下が可能です:

  1. 異なる音声と速度設定でTTSを生成
  2. 自分の音声ファイルをアップロードして再生
  3. インタラクティブな3Dオーブで音声を可視化
  4. 生成された音声ファイルを現在の作業フォルダのoutputsディレクトリに自動保存
  5. ローカルで実行中であれば、インターフェースから直接出力フォルダを開く

機能

  • 複数の音声オプション: 様々な音声スタイル(AF Heart、AF Nova、AF Bella、BF Emma)から選択可能
  • 話速の調整可能: インタラクティブスライダーで話速(0.5倍〜2.0倍)を制御
  • リアルタイム3Dビジュアライゼーション: 音声周波数に反応する3Dオーブ
  • 音声ファイルのアップロード: 任意の音声ファイルを再生・可視化
  • 自動再生オプション: 生成された音声を自動で再生
  • 出力フォルダへのアクセス: 出力フォルダをファイルエクスプローラで開くボタンを提供

ということで起動。

uv run mlx_audio.server

どうやらVADも使用されてGradioのUIが起動するみたい。

出力
INFO:	  Warming up STT model.
INFO:	  STT model warmed up.
INFO:	  Warming up VAD model.
INFO:	  VAD model warmed up.
Fetching 2 files:   0%|                                                          | 0/2 [00:00<?, ?it/s]2025-05-13 10:01:03,473 - httpx - INFO - HTTP Request: GET https://api.gradio.app/pkg-version "HTTP/1.1 200 OK"
config.json: 100%|████████████████████████████████████████████████| 2.41k/2.41k [00:00<00:00, 18.5MB/s]
Fetching 2 files:  50%|█████████████████████████                         | 1/2 [00:00<00:00,  1.41it/s]
kokoro-v1_0.safetensors:   5%|█▉                                   | 14.6M/283M [00:09<02:46, 1.61MB/s]

以下のように表示されればOK。なるほど、FastRTCを使ってるのね。

出力
INFO:     Started server process [20531]
INFO:     Waiting for application startup.
INFO:	  Visit https://fastrtc.org/userguide/api/ for WebRTC or Websocket API docs.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

8000版ポートにアクセスするとこんな感じの画面が表示される。

テキストを入力して音声を生成してみるとこんな感じで球体の色や大きさが変わる。

ただ、残念ながら、日本語の場合は"Japanese letter Japanese letter Japanese letter ..."みたいになってしまう。音声も日本語モデルは選択できないし、言語を設定できるようにはなっていないだよね。

Speech-to-Speechだとマイク・FastRTCを使って直接会話ができるのだと思ったけど、単にオウム返しっぽかった。なお、こちらも日本語は使えない。

次にAPIサーバ。ドキュメントは/docsでアクセスできる

のだけど・・・

APIエンドポイント

サーバは以下のREST APIエンドポイントを提供します:

  • POST /tts: TTS音声の生成

    • パラメータ(formデータ):
      • text: 音声に変換するテキスト(必須)
      • voice: 使用する音声(デフォルト: "af_heart")
      • speed: 話速(0.5~2.0、デフォルト: 1.0)
    • 返却値: 生成された音声ファイル名を含むJSON
  • GET /audio/{filename}: 生成済み音声ファイルの取得

  • POST /play: サーバ上から音声を直接再生

    • パラメータ(formデータ):
      • filename: 再生する音声ファイル名(必須)
    • 返却値: ステータスとファイル名を含むJSON
  • POST /stop: 現在再生中の音声を停止

    • 返却値: ステータスを含むJSON
  • POST /open_output_folder: 出力フォルダをファイルエクスプローラで開く

    • 返却値: ステータスとパスを含むJSON
    • 注: この機能はローカルでサーバを実行している場合のみ動作します

注: 生成された音声ファイルは、デフォルトで ~/.mlx_audio/outputs に保存されます。書き込み不可の場合はフォールバックディレクトリが使用されます。

んー、少なくともKokoro TTSで日本語を使う場合にはlang_codeをあわせて受け取れるようにする必要があるけども、残念ながらそうはなっていないので現状のAPIサーバは日本語に対応していない。

kun432kun432

MacならローカルでTTSを手軽に使えるメリットがある。ただ、

  • 様々なTTSモデルに果たして対応できるのだろうか?
  • 日本語にも対応できるのだろうか?

というところかな。過去にいろいろTTSを触ってみたけど、結構インタフェースが様々って印象があって、どこまで統一できるのかというところはちょっとわからないし、モデルごとに異なる場合はドキュメントが欲しいなというところ。例えば、bark-smallはどうやらサポートされているようなのだけど、動かし方がよくわからなかった(音声プロンプトの指定の仕方がわからない、というかbark-smallの仕組みがわかってないと難しい)

でもまあローカルでお手軽に、ってのが充実すると良いなと思う。ロードマップをみるとSTS・STTなども予定されているようなので、今後に期待。

https://github.com/Blaizzy/mlx-audio/issues/1

このスクラップは4ヶ月前にクローズされました