Skip to content

Latest commit

 

History

History
212 lines (157 loc) · 10.7 KB

README.md

File metadata and controls

212 lines (157 loc) · 10.7 KB

Piper Plus

CI PyPI Python License: MIT

高速・高品質なニューラルテキスト音声合成 (TTS) システム。VITS アーキテクチャを採用し、8言語マルチスピーカー音声合成に対応。Piper のフォークで、日本語対応・音質向上・学習機能を大幅に強化しています。

Hugging Face デモ | WebAssembly デモ | GitHub

主要機能

  • 8言語対応 — 日本語・英語・中国語・韓国語・スペイン語・フランス語・ポルトガル語・スウェーデン語
  • 日本語 TTS — OpenJTalk統合、韻律情報 (A1/A2/A3)、文脈依存音素バリアント
  • 英語 TTS — g2p-en 2.1.0由来のコードを同梱したG2P(Apache-2.0、一部MIT)、espeak-ng 不要
  • マルチスピーカー — ベースモデル571話者、言語グループ均等サンプリング
  • カスタム辞書 — 200+技術用語の発音辞書内蔵
  • 音素入力 — [[ phonemes ]] 記法による直接指定
  • クロスプラットフォーム — Linux (x86_64/ARM64)、macOS (Apple Silicon)、Windows (x64)

インストール

# v2.0.2 の CPU パッケージ
pip install "piper-plus[cpu]==2.0.2"

Python 3.11+ が必要です。新しい venv で CPU は [cpu]、GPU は [gpu] を選びます(GPU: pip install "piper-plus[gpu]==2.0.2")。CUDA / cuDNN の要件は別途必要です。末尾の「provider 選択」も参照してください。

クイックスタート

コマンドライン

# モデル一覧を表示
piper-plus --list-models
piper-plus --list-models ja

# モデルをダウンロード
piper-plus --download-model tsukuyomi

# 音声を生成
piper-plus --model tsukuyomi --text "こんにちは、今日は良い天気ですね。" --output_file output.wav

Python API

import wave
from piper_plus import PiperVoice

voice = PiperVoice.load("path/to/model.onnx", config_path="path/to/config.json")
with wave.open("output.wav", "wb") as wav_file:
    voice.synthesize("こんにちは、今日は良い天気ですね。", wav_file)

Phoneme Timing (リップシンク・字幕同期)

piper-plus は VITS Duration Predictor から音素レベルのタイミング情報を抽出できます。リップシンク、字幕同期、カラオケアプリケーションで使用できます。各 runtime の timing 契約は共通仕様に合わせています。値の互換性はモデル、実装、丸め処理を同じ条件で確認してください。

Python API

from piper_plus import PiperVoice
from piper_plus.timing import (
    PhonemeTimingInfo,
    TimingResult,
    durations_to_timing,
    timing_to_json,
    timing_to_tsv,
    timing_to_srt,
)

voice = PiperVoice.load("model.onnx", config_path="config.json")

# モデルが durations 出力をサポートしているか確認
if voice.has_duration_output:
    wav_bytes, timing = voice.synthesize_with_timing("こんにちは")

    if timing:
        # JSON 出力 (pretty-printed)
        print(timing_to_json(timing))

        # TSV 出力 (タブ区切り、ヘッダ付き)
        with open("timing.tsv", "w") as f:
            f.write(timing_to_tsv(timing))

        # SRT 字幕形式
        with open("subtitles.srt", "w") as f:
            f.write(timing_to_srt(timing))

        # 各音素を直接アクセス
        for p in timing.phonemes:
            print(f"{p.phoneme}: {p.start_ms:.1f} - {p.end_ms:.1f} ms ({p.duration_ms:.1f} ms)")

出力例

{
  "phonemes": [
    {"phoneme": "^", "start_ms": 0.0, "end_ms": 58.0, "duration_ms": 58.0},
    {"phoneme": "k", "start_ms": 58.0, "end_ms": 150.8, "duration_ms": 92.8},
    {"phoneme": "o", "start_ms": 150.8, "end_ms": 290.0, "duration_ms": 139.2}
  ],
  "total_duration_ms": 290.0,
  "sample_rate": 22050
}

HTTP エンドポイント

piper_plus.http_server を起動すると /api/phoneme-timing エンドポイントが利用可能になります:

# JSON で取得
curl "http://localhost:5000/api/phoneme-timing?text=Hello&format=json"

# TSV で取得
curl "http://localhost:5000/api/phoneme-timing?text=Hello&format=tsv"

# 言語指定
curl "http://localhost:5000/api/phoneme-timing?text=Hello&language=en&format=json"

API リファレンス

関数 / メソッド 説明
PiperVoice.synthesize_with_timing(text, ...) 音声 + TimingResult を返す
PiperVoice.has_duration_output モデルが timing をサポートするか判定
durations_to_timing(durations, tokens, sample_rate, hop_length) duration フレーム → TimingResult
timing_to_json(result) pretty-printed JSON
timing_to_json_compact(result) 単一行 JSON
timing_to_tsv(result) TSV (start_ms, end_ms, duration_ms, phoneme)
timing_to_srt(result) SRT 字幕形式
build_phoneme_id_reverse_map(phoneme_id_map, pua_to_multi_char?) ID → 音素文字列の逆引きマップ

設定

config.json の audio.hop_size で STFT hop length を指定できます (デフォルト: 256)。値は PiperConfig.hop_size 経由で利用され、timing 計算に使用されます。

事前学習済みモデル

モデル 言語 話者数 ダウンロード
tsukuyomi-chan 6言語 (ja/en/zh/es/fr/pt) 1 piper-plus --download-model tsukuyomi

公開 Zero-Shot / fine-tuning bundle (zs-v1)

一般利用向けの Zero-Shot ベースは、固定 revision の piper-plus-base/releases/zs-v1 から取得してください。これは v7 epoch32 の実験的チェックポイントで、JA/EN/ZH/ES/FR/PT、173 phonemes、CAM++ 192 次元です。 通常の参照音声なし TTS には tsukuyomi などの既成音声を使い、base.onnx は参照 embedding を渡す Zero-Shot 推論または fine-tuning に使います。

ZS_REV=3620ed788667cb76f08bd6cf2db8152c1f4c8bd1
ZS_URL="https://huggingface.co/ayousanz/piper-plus-base/resolve/${ZS_REV}/releases/zs-v1"
mkdir -p models/zs-v1
curl -L "${ZS_URL}/base.onnx" -o models/zs-v1/base.onnx
curl -L "${ZS_URL}/base.onnx.json" -o models/zs-v1/base.onnx.json
curl -L "${ZS_URL}/config.json" -o models/zs-v1/config.json
curl -L "${ZS_URL}/campplus.onnx" -o models/zs-v1/campplus.onnx
curl -L "${ZS_URL}/base.ckpt" -o models/zs-v1/base.ckpt

推論は base.onnx + base.onnx.json、追加学習は base.ckpt + 同じ bundle の config.json を使ってください。HF リポジトリ root の旧 config.json や model.ckpt と混在させないでください。公開 bundle の参照音声からの embedding 事前計算例は、zs-v1 の公開 README を参照してください。

この bundle の reference-conditioned 推論は PyPI piper-plus==2.0.0 で確認済みです。加えて、公開 CI run 38189966578 では 6 runtime の推論レポートを、Python で共有した phoneme IDs を入力として取得しています。この CI 範囲には native G2P と listening quality は含まれず、品質承認も行っていません。Python package の確認と runtime CI の範囲は別の証拠です。base / zero-shot-base-zs-v1 alias は v2.0.2 に収録されています(2.0.0 / 2.0.1 には未収録)。

対応言語

言語 コード Phonemizer 依存
日本語 ja OpenJTalk pyopenjtalk-plus
英語 en 同梱 g2p-en 2.1.0由来のバックエンド NumPy / NLTK / joblib / inflect
中国語 zh pypinyin pypinyin
韓国語 ko g2pk2 g2pk2 (Apache-2.0, optional)
スペイン語 es 規則ベース なし
フランス語 fr 規則ベース なし
ポルトガル語 pt 規則ベース なし
スウェーデン語 sv 規則ベース なし

その他のインターフェース

  • C++ CLI — ストリーミング、CUDA推論、カスタム辞書
  • Rust CLI — ストリーミング、CUDA/CoreML/DirectML対応
  • C# CLI (.NET) — クロスプラットフォーム .NET 10
  • WebAssembly — ブラウザ内で完全動作
  • Docker — 推論・学習・WebUI イメージ

リンク

ライセンス

MIT License — 詳細は LICENSE を参照。

英語バックエンドのソース・重み・同綴異音語表はprivate namespaceへ同梱し、 Apache-2.0および数値正規化コードのMIT許諾文を含めています。 v2.0.2 では外部の g2p-en と、その未使用のGPL依存 Distance を導入しません。 公開済み piper-plus==2.0.0 / 2.0.1 の依存定義は変更されません。 移行手順を参照してください。

provider 選択

v2.0.2 は CPU/GPU ORT を基底依存にせず、[cpu] / [gpu] の一方を選びます。既存環境で切り替える場合は新しい venv を使用してください。公開済み v2.0.1 の基底依存は CPU ORT を含むため、v2.0.2 とは異なります。ソースから GPU 環境を作る場合は root で uv sync --locked --no-group cpu --extra inference-gpu を使用し、実行には uv run --no-sync を使用します。