高火力 DOKはコンテナー型の GPU サービスで、NVIDIA V100 や H100 を実行時間課金で利用できるサービスです。
今回はこの高火力 DOK を使って、Chatterboxを試してみました。
Chatterbox について
Chatterbox は、Resemble AI が開発したオープンソースの TTS(テキスト読み上げ)です。ゼロショットで利用でき、学習などの手間はありません。また、リファレンスの音声も指定可能で、自分の声風に読ませることもできます。もう一つの特徴として、exaggeration(誇張度)という設定があり、感情の起伏をコントロールできます。
参考
ResembleAI/chatterbox · Hugging Faceをベースに進めます。なお、日本語の読み上げにも対応しているという記事がいくつかあったのですが、執筆時点(2025 年 6 月)では日本語にはまだ未対応のようです。
とりあえず試す
コンテナレジストリにプッシュ済みのイメージを使って実行してみたい方は、高火力 DOK にて新しいタスクを作成し、以下の情報を入力してください。TEXT は読み上げるテキストで、現在は英語のみ指定できます。
なお、モデルは V100 で問題ありません。
項目 | 設定 |
---|---|
イメージ | dok-handson.sakuracr.jp/chatterbox |
環境変数 | TEXT=Hello, world! |
この他、以下のプロパティが指定できます。
項目 | 説明 | デフォルト |
---|---|---|
EXAGGERATION | 感情度 | 0.5 |
CFG | 読み上げ速度 | 0.5 |
REFERENCE | 参照する音声 | |
S3_BUCKET | オブジェクトストレージのバケット名を指定します | |
S3_ENDPOINT | オブジェクトストレージのエンドポイントを指定します | |
S3_SECRET | オブジェクトストレージのシークレットアクセスキーを指定します | |
S3_TOKEN | オブジェクトストレージのアクセスキー ID を指定します |
S3_で始まる環境変数は、さくらのオブジェクトストレージに画像を保存するためのものです。保存しない場合には指定しなくても問題ありません。
以下はリファレンス付きの生成例です。筆者の声風に、英語の文章を読み上げています
https://s3.isk01.sakurastorage.jp/dok-handson/chatterbox.wav
コンテナイメージの作成と登録
上記タスクで利用した Docker イメージを作成する手順は以下の通りです。完成版はgoofmint/dok-chatterboxにありますので、実装時の参考にしてください。
Dockerfile の作成
ResembleAI/chatterbox · Hugging Faceの内容に沿って、Dockerfile を作成します。
ベースイメージ
ベースは continuumio/miniconda3
です。Python 3.11 の環境を作ります。
FROM continuumio/miniconda3
# conda create
RUN conda create -n chatterbox python==3.11
SHELL ["conda", "run", "-n", "chatterbox", "/bin/bash", "-c"]
ライブラリのインストール
Python と、必要なライブラリをインストールします。
RUN apt-get update && \
apt-get install -y ffmpeg && \
mkdir /app /opt/artifact
WORKDIR /app
COPY . .
RUN pip install chatterbox-tts
RUN pip uninstall numpy -y && \
pip install --no-cache-dir "numpy<2.1.0" && \
pip uninstall transformers -y && \
pip install --no-cache-dir transformers && \
pip install boto3 argparse
後は 後述する docker-entrypoint.sh
をコピーします。
RUN chmod +x /app/docker-entrypoint.sh
# Docker コンテナー起動時に実行するスクリプトを指定して実行
CMD ["/bin/bash", "/app/docker-entrypoint.sh"]
Dockerfile 全体
Dockerfile の全体は以下の通りです。
FROM continuumio/miniconda3
# conda create
RUN conda create -n chatterbox python==3.11
SHELL ["conda", "run", "-n", "chatterbox", "/bin/bash", "-c"]
RUN apt-get update && \
apt-get install -y ffmpeg && \
mkdir /app /opt/artifact
# install conda package
WORKDIR /app
COPY . .
RUN pip install chatterbox-tts
RUN pip uninstall numpy -y && \
pip install --no-cache-dir "numpy<2.1.0" && \
pip uninstall transformers -y && \
pip install --no-cache-dir transformers && \
pip install boto3 argparse
RUN chmod +x /app/docker-entrypoint.sh
# Docker コンテナー起動時に実行するスクリプトを指定して実行
CMD ["/bin/bash", "/app/docker-entrypoint.sh"]
docker-entrypoint.sh の作成
docker-entrypoint.sh
は Docker コンテナー起動時に実行するスクリプトです。ここでは環境変数をチェックして、 runner.py
を呼び出します。以下の内容で作成します。TEXT は必須で、他は任意です。SAKURA_
ではじまる環境変数は、高火力 DOK 実行時に自動的に渡される変数になります。
#!/bin/bash
set -ue
shopt -s nullglob
export TZ=${TZ:-Asia/Tokyo}
# アウトプット先ディレクトリ(自動付与) /opt/artifact 固定です
if [ -z "${SAKURA_ARTIFACT_DIR:-}" ]; then
echo "Environment variable SAKURA_ARTIFACT_DIR is not set" >&2
exit 1
fi
# DOK のタスク ID(自動付与)
if [ -z "${SAKURA_TASK_ID:-}" ]; then
echo "Environment variable SAKURA_TASK_ID is not set" >&2
exit 1
fi
# 読み上げるテキスト(環境変数で指定)
if [ -z "${TEXT:-}" ]; then
echo "Environment variable PROMPT is not set" >&2
exit 1
fi
# 感情強度
if [ -z "${EXAGGERATION:-}" ]; then
EXAGGERATION=0.5
fi
# 読み上げ速度
if [ -z "${CFG:-}" ]; then
CFG=0.5
fi
# リファレンスの音声
if [ -z "${REFERENCE:-}" ]; then
REFERENCE=""
else
wget $REFERENCE -O /tmp/reference.mp3
REFERENCE="/tmp/reference.mp3"
fi
# S3_はすべて boto3 用の環境変数です
cd /app
conda run -n chatterbox python3 runner.py \
--id="${SAKURA_TASK_ID}" \
--output="${SAKURA_ARTIFACT_DIR}" \
--text="${TEXT}" \
--exaggeration="${EXAGGERATION}" \
--cfg="${CFG}" \
--reference="${REFERENCE}" \
--s3-bucket="${S3_BUCKET:-}" \
--s3-endpoint="${S3_ENDPOINT:-}" \
--s3-secret="${S3_SECRET:-}" \
--s3-token="${S3_TOKEN:-}"
runner.py の作成
runner.py は実際に処理を行うスクリプトです。まず必要なライブラリをインポートします。
import os
import argparse
import boto3
import torchaudio as ta
from chatterbox.tts import ChatterboxTTS
パラメータの取得
docker-entrypoint.sh
から渡されたパラメータを取得します。
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument(
'--output',
default='/opt/artifact',
help='出力先ディレクトリを指定します。',
)
arg_parser.add_argument(
'--id',
default='',
help='タスク ID を指定します。',
)
arg_parser.add_argument(
'--text',
default='',
help='読み上げる文章',
)
arg_parser.add_argument(
'--exaggeration',
type=float,
default=0.5,
help='感情強度',
)
arg_parser.add_argument(
'--cfg',
type=float,
default=0.5,
help='読み上げ速度',
)
arg_parser.add_argument(
'--reference',
default='',
help='リファレンスの音声',
)
arg_parser.add_argument('--s3-bucket', help='S3 のバケットを指定します。')
arg_parser.add_argument('--s3-endpoint', help='S3 互換エンドポイントの URL を指定します。')
arg_parser.add_argument('--s3-secret', help='S3 のシークレットアクセスキーを指定します。')
arg_parser.add_argument('--s3-token', help='S3 のアクセスキー ID を指定します。')
args = arg_parser.parse_args()
オブジェクトストレージ用のオブジェクトを準備
S3_ではじまる環境変数があれば、それを使って S3 オブジェクトを作成します。
s3 = None
if args.s3_token and args.s3_secret and args.s3_bucket:
# S3 クライアントの作成
s3 = boto3.client(
's3',
endpoint_url=args.s3_endpoint if args.s3_endpoint else None,
aws_access_key_id=args.s3_token,
aws_secret_access_key=args.s3_secret)
Chatterbox の準備
Chatterbox は ChatterboxTTS.from_pretrained
を呼び出すだけで準備完了です。
model = ChatterboxTTS.from_pretrained(device="cuda")
テキストの指定と読み上げ
テキストを読み上げ、結果を WAV ファイルとして保存します。参考にする音声が指定されている場合には、それを利用します。
text = args.text
wav = model.generate(text, exaggeration=args.exaggeration, cfg_weight=args.cfg, audio_prompt_path=args.reference)
save_path = f"{args.output}/{args.id}.wav"
ta.save(save_path, wav, model.sr)
オブジェクトストレージへの保存
オブジェクトストレージに関する設定があれば、それに沿ってデータを保存します。
if s3 is not None:
s3.upload_file(
Filename=save_path,
Bucket=args.s3_bucket,
Key=os.path.basename(save_path))
全体の処理
runner.py
の全体の処理は以下の通りです。
import os
import argparse
import boto3
import torchaudio as ta
from chatterbox.tts import ChatterboxTTS
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument(
'--output',
default='/opt/artifact',
help='出力先ディレクトリを指定します。',
)
arg_parser.add_argument(
'--id',
default='',
help='タスク ID を指定します。',
)
arg_parser.add_argument(
'--text',
default='',
help='読み上げる文章',
)
arg_parser.add_argument(
'--exaggeration',
type=float,
default=0.5,
help='感情強度',
)
arg_parser.add_argument(
'--cfg',
type=float,
default=0.5,
help='読み上げ速度',
)
arg_parser.add_argument(
'--reference',
default='',
help='リファレンスの音声',
)
arg_parser.add_argument('--s3-bucket', help='S3 のバケットを指定します。')
arg_parser.add_argument('--s3-endpoint', help='S3 互換エンドポイントの URL を指定します。')
arg_parser.add_argument('--s3-secret', help='S3 のシークレットアクセスキーを指定します。')
arg_parser.add_argument('--s3-token', help='S3 のアクセスキー ID を指定します。')
args = arg_parser.parse_args()
s3 = None
if args.s3_token and args.s3_secret and args.s3_bucket:
# S3 クライアントの作成
s3 = boto3.client(
's3',
endpoint_url=args.s3_endpoint if args.s3_endpoint else None,
aws_access_key_id=args.s3_token,
aws_secret_access_key=args.s3_secret)
model = ChatterboxTTS.from_pretrained(device="cuda")
text = args.text
wav = model.generate(text, exaggeration=args.exaggeration, cfg_weight=args.cfg, audio_prompt_path=args.reference)
save_path = f"{args.output}/{args.id}.wav"
ta.save(save_path, wav, model.sr)
if s3 is not None:
s3.upload_file(
Filename=save_path,
Bucket=args.s3_bucket,
Key=os.path.basename(save_path))
Docker イメージのビルド
上記の内容で、Docker イメージをビルドします。Linux 環境などで行います。
コンテナレジストリの用意
Docker イメージを登録するコンテナレジストリを作成します。さくらのクラウドでは LAB 機能で、コンテナレジストリを提供しています。さくらのクラウドにログインしたら さくらのクラウド
を選択します。
左側のメニューの グローバル
の中にある コンテナレジストリ
を選択します。
追加
を押して、コンテナレジストリを作成します。最低限、以下の入力が必要です。
項目 | 設定 |
---|---|
名前 | 分かりやすい、任意の名前を入力してください |
コンテナレジストリ名 | ドメイン名に使われます。以下では、 EXAMPLE.sakuracr.jp として説明します |
公開設定 | Pull のみとします |
ユーザーの作成
コンテナレジストリを作成したら、作成したコンテナレジストリを一覧でダブルクリックします。
詳細表示にて、ユーザータブをクリックします。
追加ボタンを押し、ユーザーを作成します。 YOUR_USER_NAME
と PASSWORD
は任意のものを指定してください。
項目 | 設定 |
---|---|
ユーザー名 | YOUR_USER_NAME |
パスワード | YOUR_PASSWORD |
ユーザ権限設定 | All |
Docker イメージのビルド
Docker イメージは Linux で行います。今回は Ubuntu 24.04 を使っています。Docker が使える環境であれば、Windows + WSL2 でも問題ありません。macOS の場合、アーキテクチャが異なるので動かせないかも知れません(未検証です)。
EXAMPLE.sakuracr.jp
の部分は、作成したコンテナレジストリのドメイン名に置き換えてください。また、 chatterbox
は任意の名前で大丈夫です(以下はその名称で読み替えてください)。
sudo docker build -t EXAMPLE.sakuracr.jp/chatterbox:latest .
コンテナレジストリへのログイン
作成したコンテナレジストリにログインします。ログイン ID とパスワードが求められるので、作成したものを入力してください。
sudo docker login EXAMPLE.sakuracr.jp
イメージのプッシュ
作成したイメージをコンテナレジストリにプッシュします。イメージサイズが大きいので、数十分かかります。
sudo docker push EXAMPLE.sakuracr.jp/chatterbox:latest
タスクを作成する
後は最初と同じように高火力 DOK でタスクを作成、実行します。
項目 | 設定 |
---|---|
イメージ | EXAMPLE.sakuracr.jp/chatterbox |
環境変数 | TEXT=Hello, world! |
実行完了し、音声ファイルが生成できていれば成功です。
まとめ
今回は Chatterbox を使って、高火力 DOK 上で音声生成を行いました。まずは実行できるのみ、次に Docker イメージの作成と段階的に進められるようにしています。動画生成のように、処理に時間がかかるものを利用する際に高火力 DOK は便利です。
高火力 DOK はタスクを多数立ち上げて、後は結果を待つのみと言った使い方ができます。ぜひ AI ・機械学習に活用してください。