tacotron2をWindowsで動かす

初めに

いまさらですが、tacotron2を触ってみます

以下に現在の環境に合わせてuvで環境構築をしたRepositoryを作成しました

github.com

tacotron2の構成と課題

自己回帰 + Attentionのアーキテクチャになっているが以下のような課題があった

  • 推論に時間がかかる
  • Attention部分で確率の計算をしているためスキップや連続の音が間違えることがあった

開発環境

  • Windos 11
  • cuda 12.6

環境構築

uv環境に切り替える前提で進めていきます

まずは3.10の環境構築を行います

uv python pin 3.10

次に以下のようなpyproject.toml の作成します。

[project]
name = "tacotron2"
version = "0.1.0"
description = "Tacotron2 Text-to-Speech"
requires-python = ">=3.10,<3.12"
dependencies = [
    "gdown>=5.2.0",
    "inflect>=7.5.0",
    "librosa>=0.11.0",
    "matplotlib>=3.10.8",
    "scipy>=1.15.3",
    "torch>=2.6.0",
    "torchaudio>=2.6.0",
    "torchvision>=0.21.0",
    "unidecode>=1.4.0",
]

[[tool.uv.index]]
name = "pytorch-cu124"
url = "https://download.pytorch.org/whl/cu124"
explicit = true

[tool.uv.sources]
torch = { index = "pytorch-cu124" }
torchvision = { index = "pytorch-cu124" }
torchaudio = { index = "pytorch-cu124" }

これをもとに uv sync を行い依存関係をインストールします。このとき Pytorch Hubからモデルをダウンロードします

実行

環境が作成できたので、推論コードをを作成して実行していきます。

import argparse
import warnings
import torch
from scipy.io.wavfile import write


def load_models(device: str = "cuda"):
    """Load Tacotron2 and WaveGlow models from PyTorch Hub."""
    print("Loading Tacotron2...")
    tacotron2 = torch.hub.load(
        'NVIDIA/DeepLearningExamples:torchhub',
        'nvidia_tacotron2',
        model_math='fp32',
        trust_repo=True
    )
    tacotron2 = tacotron2.to(device).eval()

    print("Loading WaveGlow...")
    waveglow = torch.hub.load(
        'NVIDIA/DeepLearningExamples:torchhub',
        'nvidia_waveglow',
        model_math='fp32',
        trust_repo=True
    )
    waveglow = waveglow.remove_weightnorm(waveglow)
    waveglow = waveglow.to(device).eval()

    print("Loading text utilities...")
    utils = torch.hub.load(
        'NVIDIA/DeepLearningExamples:torchhub',
        'nvidia_tts_utils',
        trust_repo=True
    )

    return tacotron2, waveglow, utils


def synthesize(text: str, tacotron2, waveglow, utils, device: str = "cuda", sigma: float = 0.666):
    """Synthesize speech from text."""
    # Prepare text
    sequences, lengths = utils.prepare_input_sequence([text])
    sequences = sequences.to(device)
    lengths = lengths.to(device)

    # Generate mel spectrogram
    with torch.no_grad():
        mel, _, _ = tacotron2.infer(sequences, lengths)

        # Generate audio
        audio = waveglow.infer(mel, sigma=sigma)

    # Convert to numpy
    audio = audio.squeeze().cpu().numpy()
    return audio


def main():
    parser = argparse.ArgumentParser(
        description='Text-to-Speech using Tacotron2 + WaveGlow',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
    uv run python inference_cli.py --text "Hello, this is a test."
    uv run python inference_cli.py --text "The quick brown fox." --output fox.wav
    uv run python inference_cli.py --text "Hello" --sigma 0.8
        """
    )
    parser.add_argument('--text', type=str, required=True, help='Text to synthesize')
    parser.add_argument('--output', type=str, default='output.wav', help='Output WAV file')
    parser.add_argument('--sigma', type=float, default=0.666,
                        help='WaveGlow sigma (0.666 recommended, higher=more variation)')
    parser.add_argument('--device', type=str, default='cuda',
                        choices=['cuda', 'cpu'], help='Device to use')
    args = parser.parse_args()

    # Suppress warnings
    warnings.filterwarnings('ignore', category=UserWarning)
    warnings.filterwarnings('ignore', category=FutureWarning)

    # Check CUDA
    if args.device == 'cuda' and not torch.cuda.is_available():
        print("CUDA not available, falling back to CPU")
        args.device = 'cpu'

    print(f"Device: {args.device}")
    print(f"Input text: {args.text}")
    print(f"Output file: {args.output}")
    print(f"Sigma: {args.sigma}")
    print()

    # Load models
    tacotron2, waveglow, utils = load_models(args.device)

    # Synthesize
    print("\nSynthesizing...")
    audio = synthesize(args.text, tacotron2, waveglow, utils, args.device, args.sigma)

    # Normalize and save
    audio = audio / max(abs(audio.max()), abs(audio.min()))  # Normalize to [-1, 1]
    audio_int16 = (audio * 32767).astype('int16')
    write(args.output, 22050, audio_int16)

    print(f"\nSaved: {args.output}")
    print(f"Duration: {len(audio) / 22050:.2f} seconds")


if __name__ == '__main__':
    main()

以下で実行すると 英吾の音声ファイルが生成されます

uv run python inference_cli.py --text "Hello, this is a test."

7000言語以上対応しているTTS「IMS-Toucan」を試す

初めに

7000言語以上の言語の対応したTTSのIMS-Toucanを動かしていきます

開発環境

環境構築

システム依存関係のインストールします

brew install espeak-ng brew install ffmpeg

インストール後に環境変数にパスを追加します

export PHONEMIZER_ESPEAK_LIBRARY=/opt/homebrew/lib/libespeak-ng.dylib

uvの環境を作ります

uv venv --python 3.10

依存ライブラリをインストールします

uv pip install "torch~=2.4.0" "torchaudio~=2.4.0" "torch_complex~=0.4.3" "epitran==1.24" "tqdm~=4.64.1" "scipy~=1.9.3" "librosa~=0.9.2" "praat-parselmouth~=0.4.2" "numpy~=1.23.4"
   "soundfile~=0.12.0" "pypinyin~=0.47.1" "pyloudnorm~=0.1.0" "cvxopt~=1.3.0" "sounddevice~=0.4.5" "matplotlib~=3.9.2" "phonemizer~=3.2.1" "pyqt5~=5.15.11" "pyqtgraph~=0.13.7" "wandb~=0.13.5"
  "speechbrain==0.5.13" "dragonmapper~=0.2.6" "alias_free_torch~=0.0.6" "dotwiz==0.4.0" "transphone==1.5.3" "phonepiece==1.4.2" "geopy==2.4.1" "einops==0.7.0" "datasets~=2.10.1" "pandas~=1.5.0"
  "rich~=13.4.2" "PyYAML~=6.0" "imageio~=2.34.0" "pykakasi~=2.2.1" "jamo~=0.4.1" "g2pk~=0.9.4" "pykan~=0.2.6" "pynput~=1.7.7" "PyAutoGUI~=0.9.54" "networkx~=3.3" "scikit-learn~=1.5.0"
  "huggingface-hub>=0.28.1" "gradio~=5.23.2"

実行

日本語および英語の音声を生成してみます

PHONEMIZER_ESPEAK_LIBRARY=/opt/homebrew/lib/libespeak-ng.dylib uv run python -c "
  from InferenceInterfaces.ToucanTTSInterface import ToucanTTSInterface
  import os
  os.makedirs('audios', exist_ok=True)

  tts = ToucanTTSInterface(device='cpu')

  # 英語
  tts.set_language('eng')
  tts.read_to_file(['Hello, this is a test.'], 'audios/test_english.wav')

  # 日本語
  tts.set_language('jpn')
  tts.read_to_file(['こんにちは、テストです。'], 'audios/test_japanese.wav')
  "

日本語はG2PにTransphoneを使っているのもあってかアクセントの精度は高くないです

2016-2025年のSteamゲーム10万本を分析した結果

初めに

ゲームをSteamでリリースする場合,価格設定やタイトルの決め方,企画時のジャンル等データを見てから決める方がいいことが多々あります。今回は,Steam Web APIおよびSteam Storefront APIを使用して分析を行いました

分析データの概要

項目
総ゲーム数 100,870本
分析期間 2016-2025年
ユニーク開発者数 64,950
ユニークパブリッシャー数 58,602
データ収集期間 2025年11月-12月(17日間)

ゲームリリース数

年数ごとのリリース本数です。

  • 2016年: 約1,200本
  • 2025年: 約21,667本

わずか10年で約18倍に増加しています。Steam Directの導入(2017年)により参入障壁が下がったことが大きな要因と考えられます。

価格競争の実態

価格分析では、低価格化の傾向が顕著に表れています。グラフから半数以上が5ドル以下であることがわかります

指標
無料ゲーム率 15.1%
有料ゲーム平均価格 $8.36
有料ゲーム中央値価格 $4.99

以下が価格分布詳細です

  • フルプライス($59.99)で成功しているのは大手タイトルのみ
  • インディーゲームの多くは$5-$20の価格帯
  • 無料+課金モデル(F2P)も15%を占める

タグの分布について

ジャンル分析では、Indieタグが圧倒的です。

順位 ジャンル 割合
1 Indie 72%
2 Action 49%
3 Casual 37%
4 Adventure 32%
5 Simulation 19%

またジャンプ別の価格は以下です

自己パブリッシュ率についても確認してみます。

レビュー数分布

86,065本(85.3%)のゲームがレビュー100件未満

つまり、Steamにリリースされたゲームの大多数は、ほとんど注目を集められていないのです。

※ Steam APIはレビュー数100件未満のゲームにはレビューデータを返さないため、この数字には実際の0件〜100件程度のゲームが含まれます。

ゲーム機能の傾向

Steam機能への対応状況を見ると:

  • シングルプレイヤー: 最も多い
  • Steam実績: 多くのゲームが対応
  • コントローラーサポート: 増加傾向
  • マルチプレイヤー: 全体の約20%

任意の話し声を歌声に変換する音声変換「toSinging」を動かす

初めに

話している音声から歌声に変換する面白いものがあったので、動かしていきます。

github.com

依存関係が固定化されていなかったので、以下にuvで整理をしたものを作成しました

github.com

記事の内容はfork版とします。

開発環境

環境構築

モデルファイルもあるので、lfsを設定します

git lfs install
git clone https://github.com/akinori-ito/toSinging.git
cd toSinging

# Install dependencies
uv sync

実行

サンプル音声(話し音声)とMusicXML楽譜から歌っている感じに変換してみます




uv run python tosinging.py -i speech.wav -m song.musicxml -o singing.wav -bpm 120

制度としてはあまり高くない感じでしたが面白い内容です

自然言語プロンプトで音声スタイルを制御できる「ParaStyleTTS」を動かす

初めに

プロンプトで音声スタイルを制御するものを触っていきます。日本語は対応していないので英語と中国語のみです

github.com

以下のアーキテクチャーで二段階に分けてスタイルを適応しているところがポイントです

  アーキテクチャの新規性

  スタイルプロンプト → SentenceTransformer (768次元)
                            ↓
          ┌─────────────────┴─────────────────┐
          ↓                                   ↓
     局所スタイル                         大域スタイル
    (FiLMで音素に適用)                (VITS全体に適用)
          ↓                                   ↓
          └─────────────────┬─────────────────┘
                            ↓
                      VITS音声生成

開発環境

環境構築

# 仮想環境の作成
uv venv --python=3.11
source .venv/bin/activate

# 依存関係のインストール

uv pip install torch==2.6.0 torchaudio==2.6.0
uv pip install Cython==3.0.12 librosa==0.10.2.post1 nltk==3.9.1  numpy==2.3.3 pypinyin==0.53.0 scipy==1.16.2 sentence_transformers==4.0.1

# Cythonモジュールのビルド
cd tts/monotonic_align
uv run python setup.py build_ext --inplace
cd ../..

# NLTKデータのダウンロード
uv run python -c "import nltk; nltk.download('cmudict')"

実行

以下を実行します

uv run python generate.py

中国語に関しては、母国語の人曰く精度はかなり良いらしいです

低レイテンシな音声コードブック生成+軽量デコーダのストリーミング志向オープンソース多言語TTS「kani-tts」を動かす

初めに

多言語対応している高速なTTS kani-ttsを動かしていきます

開発環境

環境構築

必要なライブラリを入れます

uv venv .venv --python 3.12
uv pip install --python .venv/bin/python "nemo-toolkit[tts]==2.4.0"
uv pip install --python .venv/bin/python --no-deps --force-reinstall "transformers==4.57.1"
uv pip install --python .venv/bin/python "tokenizers==0.22.0"

Torch や Matplotlib が書き込みできる場所を明示する。

mkdir -p tmp hf_cache
export TMPDIR="$(pwd)/tmp"
export HF_HOME="$(pwd)/hf_cache"

実行

英語の文章を生成する場合は以下を実行します

TMPDIR=./tmp HF_HOME=./hf_cache .venv/bin/python examples/basic/main.py

精度としては英語以外は微妙な感じでした

リアルタイム物体検出フレームワーク「DEIMv2」を動かす

初めに

画像や動画の物体検出にはYoloがよく使われますが、他の選択肢を知ったので触ってみます。
今回触ってみるDEIMv2(DETR with Improved Matching v2) は、DINOv3の特徴を活用したリアルタイム物体検出フレームワークです。

DINOv3とは

DINOv3 とは、Metaが開発したVision 基盤モデルです

DEIMv2とは

DEIMv2は 内部の処理(モデル)に DINO v3を使ったリアルタイム物体検出フレームワークです

YOLOとの比較

精度重視、研究用途の場合はDEIMv2を選択肢となりそうです

開発環境

環境構築

環境の作成します

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

依存関係のインストールをします

uv pip install torch torchvision

# DEIMv2の依存関係
uv pip install PyYAML tensorboard scipy calflops transformers
uv pip install "faster-coco-eval>=1.6.7"

# モデルダウンロード用
uv pip install gdown

# 推論用(画像・動画処理)
uv pip install opencv-python pillow

モデルをダウンロードします(手動でも問題ないです)。今回は一番精度の良いものを使います

gdown "https://drive.google.com/uc?id=1pTiQaBGt8hwtO0mbYlJ8nE-HGztGafS7" -O deimv2_x.pth

実行

今回はサンプルの画像と動画を実行します

  • 画像で推論
python tools/inference/torch_inf.py \
    -c configs/deimv2/deimv2_dinov3_x_coco.yml \
    -r deimv2_x.pth \
    -i sample.jpg \
    -d cpu

  • 動画で推論
python tools/inference/torch_inf.py \
    -c configs/deimv2/deimv2_dinov3_x_coco.yml \
    -r deimv2_x.pth \
    -i your_video.mp4 \
    -d cpu