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?

DOKを使ってText2Video-Zeroでテキストから動画を生成する

Last updated at Posted at 2024-11-25

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

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

今回はこのDOKを使って、Text2Video-Zeroにてテキストから動画を生成してみます。

結果

結果は以下のようになっています。4FPSがデフォルトなので、別途フレーム補間は必要です。

text2video_A_horse_galloping_on_a_street.mp4.gif

とりあえず試す

学習済みのデータを使って実行してみたい方は、DOKにて新しいタスクを作成し、以下の情報を入力してください。

項目 設定
イメージ dok-handson.sakuracr.jp/text2video
環境変数 PROMPT=A horse galloping on a street
FPS=4
LENGTH=8

PROMPTで指定したテキストに対して動画を生成します。FPSはフレームレート、LENGTHは秒数です。処理は5分弱で終わります(V100の場合。Dockerイメージの準備などもあるので、実際の実行時間はもっと短いはずです)。

image.png

コンテナイメージの作成と登録

上記タスクで利用したDockerイメージを作成する手順は以下の通りです。ベースとしては、Picsart-AI-Research/Text2Video-Zeroを使っています。

完成版はgoofmint/dok-text2videoにありますので、実装時の参考にしてください。

必要なファイルの取得

上記リポジトリで、処理に必要なファイルを取得します。

  • assets
  • annotator
  • gradio_utils.py
  • model.py
  • requirements.txt
  • text_to_video_pipeline.py
  • utils.py

requirements.txt の修正

DOKで実行する際に必要なライブラリを追加します。 huggingface_hub も必要でした。

huggingface_hub==0.25.0
boto3

Dockerfile の作成

Dockerfileの内容は以下の通りです。必要なライブラリをインストールし、ファイルをコピーしています。また、 requirements.txt を使ってライブラリをインストールしています。

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 \
	libgl1-mesa-glx \
	libgl1-mesa-dev \
	libglib2.0-0 \
      && \
    mkdir /app /opt/artifact && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app
# 必要なファイルのコピー
COPY * /app/
COPY annotator/ /app/annotator/
COPY __assets__/ /app/__assets__/
# 必要なライブラリのインストール
RUN pip install -r requirements.txt
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コンテナー起動時に実行するスクリプトです。ここでは環境変数をチェックして、 runner.py を呼び出します。以下の内容で作成します。

#!/bin/bash

set -ue

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 "${PROMPT:-}" ]; then
  echo "Environment variable PROMPT is not set" >&2
  exit 1
fi

if [ -z "${FPS:-}" ]; then
  FPS=4
fi

if [ -z "${LENGTH:-}" ]; then
  LENGTH=8
fi

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

runner.py の作成

runner.py は実際に処理を行うスクリプトです。以下の内容で作成します。

import torch
from model import Model
import boto3
import argparse

def main():
    # この中に実装します

if __name__ == "__main__":
    main()    # メイン関数を実行

パラメータの取得

docker-entrypoint.sh から渡されたパラメータを取得します。

arg_parser = argparse.ArgumentParser()

arg_parser.add_argument(
    '--output',
    default='/opt/artifact',
    help='出力先ディレクトリを指定します。',
)
arg_parser.add_argument(
    '--prompt',
    help='プロンプトです',
)
arg_parser.add_argument(
    '--id',
    default='',
    help='タスクIDを指定します。',
)
arg_parser.add_argument(
    '--fps',
    default='4',
    help='FPSです。',
)
arg_parser.add_argument(
    '--length',
    default='8',
    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()

また、モデルを読み込む処理も追加します。

model = Model(device = "cuda", dtype = torch.float16)

main 関数の実装

main関数では、動画を生成するパスを作成し、後述する txt2video 関数を呼び出します。また、S3にアップロードする処理も追加しています。

def main():
    # この中に実装します
    file_path = f"{args.output}/{args.id}.mp4"
    print(f"Save to {file_path}")
    txt2video(file_path, args.prompt, int(args.fps), int(args.length))
    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(file_path, args.s3_bucket, os.path.basename(file))

txt2video 関数は以下の通りです。 model.process_text2video で動画を生成しています。

def txt2video(file_path, prompt, fps, length):
  params = {"t0": 44, "t1": 47 , "motion_field_strength_x" : 12, "motion_field_strength_y" : 12, "video_length": length}
  model.process_text2video(prompt, fps = fps, path = file_path, **params)

全体の処理

runner.py の全体の処理は以下の通りです。

import torch
from model import Model
import boto3
import argparse

arg_parser = argparse.ArgumentParser()

arg_parser.add_argument(
    '--output',
    default='/opt/artifact',
    help='出力先ディレクトリを指定します。',
)
arg_parser.add_argument(
    '--prompt',
    help='プロンプトです',
)
arg_parser.add_argument(
    '--id',
    default='',
    help='タスクIDを指定します。',
)
arg_parser.add_argument(
    '--fps',
    default='4',
    help='FPSです。',
)
arg_parser.add_argument(
    '--length',
    default='8',
    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()


model = Model(device = "cuda", dtype = torch.float16)

def txt2video(file_path, prompt, fps, length):
  params = {"t0": 44, "t1": 47 , "motion_field_strength_x" : 12, "motion_field_strength_y" : 12, "video_length": length}
  model.process_text2video(prompt, fps = fps, path = file_path, **params)

def main():
    # この中に実装します
    file_path = f"{args.output}/{args.id}.mp4"
    print(f"Save to {file_path}")
    txt2video(file_path, args.prompt, int(args.fps), int(args.length))
    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(file_path, args.s3_bucket, os.path.basename(file))
    
if __name__ == "__main__":
    main()    # メイン関数を実行

Dockerイメージのビルド

上記の内容で、Dockerイメージをビルドします。Linux環境などで行います。

コンテナレジストリの用意

Dockerイメージを登録するコンテナレジストリを作成します。さくらのクラウドではLAB機能で、コンテナレジストリを提供しています。さくらのクラウドにログインしたら さくらのクラウド を選択します。

image.png

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

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 の部分は、作成したコンテナレジストリのドメイン名に置き換えてください。

sudo docker build -t EXAMPLE.sakuracr.jp/text2video:latest .

コンテナレジストリへのログイン

作成したコンテナレジストリにログインします。ログインIDとパスワードが求められるので、作成したものを入力してください。

sudo docker login EXAMPLE.sakuracr.jp

イメージのプッシュ

作成したイメージをコンテナレジストリにプッシュします。イメージサイズが大きいので、数十分かかります。

sudo docker push EXAMPLE.sakuracr.jp/text2video:latest

タスクを作成する

後は最初と同じようにDOKでタスクを作成、実行します。

項目 設定
イメージ EXAMPLE.sakuracr.jp/text2video
環境変数 PROMPT=A horse galloping on a street
FPS=4
LENGTH=8

image.png

まとめ

今回はText2Video-Zeroを使って、DOK上で動画を作成する手順を解説しました。まずは実行できるのみ、次にDockerイメージの作成と段階的に進められるようにしています。ぜひ、試してみてください。

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?