0
1

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でVALL-E X(音声読み上げAI)を試す

Posted at

DOKはコンテナー型のGPUサービスで、NVIDIA V100とかH100を実行時間課金で利用できるサービスです。

image.png

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

今回はこのDOKで、VALL-E X(音声読み上げAI) を試してみました。

実行までのステップ

  1. さくらのクラウドのアカウントの用意(必須)
  2. Dockerイメージのビルド環境(Linuxなど)を用意
  3. Dockerイメージのビルド
  4. DOKにイメージをアップロード
  5. DOKでコンテナーを起動・実行

1. さくらのクラウドのアカウントの用意

DOKはさくらのクラウドに紐付いたサービスなので、さくらのクラウドのアカウント必須です。

クラウドサーバーはIaaS型のさくらのクラウド

コンテナレジストリの作成

さくらのクラウドにログインしたら さくらのクラウド を選択します。

image.png

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

image.png

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

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

ユーザーの作成

コンテナレジストリにアクセスできるユーザーを作成します。作成したコンテナレジストリをダブルクリックして、詳細を表示します。

image.png

ユーザー タブを選択して、追加 を押します。

IDとパスワードを設定して、権限は All にして作成してください。

2. Dockerイメージのビルド環境(Linuxなど)を用意

WindowsのWSL2でできるかは分かりませんが、少なくともmacOS(M1など)ではDockerイメージをビルドできなかったので、別途用意が必要です。これは適当なVPSサーバーや自宅サーバ、さくらのクラウドでインスタンスを立ち上げるでもOKです。

以下はスペックの例です。

  • コア
    2
  • メモリ
    4GB
  • OS
    Ubuntu Server 22.04.4 LTS 64bit
  • ディスク
    100GB

3. Dockerイメージのビルド

作業フォルダを作成します。

mkdir VALL-E-X
cd VALL-E-X

後はこの VALL-E-X ディレクトリの中で処理を書いていきます。

Dockerfileの作成

Dockerfileを作成します。内容は以下の通りです。

FROM nvidia/cuda:12.5.1-runtime-ubuntu22.04
ENV DEBIAN_FRONTEND=noninteractive

# 必要なパッケージのインストール
# /appはアプリのディレクトリ、/opt/artifactはアウトプット先のディレクトリ
RUN apt-get update && \
    apt-get install -y \
        git \
        git-lfs \
        python3 \
        python3-pip \
      && \
    mkdir /app /opt/artifact && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# VALL-E Xのリポジトリをクローン
RUN git clone https://github.com/Plachtaa/VALL-E-X.git /app
WORKDIR /app
# git-lfsのインストール
RUN git lfs install --skip-smudge 
# 依存ライブラリのインストール
RUN pip install -r requirements.txt
# 出力データをオブジェクトストレージにアップロードするためのライブラリ
RUN pip install boto3
RUN pip cache purge

# 実行スクリプト(後で作成)
COPY runner.py /app/
# Dockerコンテナー起動時に実行するスクリプト(後で作成)
COPY docker-entrypoint.sh /
# 実行権限を付与
RUN chmod +x /docker-entrypoint.sh /

WORKDIR /
# Dockerコンテナー起動時に実行するスクリプトを指定して実行
CMD ["/bin/bash", "/docker-entrypoint.sh"]

docker-entrypoint.shの作成

docker-entrypoint.shは、Dockerコンテナー起動時に実行するスクリプトです。内容は以下の通りです。

#!/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 TEXT is not set" >&2
  exit 1
fi

# S3_はすべてboto3用の環境変数です
pushd /app
  python3 runner.py \
	  --id="${SAKURA_TASK_ID}" \
	  --output="${SAKURA_ARTIFACT_DIR}" \
	  --text="${TEXT}" \
	  --s3-bucket="${S3_BUCKET:-}" \
	  --s3-endpoint="${S3_ENDPOINT:-}" \
	  --s3-secret="${S3_SECRET:-}" \
	  --s3-token="${S3_TOKEN:-}"
popd

runner.pyの作成

runner.pyは実際に実行するスクリプトです。内容は以下の通りです。

ライブラリの読み込み

最初にライブラリを読み込みます。

from utils.generation import SAMPLE_RATE, generate_audio, preload_models
from scipy.io.wavfile import write as write_wav
import argparse

引数のパース

実行時に渡される引数をパースします。

arg_parser = argparse.ArgumentParser()

arg_parser.add_argument(
    '--output',
    default='/opt/artifact',
    help='出力先ディレクトリを指定します。',
)
arg_parser.add_argument(
    '--text',
    default='Hello from Dok',
    help='読み上げるテキストを指定します。',
)
arg_parser.add_argument(
    '--id',
    default='',
    help='タスクIDを指定します。',
)
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()

モデルの読み込み

必要なモデルをダウンロードして読み込みます。

preload_models()

テキストから音声の生成

テキストから音声データを生成します。

audio_array = generate_audio(args.text)

音声データの保存

音声データを保存します。 /opt/artifact ディレクトリに output-{args.id}.wav という名前で保存します。

file = f'{args.output}/output-{args.id}.wav'
write_wav(file, SAMPLE_RATE, audio_array)

オブジェクトストレージへのアップロード

もし、S3_ではじまる環境変数が設定されていれば、boto3を使って出力内容をアップロードします。

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,
    )
		# ファイルアップロード
		s3.upload_file(
			Filename=file,
			Bucket=args.s3_bucket,
			Key=os.path.basename(file),
		)

全体のコード

runner.py の全体のコードは以下の通りです。

from utils.generation import SAMPLE_RATE, generate_audio, preload_models
from scipy.io.wavfile import write as write_wav
import argparse

arg_parser = argparse.ArgumentParser()

arg_parser.add_argument(
    '--output',
    default='/opt/artifact',
    help='出力先ディレクトリを指定します。',
)
arg_parser.add_argument(
    '--text',
    default='Hello from Dok',
    help='読み上げるテキストを指定します。',
)
arg_parser.add_argument(
    '--id',
    default='',
    help='タスクIDを指定します。',
)
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()

preload_models()

audio_array = generate_audio(args.text)

file = f'{args.output}/output-{args.id}.wav'
write_wav(file, SAMPLE_RATE, audio_array)

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,
    )
		# ファイルアップロード
		s3.upload_file(
			Filename=file,
			Bucket=args.s3_bucket,
			Key=os.path.basename(file),
		)

Dockerイメージのビルド

Dockerイメージをビルドします。この時、コンテナレジストリのドメイン名を使ってイメージ名を作成してください。

EXAMPLE.sakuracr.jp の場合、 EXAMPLE.sakuracr.jp/VALL-E-X といった名前になります。 VALL-E-X は適当に分かりやすいものを付けます。

$ sudo docker build -t EXAMPLE.sakuracr.jp/VALL-E-X .

実際の動作を確認する際には、docker run でコンテナーを起動して動作確認をしてください。出力ファイルを確認する際には、適当なディレクトリを /opt/artifact にマウントしてください。

$ sudo docker run -e TEXT=hello \
    -e SAKURA_TASK_ID=001 \
    -e SAKURA_ARTIFACT_DIR=/opt/artifact \
    -v /path/to/data/:/opt/artifact \
    -t EXAMPLE.sakuracr.jp/VALL-E-X

これで、/path/to/data/output-001.wav というファイルが作成されているはずです。

4. DOKにイメージをアップロード

作成したDockerイメージをDOKにアップロードします。まずコンテナレジストリにログインします。コンテナレジストリのドメイン、ユーザー名、パスワードを入力してください。

$ sudo docker login EXAMPLE.sakuracr.jp
Username:
Password:

ログインしたら、イメージをプッシュします。

$ sudo docker image push EXAMPLE.sakuracr.jp/VALL-E-X

これでプッシュが終われば、準備は完了です。

5. DOKでコンテナーを起動・実行

レジストリーの登録

DOKのダッシュボードで、 レジストリー を選択して、 新規登録 を押します。

image.png

以下のように入力してください。入力したら、 登録 を押します。

項目 設定
ホスト名 例)EXAMPLE.sakuracr.jp
ユーザー名 コンテナレジストリで登録したもの
パスワード コンテナレジストリで登録したもの
パスワード(確認用) コンテナレジストリで登録したもの

タスクの作成

DOKのダッシュボードで、 タスク を選択して、 新規作成 を押します。

image.png

以下のように入力してください。入力したら、 作成 を押します。 :latest をつけて、レジストリの最新イメージを指定しています。

項目 設定
イメージ EXAMPLE.sakuracr.jp/VALL-E-X:latest
レジストリー 登録したレジストリー
コマンド 何もなし
エントリーポイント 何もなし
環境変数 後述
プラン v100-32gbまたはh100-80gb

環境変数は、以下のように設定してください。

項目 設定
TEXT 読み上げるテキストを指定します

TEXTは英語や日本語、中国語が指定できます(自動判別)。

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

タスクを作成するとキューに入り、順番に処理されます。

結果の確認

結果はタスクの画面で確認できます。完了していれば、 アーティファクト にて、出力ファイルをダウンロードできます。なお、ファイルはtar.gz形式で圧縮されています。

image.png

おまけ(オブジェクトストレージを使う)

アーティファクトの保存期限は72時間なので、データを永続的に残しておきたい場合はオブジェクトストレージへの保存をお勧めします。

オブジェクトストレージの作成

さくらのクラウドのダッシュボードで、 オブジェクトストレージ を選択します。

image.png

バケットとアクセスキーを作成します。シークレットアクセスキーも生成されるので、保存しておいてください。

image.png

情報としては、以下が手に入ります(例)。

  • S3エンドポイント
    s3.isk01.sakurastorage.jp
  • バケット名
    自分で決めたもの
  • アクセスキー
    自動生成されたもの
  • シークレットアクセスキー
    自動生成されたもの

そして、これらの情報をDOKのタスク実行時の環境変数に設定してください。

項目 設定
S3_ENDPOINT S3エンドポイント
S3_BUCKET バケット名
S3_TOKEN アクセスキー
S3_SECRET シークレットアクセスキー

これでDOKのタスクを実行すると、結果ファイルがオブジェクトストレージにアップロードされます。ファイルアップロードの場合は、圧縮されていない状態で取得できます。

image.png

まとめ

今回は、DOKでVALL-E X(音声読み上げAI)を試してみました。Dockerイメージを作成する必要があるので、Dockerの知識とDockerイメージを作成できる環境を用意する必要があるので注意してください。

Dockerイメージさえできてしまえば、後は環境変数を指定して実行すれば良いだけなので簡単です。ぜひAI・機械学習などに活用してください。

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

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?