「MLX-Audio」を試す
GitHubレポジトリ。MLX公式ではないみたい。
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は日本語に対応している。
インストール&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に追加が必要になる。
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
実際に生成されたもの
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
Python
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を試したことはあるのだけど、そこまでしっかり確認できていない。
WebインタフェースとAPIサーバ
Webインターフェース & APIサーバ
MLX-Audioには、音声周波数に反応する3Dビジュアライゼーション付きのWebインターフェースが含まれています。このインターフェースでは以下が可能です:
- 異なる音声と速度設定でTTSを生成
- 自分の音声ファイルをアップロードして再生
- インタラクティブな3Dオーブで音声を可視化
- 生成された音声ファイルを現在の作業フォルダのoutputsディレクトリに自動保存
- ローカルで実行中であれば、インターフェースから直接出力フォルダを開く
機能
- 複数の音声オプション: 様々な音声スタイル(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サーバは日本語に対応していない。
MacならローカルでTTSを手軽に使えるメリットがある。ただ、
- 様々なTTSモデルに果たして対応できるのだろうか?
- 日本語にも対応できるのだろうか?
というところかな。過去にいろいろTTSを触ってみたけど、結構インタフェースが様々って印象があって、どこまで統一できるのかというところはちょっとわからないし、モデルごとに異なる場合はドキュメントが欲しいなというところ。例えば、bark-smallはどうやらサポートされているようなのだけど、動かし方がよくわからなかった(音声プロンプトの指定の仕方がわからない、というかbark-smallの仕組みがわかってないと難しい)
でもまあローカルでお手軽に、ってのが充実すると良いなと思う。ロードマップをみるとSTS・STTなども予定されているようなので、今後に期待。