0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Mac M4 Proで「Fish Speech 1.5」を完全制圧せよ!日本語検閲官を成敗し、勝利の音声を響かせる奥義書

0
Last updated at Posted at 2026-02-08

序文:日本語が消える? 戯言を申すな!

Fish Speech 1.5 は、10万時間を超える日本語データで鍛え上げられた素晴らしいモデルでござる。
しかし、そのまま導入して「こんにちは」と入力しても、城内(コード内部)に潜む「検閲官」どもが日本語をノイズとみなして勝手に消去し、虚無(無音)を生成する事態が多発しておる。

本記事では、最新の Mac M4 Pro において、不届きな役人(バグ・仕様)を「御免状パッチ」で根こそぎ成敗し、勝利の音声を響かせるまでの手順を認め(したため)た。

第零章:土台(Conda)の築城

まずは馬(Python実行環境)を飼わねばならぬ。Mac M4 Pro(Apple Silicon)に最適化された Miniconda を導入せよ。

  1. インストーラーの奪取:
    Miniconda公式サイトより、M1/M2/M3/M4 (Apple Silicon) 用pkg または sh ファイルを拾いなされ。
  2. 儀式の実行:
    ターミナルで以下を叩き、道筋(パス)を通すのじゃ。
# インストール(例:shファイルの場合)
bash Miniconda3-latest-MacOSX-arm64.sh
# 初期化
source ~/miniconda3/bin/activate
conda init zsh

一度ターミナルを閉じ、再び開いて左端に (base) と出れば成功でござる!


第一章:城(環境)の構築と「時の固定」

最新の main ブランチは日々仕様が変わる魔境。まずは時を戻し、安定版に固定するのが兵法の定石でござる。

1. 陣の設営

# プロジェクトのクローン
git clone https://github.com/fishaudio/fish-speech.git
cd fish-speech

# 【最重要】v1.5.0 のタグにチェックアウトせよ!
# これを忘れると、最新の仕様変更(引数エラーなど)に翻弄されることになる。
git checkout v1.5.0

# 仮想環境の作成(conda推奨)
conda create -n fish-speech python=3.10
conda activate fish-speech

# 依存関係のインストール
pip install -e .
pip install torch torchaudio torchvision

2. 武器(モデル)の調達と「大八車」の用意

モデルを Hugging Face から引き出すには、専用の道具(CLI)が必要じゃ。これを入れ忘れると、空の棚を眺めることになりますぞ。

# 大八車(huggingface_hub)のインストール
pip install huggingface_hub

# ログイン(必要に応じて)
# huggingface-cli login

# モデルの一括ダウンロード
huggingface-cli download fishaudio/fish-speech-1.5 --local-dir checkpoints/fish-speech-1.5


第二章:検閲官の粛清(御免状パッチ)

日本語を「不審な文字」として切り捨てる仕様を、以下の 4つの修正(パッチ) で物理的に書き換える。

1. clean.py の無害化

日本語を消去する主犯。機能そのものをザルにする。
fish_speech/text/clean.pyclean_text 関数を以下のように書き換えるのじゃ。

def clean_text(text):
    # 検閲を無効化し、ありのままの日本語を通す
    return str(text)

2. 正規化の強制解除

tools/inference_engine/__init__.py にて、中国語の物差し(ChnNormedText)を無視させる。

# 150行目付近
text=(
    req.text
    if not req.normalize
    else req.text,  # ← ここを強制的に req.text にする!
),

3. オーディオバックエンドの修正

Mac での自爆を防ぐため、以下の2ファイルの backends = ...backends = [] に書き換える。

  • tools/inference_engine/reference_loader.py
  • tools/vqgan/extract_vq.py

第三章:真・実行スクリプト(Master's Script)

WebUI 経由でも動くが、真の侍なら CLI で直接生成したいはず。
数多のエラー(MPS行列サイズ不一致、KV Cache未初期化、タプル戻り値問題)をすべて克服した 「v7:解脱版」 のスクリプトをここに授ける。

これを run_custom_tts_v1.5.0.py として保存し、実行せよ!

import os
import sys
import torch
import torch.nn.functional as F
import torchaudio
import soundfile as sf
import numpy as np
from pathlib import Path

# --- 【勝利の鍵1】検閲官の暗殺(メモリ上でも念押し) ---
try:
    import fish_speech.text.clean as clean_module
    clean_module.clean_text = lambda x: str(x)
    print("⚔️ clean_text を無力化しました。")
except ImportError:
    pass

# --- 【勝利の鍵2】MPS用・行列サイズ強制補正パッチ ---
original_sdpa = F.scaled_dot_product_attention

def patched_sdpa(query, key, value, attn_mask=None, dropout_p=0.0, is_causal=False, scale=None):
    if attn_mask is not None and attn_mask.shape[-1] > key.shape[-2]:
        target_len = key.shape[-2]
        attn_mask = attn_mask[..., :target_len, :target_len]
    return original_sdpa(query, key, value, attn_mask=attn_mask, dropout_p=dropout_p, is_causal=is_causal, scale=scale)

torch.nn.functional.scaled_dot_product_attention = patched_sdpa
print("🔧 MPS用 Attention Mask パッチを適用しました。")

from tools.llama.generate import load_model as load_llama_model, generate_long
from tools.vqgan.inference import load_model as load_vqgan_model

# ================= 設定エリア =================
DEVICE = "mps"
CHECKPOINT_DIR = "checkpoints/fish-speech-1.5"
DECODER_CKPT = "checkpoints/fish-speech-1.5/firefly-gan-vq-fsq-8x1024-21hz-generator.pth"
DECODER_CONFIG = "firefly_gan_vq"

TARGET_TEXT = "こんにちは。御免状式修正により、Mac M4 Proで日本語生成に成功しました。"
REFERENCE_AUDIO_PATH = "reference.wav"  # 貴殿のWAVファイル
REFERENCE_TEXT = "参照音声が喋っている内容"
# ============================================

def main():
    PRECISION = torch.float32 
    print("📥 Loading Models...")
    decoder_model = load_vqgan_model(DECODER_CONFIG, DECODER_CKPT, DEVICE)
    llama_model, decode_one_token = load_llama_model(Path(CHECKPOINT_DIR), DEVICE, PRECISION, compile=False)

    # 【重要】KV Cache の初期化
    print("🧠 Setting up Caches...")
    with torch.device(DEVICE):
        llama_model.setup_caches(max_batch_size=1, max_seq_len=llama_model.config.max_seq_len, dtype=PRECISION)

    # リファレンス処理
    audio, sr = torchaudio.load(REFERENCE_AUDIO_PATH)
    if sr != decoder_model.spec_transform.sample_rate:
        audio = torchaudio.functional.resample(audio, sr, decoder_model.spec_transform.sample_rate)
    audio = audio.mean(dim=0, keepdim=True).to(DEVICE)
    audio_length = torch.tensor([audio.shape[1]], device=DEVICE, dtype=torch.long)
    
    with torch.no_grad():
        prompt_tokens = decoder_model.encode(audio[None], audio_length)[0][0]

    # 生成
    print(f"📝 Generating: {TARGET_TEXT}")
    generator = generate_long(
        model=llama_model, device=DEVICE, decode_one_token=decode_one_token,
        text=TARGET_TEXT, num_samples=1, max_new_tokens=0,
        top_p=0.7, repetition_penalty=1.2, temperature=0.7,
        prompt_text=[REFERENCE_TEXT], prompt_tokens=[prompt_tokens],
        iterative_prompt=True, chunk_length=150
    )

    all_codes = []
    for response in generator:
        if response.action == "sample": all_codes.append(response.codes)
        elif response.action == "next": break

    # デコード(v1.5仕様:feature_lengths必須 & タプル戻り値)
    print("🔊 Decoding...")
    full_codes = torch.cat(all_codes, dim=1).unsqueeze(0)
    feature_lengths = torch.tensor([full_codes.shape[2]], device=DEVICE, dtype=torch.long)
    
    with torch.no_grad():
        decoded_output = decoder_model.decode(full_codes, feature_lengths)
        decoded_audio = decoded_output[0] if isinstance(decoded_output, tuple) else decoded_output

    sf.write("output.wav", decoded_audio.squeeze().cpu().float().numpy(), decoder_model.spec_transform.sample_rate)
    print("🎉 勝利の凱旋! output.wav が生成されました。")

if __name__ == "__main__":
    os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
    main()

実行結果:

(fish-speech) kouairchair@tanakagoujunoMac-mini fish-speech % python run_custom_tts_v1.5.0.py
⚔️ clean_text を無力化しました。
🔧 MPS用 Attention Mask パッチ(v7) を適用しました。
🚀 Device: mps で起動中...
📥 Loading VQGAN (Decoder)...
/Users/kouairchair/miniconda3/envs/fish-speech/lib/python3.10/site-packages/vector_quantize_pytorch/vector_quantize_pytorch.py:445: FutureWarning: `torch.cuda.amp.autocast(args...)` is deprecated. Please use `torch.amp.autocast('cuda', args...)` instead.
  @autocast(enabled = False)
/Users/kouairchair/miniconda3/envs/fish-speech/lib/python3.10/site-packages/vector_quantize_pytorch/vector_quantize_pytorch.py:630: FutureWarning: `torch.cuda.amp.autocast(args...)` is deprecated. Please use `torch.amp.autocast('cuda', args...)` instead.
  @autocast(enabled = False)
/Users/kouairchair/miniconda3/envs/fish-speech/lib/python3.10/site-packages/vector_quantize_pytorch/finite_scalar_quantization.py:147: FutureWarning: `torch.cuda.amp.autocast(args...)` is deprecated. Please use `torch.amp.autocast('cuda', args...)` instead.
  @autocast(enabled = False)
/Users/kouairchair/miniconda3/envs/fish-speech/lib/python3.10/site-packages/vector_quantize_pytorch/lookup_free_quantization.py:209: FutureWarning: `torch.cuda.amp.autocast(args...)` is deprecated. Please use `torch.amp.autocast('cuda', args...)` instead.
  @autocast(enabled = False)
2026-03-09 20:36:41.967 | INFO     | tools.vqgan.inference:load_model:43 - Loaded model: <All keys matched successfully>
📥 Loading Llama (Encoder)...
2026-03-09 20:36:48.367 | INFO     | tools.llama.generate:load_model:682 - Restored model from checkpoint
2026-03-09 20:36:48.368 | INFO     | tools.llama.generate:load_model:688 - Using DualARTransformer
🔧 Setting up KV Caches...
🎤 Processing Reference Audio: sample_voice.m4a
objc[10346]: Class AVFFrameReceiver is implemented in both /Users/kouairchair/miniconda3/envs/fish-speech/lib/python3.10/site-packages/av/.dylibs/libavdevice.62.1.100.dylib (0x16d9103a8) and /opt/homebrew/Cellar/ffmpeg/8.0.1_2/lib/libavdevice.62.1.100.dylib (0x17c8b4328). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[10346]: Class AVFAudioReceiver is implemented in both /Users/kouairchair/miniconda3/envs/fish-speech/lib/python3.10/site-packages/av/.dylibs/libavdevice.62.1.100.dylib (0x16d9103f8) and /opt/homebrew/Cellar/ffmpeg/8.0.1_2/lib/libavdevice.62.1.100.dylib (0x17c8b4378). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
/Users/kouairchair/miniconda3/envs/fish-speech/lib/python3.10/site-packages/torch/functional.py:681: UserWarning: An output with one or more elements was resized since it had shape [], which does not match the required output shape [1, 663, 1025]. This behavior is deprecated, and in a future PyTorch release outputs will not be resized unless they have zero elements. You can explicitly reuse an out tensor t by resizing it, inplace, to zero elements with t.resize_(0). (Triggered internally at /Users/runner/work/pytorch/pytorch/pytorch/aten/src/ATen/native/Resize.cpp:38.)
  return _VF.stft(  # type: ignore[attr-defined]
/Users/kouairchair/miniconda3/envs/fish-speech/lib/python3.10/site-packages/vector_quantize_pytorch/residual_fsq.py:170: FutureWarning: `torch.cuda.amp.autocast(args...)` is deprecated. Please use `torch.amp.autocast('cuda', args...)` instead.
  with autocast(enabled = False):
✅ Reference Encoded.
📝 Generating Semantic Tokens for text: こんにちは。御免状式修正により、Mac M4 Proで日本語生成に成功しました。
2026-03-09 20:36:48.680 | INFO     | tools.llama.generate:generate_long:789 - Encoded text: こんにちは。御免状式修正により、Mac M4 Proで日本語生成に成功しました。
2026-03-09 20:36:48.681 | INFO     | tools.llama.generate:generate_long:807 - Generating sentence 1/1 of sample 1/1
  2%|▊                                           | 152/7954 [00:13<11:29, 11.32it/s]
2026-03-09 20:37:02.493 | INFO     | tools.llama.generate:generate_long:861 - Generated 154 tokens in 13.81 seconds, 11.15 tokens/sec
2026-03-09 20:37:02.493 | INFO     | tools.llama.generate:generate_long:864 - Bandwidth achieved: 7.11 GB/s
🔊 Decoding to Audio...
🎉 Success! Audio saved to: output_cli.wav
(fish-speech) kouairchair@tanakagoujunoMac-mini fish-speech % 

結び:ならぬものはならぬ、通らぬものは通す

Fish Speech は、正しく扱えば最強の武器となる。
もし貴殿の環境で「日本語が喋らぬ」と悩んでいるのなら、この御免状パッチと時を戻す術を試すがよい。

以上。これにて一件落着!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?