MB-iSTFT-VITS2の実装とAPI構築:軽量音声合成モデルの活用

本記事では、軽量な音声合成モデルであるMB-iSTFT-VITS2の導入、学習、およびAPI設定について詳述します。MB-iSTFT-VITS2は、従来のVITSモデルと比較して、モデルサイズが小さく、推論速度が高速であり、より自然な合成音声を実現できるという利点があります。

このプロジェクトは現在も開発が進行中であり、そのソースコードは以下のGitHubリポジトリで公開されています。

https://github.com/FENRlR/MB-iSTFT-VITS2

0. 環境構築

MB-iSTFT-VITS2プロジェクトを動作させるためには、以下の環境設定を推奨します。特にGPU環境は必須です。

  • Dockerコンテナ (例: Linux 20.04)
  • Python 3.8
  • PyTorch および関連ライブラリ (推奨バージョンは以下を参照)
  • CUDA Toolkit (PyTorchのバージョンに合わせる)

推奨されるPyTorchのバージョンとCUDA Toolkitの組み合わせは以下の通りです。

推奨環境1: PyTorch 1.13 + CUDA 11.7

pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 torchaudio==0.13.1 -f https://download.pytorch.org/whl/torch_stable.html

推奨環境2: PyTorch 1.14 (開発版) + CUDA 11.8

(このバージョンを使用する場合は、PyTorch公式が提供する適切なホイールファイルを参照してください。)

1. プロジェクトのセットアップとデータ処理

まずは、プロジェクトリポジトリをローカルにクローンし、必要な依存関係をインストールします。

# プロジェクトリポジトリをクローン
git clone https://github.com/FENRlR/MB-iSTFT-VITS2

# プロジェクトディレクトリへ移動
cd MB-iSTFT-VITS2

# 必要なPythonライブラリをインストール
pip install -r requirements.txt

# テキスト処理エンジンであるespeakをインストール
sudo apt-get update
sudo apt-get install espeak

テキストデータの前処理

学習データとして使用するテキストと音声のペアは、モデルが理解できる形式に前処理する必要があります。preprocess.pyスクリプトを利用してデータセットを準備します。

単一話者データセット向け

--text_index 1を指定し、トレーニング用と検証用のデータリストを処理します。CLEANER_NAMEは、使用するクリーナー(例: english_cleaners、japanese_cleanersなど)に置き換えてください。

python preprocess.py --text_index 1 --filelists data/train_audio_text.txt --text_cleaners english_cleaners
python preprocess.py --text_index 1 --filelists data/val_audio_text.txt --text_cleaners english_cleaners

複数話者データセット向け

--text_index 2を指定します。複数話者データセットのファイルリストには、話者ID情報も含まれている必要があります。

python preprocess.py --text_index 2 --filelists data/multispeaker_train.txt --text_cleaners korean_cleaners
python preprocess.py --text_index 2 --filelists data/multispeaker_val.txt --text_cleaners korean_cleaners

Monotonic Alignment Search (MAS) モジュールの設定

学習プロセスに必要なmonotonic_alignモジュールをビルドします。

cd monotonic_align
mkdir build_temp # 既存の同名ディレクトリとの衝突を避けるため、一時的なビルドディレクトリを作成
python setup.py build_ext --inplace

これらの準備が完了したら、configs/ディレクトリ内の設定ファイルを編集し、データパスやモデルのハイパーパラメータをプロジェクトに合わせて調整してください。

2. モデルの学習

データの前処理が完了した後、モデルの学習を開始できます。学習スクリプトは、単一話者と複数話者で異なります。

2.1. 単一話者データセットでの学習

train.pyスクリプトを使用して、単一話者モデルの学習を行います。-cオプションで設定ファイル、-mオプションでモデルの保存先ディレクトリを指定します。

# 基本モデルの学習
python train.py -c configs/mb_istft_vits2_base.json -m output_models/single_speaker_model

# より小規模なモデル構成での学習(例)
# python train.py -c configs/mini_mb_istft_vits2_base.json -m output_models/mini_model

2.2. 複数話者データセットでの学習

複数話者モデルの学習には、train_ms.pyスクリプトを使用します。ファイルリストのデータ形式は、話者IDを含む必要があります。

python train_ms.py -c configs/mb_istft_vits2_base.json -m output_models/multi_speaker_model

3. Gradioを活用したAPIインターフェースの構築

学習済みのMB-iSTFT-VITS2モデルを使って、Webブラウザから手軽に音声合成を試せるGradioベースのAPIインターフェースを構築します。以下に、そのためのPythonスクリプトの例を示します。

import sys
import os
import logging
import re
import torch
import argparse
import numpy as np
import gradio as gr
import webbrowser

# カスタムモジュールとユーティリティのインポート
import commons
import utils
from models import SynthesizerTrn
from text.symbols import symbols
from text import text_to_sequence

# Numbaなど、冗長なログ出力を抑える設定
logging.getLogger("numba").setLevel(logging.WARNING)
logging.getLogger("markdown_it").setLevel(logging.WARNING)
logging.getLogger("urllib3").setLevel(logging.WARNING)
logging.getLogger("matplotlib").setLevel(logging.WARNING)

# ロギング設定の初期化
logging.basicConfig(
    level=logging.INFO, format="| %(name)s | %(levelname)s | %(message)s"
)
logger = logging.getLogger(__name__)

# モデル、ハイパーパラメータ、デバイスをグローバル変数として定義
global_synthesizer_model = None
model_hyperparams = None
inference_device = None

# 推論デバイスの自動選択
if sys.platform == "darwin" and torch.backends.mps.is_available():
    inference_device = "mps"
    os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
else:
    inference_device = "cuda" if torch.cuda.is_available() else "cpu"
logger.info(f"推論デバイス: {inference_device} を使用します。")

def process_text_for_synthesis(input_text_raw, config_params):
    """
    生の入力テキストをモデルが処理可能なトークンシーケンスに変換します。
    特殊文字を除去し、必要に応じて空白トークンを挿入します。
    """
    # 括弧などの特殊文字を除去
    cleaned_text = re.sub(r"[\[\]\(\)\{\}]", "", input_text_raw)
    
    # テキストを数値IDのシーケンスに変換
    token_sequence = text_to_sequence(cleaned_text, config_params.data.text_cleaners)
    
    # モデルの要件に応じて空白トークンを挿入
    if config_params.data.add_blank:
        token_sequence = commons.intersperse(token_sequence, 0)
        
    return torch.LongTensor(token_sequence)

def generate_speech_segment(text_part, sdp_strength, noise_level, noise_level_w, speed_factor, speaker_id):
    """
    指定されたパラメータに基づき、単一のテキスト部分から音声を合成します。
    """
    global global_synthesizer_model, model_hyperparams, inference_device

    # テキストをトークンIDに変換
    token_ids = process_text_for_synthesis(text_part, model_hyperparams)

    with torch.no_grad():
        # トークンIDテンソルをデバイスに移動し、バッチ次元を追加
        input_token_tensor = token_ids.to(inference_device).unsqueeze(0)
        input_length_tensor = torch.LongTensor([token_ids.size(0)]).to(inference_device)
        
        # 音声合成を実行
        # length_scaleは、Gradioのspeed_factorの逆数として解釈
        audio_waveform_tensor = global_synthesizer_model.infer(
            input_token_tensor,
            input_length_tensor,
            noise_scale=noise_level,
            noise_scale_w=noise_level_w,
            length_scale=1.0 / speed_factor, # 話速調整
            sid=speaker_id # 話者ID(複数話者モデルの場合)
        )[0][0, 0] # 最初のバッチ、最初のチャンネル、最初のスピーカーの出力

        return audio_waveform_tensor.data.cpu().float().numpy()

def perform_full_synthesis(
    input_text, target_speaker_id, sdp_ratio_val, noise_scale_val, noise_scale_w_val, length_scale_val
):
    """
    入力テキスト(パイプで区切られた複数のセグメントを含む可能性あり)から
    完全な音声を生成し、間に無音を挿入します。
    """
    text_segments = input_text.split("|")
    output_audio_segments = []
    
    with torch.no_grad():
        for segment in text_segments:
            # 各セグメントの音声を合成
            synthesized_segment_audio = generate_speech_segment(
                segment,
                sdp_strength=sdp_ratio_val,
                noise_level=noise_scale_val,
                noise_level_w=noise_scale_w_val,
                speed_factor=length_scale_val,
                speaker_id=target_speaker_id,
            )
            output_audio_segments.append(synthesized_segment_audio)
            
            # 各合成音声セグメントの間に0.5秒の無音を挿入
            silence_samples = int(model_hyperparams.data.sampling_rate * 0.5) # 0.5秒の無音
            silent_padding = np.zeros(silence_samples, dtype=np.float32)
            output_audio_segments.append(silent_padding)
            
    # 全ての音声セグメント(と無音)を連結
    final_output_waveform = np.concatenate(output_audio_segments)
    
    return "合成処理が正常に完了しました。", (model_hyperparams.data.sampling_rate, final_output_waveform)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="MB-iSTFT-VITS2 音声合成Gradioインターフェース")
    parser.add_argument(
        "-m", "--model_checkpoint", default="./logs/models/G_94000.pth", help="学習済みモデルのチェックポイントファイルパス"
    )
    parser.add_argument(
        "-c",
        "--config_file",
        default="./logs/models/config.json",
        help="モデル設定ファイルのパス",
    )
    parser.add_argument(
        "--share", action="store_true", help="Gradioアプリケーションを公開リンクで起動します。"
    )
    parser.add_argument(
        "-v", "--verbose", action="store_true", help="詳細なデバッグログを有効にします。"
    )

    cli_arguments = parser.parse_args()

    if cli_arguments.verbose:
        logger.setLevel(logging.DEBUG)
        logger.debug("詳細ログモードが有効になりました。")
    
    model_hyperparams = utils.get_hparams_from_file(cli_arguments.config_file)
    
    # モデルの後方エンコーダーのチャンネル数を設定 (VITS1/VITS2の差異)
    if "use_mel_posterior_encoder" in model_hyperparams.model.keys() and model_hyperparams.model.use_mel_posterior_encoder:
        logger.info("VITS2用のメル後方エンコーダー設定を検出しました。")
        posterior_channels_count = 80  # VITS2の場合
        model_hyperparams.data.use_mel_posterior_encoder = True
    else:
        logger.info("VITS1用の線形後方エンコーダー設定を検出しました。")
        posterior_channels_count = model_hyperparams.data.filter_length // 2 + 1 # VITS1の場合
        model_hyperparams.data.use_mel_posterior_encoder = False
    
    # SynthesizerTrnモデルの初期化
    global_synthesizer_model = SynthesizerTrn(
        len(symbols),
        posterior_channels_count,
        model_hyperparams.train.segment_size // model_hyperparams.data.hop_length,
        n_speakers=model_hyperparams.data.n_speakers,
        **model_hyperparams.model
    ).to(inference_device)
    global_synthesizer_model.eval() # 推論モードに設定

    # 学習済みモデルの重みをロード
    utils.load_checkpoint(cli_arguments.model_checkpoint, global_synthesizer_model, None)

    # Gradio UIコンポーネントの定義
    total_speakers = model_hyperparams.data.n_speakers
    supported_languages = ["JA", "EN", "ZH", "KO"] # サポート言語の例

    with gr.Blocks(title="MB-iSTFT-VITS2 音声合成デモンストレーション") as app_interface:
        with gr.Row():
            with gr.Column():
                input_text_component = gr.TextArea(
                    label="合成テキスト",
                    placeholder="ここに合成したいテキストを入力してください。複数の文を「|」で区切ると、それぞれが個別に合成され、間に短い無音が挿入されます。",
                    value="こんにちは、MB-iSTFT-VITS2による最新の音声合成デモです。",
                    lines=5
                )
                speaker_id_component = gr.Slider(
                    minimum=0, maximum=total_speakers - 1, value=0, step=1, label="話者ID"
                )
                sdp_ratio_component = gr.Slider(
                    minimum=0.0, maximum=1.0, value=0.2, step=0.05, label="SDP比率(セグメント化確率)"
                )
                noise_scale_component = gr.Slider(
                    minimum=0.1, maximum=2.0, value=0.6, step=0.05, label="ノイズスケール(音声の多様性・感情表現)"
                )
                noise_scale_w_component = gr.Slider(
                    minimum=0.1, maximum=2.0, value=0.8, step=0.05, label="ノイズスケールW(ピッチ変動)"
                )
                length_scale_component = gr.Slider(
                    minimum=0.1, maximum=2.0, value=1.0, step=0.05, label="話速スケール(1.0で標準速度)"
                )
                language_component = gr.Dropdown(
                    choices=supported_languages, value=supported_languages[0], label="合成言語"
                )
                generate_button_component = gr.Button("音声生成を開始!", variant="primary")
            with gr.Column():
                status_message_component = gr.Textbox(label="処理状況")
                output_audio_component = gr.Audio(label="生成された音声")

        generate_button_component.click(
            perform_full_synthesis,
            inputs=[
                input_text_component,
                speaker_id_component,
                sdp_ratio_component,
                noise_scale_component,
                noise_scale_w_component,
                length_scale_component,
            ],
            outputs=[status_message_component, output_audio_component],
        )
    
    # Gradioアプリケーションの起動
    logger.info(f"Gradioアプリケーションを起動中。http://127.0.0.1:7860 でアクセス可能。共有リンク: {cli_arguments.share}")
    webbrowser.open("http://127.0.0.1:7860") # デフォルトブラウザを自動で開く
    app_interface.launch(share=cli_arguments.share)

4. VITS2とMB-iSTFT-VITS2の主な相違点

MB-iSTFT-VITS2モデルは、VITS2のアーキテクチャをベースとしつつ、いくつかの変更が加えられています。主な違いは以下の通りです。

  • 不使用コンポーネント: use_spk_conditioned_encoder および gin_channels は使用されません。
  • 追加コンポーネント: 以下のモジュールが新たに追加されています。
    • duration_discriminator_type
    • subbands
    • gen_istft_n_fft
    • gen_istft_hop_size

5. よくある問題とその解決策 (Q&A)

プロジェクトの実施中に遭遇する可能性のある一般的な問題と、その解決策をまとめました。

[問題1] 訓練中に cuda out of memory エラーが発生する

GPUメモリが不足していることを示します。

解決策:

  • 学習設定ファイル(例: config.json)内のbatch_sizeを小さくします。
  • データローダーのnum_workersを0に設定し、CPUでのデータ読み込みプロセス数を減らします(ただし、これによりデータ読み込みが遅くなる場合があります)。

[問題2] 訓練後、スレッド関連のエラー (RuntimeError: Detected mismatch between collectives on ranks) が発生する

PyTorchの分散学習 (Distributed Data Parallel: DDP) 環境で、異なるGPUプロセス間での集団通信に不整合がある場合に発生します。特に、GPUリソースが複数のプロセスで競合している状況で発生しやすいです。

解決策:

  • 現在実行中の他のGPU利用プロセス(特に同じGPUを使用しているもの)を全て終了させます。
  • Dockerコンテナを使用している場合は、コンテナを再起動するか、GPUリソースを適切に割り当て直します。
  • 再度訓練を開始します。前回の中断時点から学習を再開できる場合があります。

[問題2-1] 訓練中に ZeroDivisionError: integer division or modulo by zero が発生する

データサンプリングのロジックに問題がある可能性が高いです。特に、モデルが期待するサンプリングレート(例: 22050 Hz)と、実際のデータセットのサンプリングレートが異なる場合に発生することがあります。

解決策:

  • データセットの音声ファイルのサンプリングレートが、config.jsonで指定されているサンプリングレートと一致していることを確認してください。不一致がある場合は、データセットをリサンプリングするか、設定ファイルを修正します。
  • データセットに空のバケットや、極端に短いオーディオファイルが含まれていないか確認します。

[問題3] API設定時に RuntimeError: Invalid device, must be cuda device が発生する

モデルまたはデータがCUDAデバイスに配置されているにもかかわらず、そのCUDAデバイスが利用できない、またはメモリ不足の状態であることを示します。

原因と解決策:

  • CUDAデバイスの可用性: 実行環境にCUDA対応のGPUが正しくセットアップされているか、またPyTorchがそれを認識しているかを確認します。torch.cuda.is_available()で確認できます。
  • GPUメモリ不足: 別のプロセスがGPUメモリを大量に消費している可能性があります。他のGPUを使用するアプリケーションや学習プロセスを停止し、再試行します。batch_sizeを小さくすることも有効です。

[問題4] RuntimeError: Error(s) in loading state_dict for SynthesizerTrn: size mismatch for enc_q.pre.weight: copying a param with shape torch.Size([192, 80, 1]) from checkpoint, the shape in current model is torch.Size([192, 513, 1]).

ロードしようとしているチェックポイントファイルのモデル構造と、現在のスクリプトで初期化されたモデル構造との間で、レイヤーの形状に不一致があることを示します。特に、後方エンコーダーのチャンネル数に関する問題です。

解決策:

SynthesizerTrnの初期化時に、モデル設定(hps.model)に基づいてposterior_channelsを正しく設定する必要があります。VITS2では通常80チャンネル、VITS1ではfilter_length // 2 + 1チャンネルです。以下のコードスニペットのように、use_mel_posterior_encoderフラグを適切に参照してposterior_channelsを決定し、それをモデル初期化に渡してください。

if "use_mel_posterior_encoder" in hps.model.keys() and hps.model.use_mel_posterior_encoder == True:
    posterior_channels = 80  # VITS2の場合
else:
    posterior_channels = hps.data.filter_length // 2 + 1 # VITS1の場合

net_g = SynthesizerTrn(
    len(symbols),
    posterior_channels, # ここに正しく計算されたチャンネル数を渡す
    hps.train.segment_size // hps.data.hop_length,
    n_speakers=hps.data.n_speakers,
    **hps.model
).to(device)

[問題5] TypeError: load_checkpoint() got an unexpected keyword argument 'skip_optimizer'

使用しているutils.load_checkpoint関数のバージョンが、skip_optimizer引数をサポートしていないことを示します。

解決策:

skip_optimizer=True引数を削除して、モデルの重みのみをロードするようにします。

# 変更前: _ = utils.load_checkpoint(args.model, net_g, None, skip_optimizer=True)
# 変更後:
_ = utils.load_checkpoint(args.model, net_g, None)

[問題6] GradioのWeb UIが「Loading...」のまま動作しない

Gradioのバージョンと他の依存関係との間に互換性の問題がある可能性があります。

解決策:

Gradioの安定したバージョンをインストールし直してみてください。例えば、以下のバージョンが動作する場合があります。

pip install gradio==3.12.0
# または
pip install gradio==3.23.0

[問題7] ValueError: numpy.ndarray size changed, may indicate binary incompatibility. Expected 96 from C header, got 80 from PyObject

numpyと他のライブラリ(特にPyAudioなど、C拡張を使用するライブラリ)との間でバージョン競合が発生している可能性があります。このエラーは通常、numpyが他のライブラリのビルド後にアップデートされた場合に発生します。

解決策:

オーディオ関連のライブラリ、特にPyAudioを再インストールします。その前に、システムに必要な開発パッケージをインストールします。

sudo apt-get update
sudo apt-get install portaudio19-dev
sudo apt-get install python3-all-dev
pip uninstall pyaudio # 既存のものをアンインストール
pip install pyaudio   # 再インストール

解決しない場合は、numpyをアンインストールし、再インストールしてから他の依存ライブラリを再インストールするサイクルを試してください。

[問題8] pip install pyopenjtalk が失敗する

pyopenjtalkのインストールにはcmakeが必要ですが、環境内のcmakeのバージョンや設定に問題がある場合に発生します。

解決策:

  1. まず、現在システムが使用しているcmakeのパスを確認します。
    which cmake
    
  2. もしpipでインストールされたcmake(通常は/usr/local/bin/cmakeのようなパス)が使用されている場合、それをアンインストールします。pip uninstall cmake。
  3. システムにaptなどでインストールされた最新のcmakeがあることを確認します。ない場合は、インストールします。
    sudo apt-get update
    sudo apt-get install cmake
    
  4. パスが正しく設定されていることを確認し、pyopenjtalkを再インストールします。
    pip install pyopenjtalk
    

[問題9] Numpy is not available または numpy のバージョン不一致

特にJupyter Notebook環境で発生しやすく、numpyライブラリが正しくロードされていないか、PyTorchや他のライブラリと互換性のないバージョンがインストールされていることを示します。

解決策:

  • Python環境(仮想環境など)を再構築し、互換性のあるnumpyバージョンを指定してインストールします。例えば、PyTorch 1.14を使用している場合、numpy==1.23.5のようなバージョンが推奨されることがあります。
  • 関連するライブラリ(torch、torchaudioなど)と同時にnumpyをインストールし、依存関係が適切に解決されるようにします。
  • Jupyterなどの対話型環境では、カーネルを再起動してからスクリプトを最初から順に実行することで、中間状態の問題が解消される場合があります。

[問題10] self.transformer_flow_type 在 AVAILABLE_FLOW_TYPES 中,f "transformer_flow_type 必须是 {AVAILABLE_FLOW_TYPES} 中的一个"

これは、モデル設定ファイル(config.json)内でtransformer_flow_typeパラメータに無効な値が設定されていることを示します。指定された値が、モデルがサポートするフロータイプ(AVAILABLE_FLOW_TYPES)のいずれとも一致しません。

解決策:

config.jsonファイルを開き、transformer_flow_typeキーの値を、エラーメッセージに示されているAVAILABLE_FLOW_TYPESの中から選択して修正します。もしカスタムの変更を加えている場合は、元のモデルの実装を参照して正しい値を確認してください。

[問題11] _pickle.UnpicklingError: invalid load key, '<'.

これは通常、PyTorchのチェックポイントファイル(.pthファイル)が破損しているか、実際には有効なPyTorchのpickle形式ではない場合に発生します。特に、Webサイトからダウンロードした際にHTMLコンテンツ(例: 404エラーページ)が誤ってファイルとして保存された場合に多く見られます。

解決策:

  • チェックポイントファイルが完全にダウンロードされ、破損していないことを確認します。
  • wgetやcurlなどのコマンドでダウンロードする際に、リダイレクトが正しく処理されているか確認し、ダウンロードが成功しているかファイルサイズなどで検証します。
  • 可能であれば、ファイルを再ダウンロードします。

[問題12, 15] RuntimeError: PytorchStreamReader failed reading zip archive: failed finding central directory

このエラーも、PyTorchのチェックポイントファイルが破損しているか、不完全な場合に発生します。PyTorchのチェックポイントは通常、内部的にZIPアーカイブ形式を使用しており、このエラーはZIPの構造(特にセントラルディレクトリ)が見つからないことを意味します。

解決策:

  • ファイルの整合性チェック: ダウンロードしたチェックポイントファイルが完全であることを確認します。ファイルサイズが想定通りか、ダウンロード中にネットワークが中断されなかったかなどを確認します。
  • 再ダウンロード: 最も一般的な解決策は、チェックポイントファイルを信頼できるソースから再ダウンロードすることです。ダウンロードツール(wgetなど)で問題が発生した場合は、ブラウザからのダウンロードや別のツールを試してみてください。
  • PyTorchバージョンの互換性: ごく稀に、チェックポイントが非常に異なるPyTorchバージョンで保存された場合に互換性の問題が発生することもありますが、まずはファイルの破損を疑うのが先決です。
  • ファイル名とパス: ファイル名に特殊文字が含まれていたり、パスが長すぎたりしないか確認します。

[問題13] RuntimeError: Given groups=1, weight of size [192, 80, 1], expected input[64, 513, 470] to have 80 channels, but got 513 channels instead

このエラーは、モデルのレイヤーが特定の入力チャンネル数を期待しているにもかかわらず、実際には異なるチャンネル数の入力が与えられたときに発生します。多くの場合、モデルのアーキテクチャの変更や、設定ファイルとコードの不一致が原因です。

解決策:

  • モデルコードの確認: SynthesizerTrnや関連するエンコーダー、デコーダーの定義を慎重に確認し、期待される入力/出力チャンネル数がconfig.jsonのfilter_lengthやposterior_channelsなどの設定と一致しているかを確認します。
  • カスタム変更の巻き戻し: もしモデルコードに手動で変更を加えている場合、それを元の状態に戻して問題が解決するか試します。
  • 設定ファイルの同期: 使用している設定ファイルが、ロードしようとしているチェックポイントモデルの訓練時に使用されたものと一致していることを確認します。

[問題14] nltk_data のダウンロード失敗 (LookupError: Resource cmudict not found.)

NLTK (Natural Language Toolkit) が必要なデータセット(例: cmudict)を見つけられない、またはダウンロードできないことを示します。

解決策:

NLTK Downloaderを使用して、必要なリソースを手動でダウンロードします。Pythonスクリプトまたは対話型シェルから実行できます。

import nltk
nltk.download('cmudict')

または、NLTKデータディレクトリが存在しないか書き込み権限がない場合は、GitHubから手動でクローンし、パスを設定します。

cd /usr/share # またはNLTKデータが保存される適切なディレクトリ
git clone https://github.com/nltk/nltk_data
# その後、Pythonスクリプト内で nltk.data.path.append('/usr/share/nltk_data') を追加するか、
# 環境変数 NLTK_DATA を設定してこのパスを含めます。

タグ: MB-iSTFT-VITS2 VITS2 音声合成 TTS PyTorch

11月2日 07:13 投稿