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?

GPU コンテナの高火力 DOK で Chatterbox(テキスト読み上げ)を試す

Last updated at Posted at 2025-07-08

高火力 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 機能で、コンテナレジストリを提供しています。さくらのクラウドにログインしたら さくらのクラウド を選択します。

image.png

左側のメニューの グローバル の中にある コンテナレジストリ を選択します。

image.png

追加 を押して、コンテナレジストリを作成します。最低限、以下の入力が必要です。

項目 設定
名前 分かりやすい、任意の名前を入力してください
コンテナレジストリ名 ドメイン名に使われます。以下では、 EXAMPLE.sakuracr.jp として説明します
公開設定 Pull のみとします

ユーザーの作成

コンテナレジストリを作成したら、作成したコンテナレジストリを一覧でダブルクリックします。

image.png

詳細表示にて、ユーザータブをクリックします。

image.png

追加ボタンを押し、ユーザーを作成します。 YOUR_USER_NAMEPASSWORD は任意のものを指定してください。

項目 設定
ユーザー名 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!

FireShot Capture 393 - 高火力 DOK - タスク › 新規作成 - secure.sakura.ad.jp.jpg

実行完了し、音声ファイルが生成できていれば成功です。

まとめ

今回は Chatterbox を使って、高火力 DOK 上で音声生成を行いました。まずは実行できるのみ、次に Docker イメージの作成と段階的に進められるようにしています。動画生成のように、処理に時間がかかるものを利用する際に高火力 DOK は便利です。

高火力 DOK はタスクを多数立ち上げて、後は結果を待つのみと言った使い方ができます。ぜひ AI ・機械学習に活用してください。

コンテナー型 GPU クラウドサービス 高火力 DOK(ドック) | さくらインターネット

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?