すべてのプロダクト
Search
ドキュメントセンター

Function Compute:オーディオおよびビデオ処理のベストプラクティス

最終更新日:Sep 09, 2024

Function Computeコンソール、SDK、またはServerless Devsを使用して、GPU高速化インスタンスのベストプラクティスを体験できます。 このトピックでは、Serverless Devsと関数コードを使用してビデオをトランスコードする方法について説明します。mp4から. flv。 このトピックでは、Pythonを例として使用します。

シナリオと利点

ソーシャルライブストリーミング、オンライン教室、遠隔医療などの高度にインタラクティブなアプリケーションシナリオの出現により、リアルタイムおよび準リアルタイムのインターネットトラフィックがトレンドになりつつあります。 ほとんどの場合、ビデオプラットフォームは、ソースビデオコンテンツをトランスコードして、ビットレート、解像度、チャネルパッチ、および再生プラットフォームなどの要因に基づいて1:N方式で複数の配信ビデオフォーマットを出力し、異なる再生プラットフォーム上の視聴者に異なるネットワーク品質を提供する必要があります。 ビデオのトランスコーディングは、ビデオの制作と配信の重要なステップです。 理想的なビデオコード変換ソリューションは、コスト (RMB /ストリーム) と電力効率 (ワット /ストリーム) の点で費用対効果が高い必要があります。

このセクションでは、Function ComputeにGPUアクセラレーションがないインスタンスと比較した、GPUアクセラレーションインスタンスの利点について説明します。

  • リアルタイムおよび準リアルタイムのアプリケーションシナリオ

    GPU高速化されたインスタンスは、ビデオを数倍高速にトランスコードし、プロダクションコンテンツをより効率的にユーザーにプッシュできます。

  • コスト優先GPUアプリケーションシナリオ

    GPU高速化インスタンスは、ビジネス要件に基づいて柔軟にプロビジョニングでき、自己購入の仮想マシン (VM) よりも費用対効果が高くなります。

  • 効率優先GPUアプリケーションシナリオ

    ドライバーとCUDAのバージョン管理、マシンの運用管理、欠陥のあるGPU管理など、GPUクラスターでO&Mを実行することなく、コード開発とビジネス目標に焦点を当てます。

GPU高速化インスタンスの詳細については、「インスタンスタイプとインスタンスモード」をご参照ください。

性能比較

Function ComputeのGPU高速化インスタンスは、Turingアーキテクチャに基づいており、次のエンコードおよびデコード形式をサポートしています。

  • エンコード形式

    H.264 (AVCHD) YUV 4:2:0

    H.264 (AVCHD) YUV 4:4:4

    H.264 (AVCHD) ロスレス

    H.265 (HEVC) 4K YUV 4:2:0

    H.265 (HEVC) 4K YUV 4:4:4

    H.265 (HEVC) 4Kロスレス

    H.265 (HEVC) 8k

    HEVC10-bitsupport

    HEVCBフレームサポート

  • デコード形式

    MPEG-1

    MPEG-2

    VC-1

    VP8

    VP9

    H.264 (AVCHD)

    H.265 (HEVC) 4:2:0

    * H.265 (HEVC) 4:4:4

    8ビット

    10ビット

    12ビット

    8ビット

    10ビット

    12ビット

    8ビット

    10ビット

    12ビット

次の表に、ソースビデオに関する情報を示します。

項目

有効期間

2分5秒

ビットレート

4085 Kb/s

ビデオストリーム情報

h264 (高) 、yuv420p (プログレッシブ) 、1920x1080 [SAR 1:1 DAR 16:9] 、25 fps、25 tbr、1k tbn、50 tbc

オーディオおよびビデオ情報

aac (LC) 、44100Hz、ステレオ、fltp

次の表に、GPUアクセラレーションを使用するテストマシンとGPUアクセラレーションを使用しないマシンに関する情報を示します。

項目

マシン、GPUアクセラレーションなし

マシンとGPUアクセラレーション

CPU

CPU Xeon®プラチナ8163 4C

CPU Xeon®プラチナ8163 4C

RAM

16 GB

16 GB

GPU

非該当

T4

FFmpeg

git-2020-08-12-1201687

git-2020-08-12-1201687

ビデオトランスコード (1:1)

パフォーマンステスト: 1入力steramと1出力ストリーム

解像度

GPUアクセラレーションなしのトランスコード期間

GPUアクセラレーションによるトランスコード期間

H264 ∶ 1920x1080 (1080p) (フルHD)

3分19.331秒

9.399秒

H264 ∶ 1280x720 (720p) (ハーフHD)

2分3.708秒

5.791秒

H264 ∶ 640x480 (480p)

1分1.018秒

5.753秒

H264 ∶ 480x360 (360p)

44.376秒

5.749秒

ビデオトランスコーディング (1: N)

パフォーマンステスト: 1つの入力ストリームと3つの出力ストリーム

解像度

GPUアクセラレーションなしのトランスコード期間

GPUアクセラレーションによるトランスコード期間

H264 ∶ 1920x1080 (1080p) (フルHD)

5分58.696秒

45.268秒

H264 ∶ 1280x720 (720p) (ハーフHD)

H264 ∶ 640x480 (480p)

コード変換コマンド

  • GPU高速化なしのトランスコードのコマンド

    • シングルストリームのトランスコード (1:1)

      docker run --rm -it --volume $PWD:/workspace --runtime=nvidia willprice/nvidia-ffmpeg -y -i input.mp4 -c:v h264 -vf scale=1920:1080 -b:v 5M output.mp4
    • 複数ストリームのトランスコーディング (1:N)

      docker run --rm -it --volume $PWD:/workspace --runtime=nvidia willprice/nvidia-ffmpeg \
      -y -i input.mp4 \
      -c:a copy -c:v h264 -vf scale=1920:1080 -b:v 5M output_1080.mp4 \
      -c:a copy -c:v h264 -vf scale=1280:720 -b:v 5M output_720.mp4 \
      -c:a copy -c:v h264 -vf scale=640:480 -b:v 5M output_480.mp4

    表 1. パラメーターの説明

    パラメーター

    説明

    -c: コピー

    オーディオストリームは、記録せずにコピーすることができる。

    -c:v h264

    出力ストリーム用のソフトウェアH.264エンコーダを選択します。

    -b:v 5M

    出力ビットレートを5メガバイト/秒に設定します。

  • GPUアクセラレーションによるトランスコードのコマンド

    • シングルストリームのトランスコード (1:1)

      docker run --rm -it --volume $PWD:/workspace --runtime=nvidia willprice/nvidia-ffmpeg -y -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -c:v h264_nvenc -vf scale_cuda=1920:1080:1:4 -b:v 5M output.mp4
    • 複数ストリームのトランスコーディング (1:N)

      docker run --rm -it --volume $PWD:/workspace --runtime=nvidia willprice/nvidia-ffmpeg \
      -y -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 \
      -c:a copy -c:v h264_nvenc -vf scale_npp=1920:1080 -b:v 5M output_1080.mp4 \
      -c:a copy -c:v h264_nvenc -vf scale_npp=1280:720 -b:v 5M output_720.mp4 \
      -c:a copy -c:v h264_nvenc -vf scale_npp=640:480 -b:v 5M output_480.mp4

    表 2. パラメーターの説明

    パラメーター

    説明

    -hwaccel cuda

    適切なハードウェアアクセラレータを選択します。

    -hwaccel_output_format cuda

    デコードされたフレームをGPUメモリに保存します。

    -c:v h264_nvenc

    NVIDIAハードウェアを使用してH.264エンコーダを高速化します。

準備

  • ユーザーエクスペリエンスを最適にするには、DingTalkグループ (ID 11721331) に参加し、次の情報を提供します。

    • 組織名 (会社の名前など) 。

    • Alibaba CloudアカウントのID。

    • GPUアクセラレーションインスタンスを使用するリージョン (中国 (深セン) など) 。

    • 携帯電話番号、メールアドレス、DingTalkアカウントなどの連絡先情報。

  • GPUアクセラレーションインスタンスが存在するリージョンで、次の操作を実行します。

  • FFmpegをコンパイルします。

    GPUアクセラレーションを使用する前に、FFmpegをコンパイルする必要があります。 次の項目は、FFmpegをコンパイルする方法を説明します。

    • (推奨) Dockerからコンパイル済みFFmpegを使用します。 ダウンロードアドレス: nvidia-ffmpegまたはffmpeg

    • FFmpegを手動でコンパイルします。 詳細については、「コンパイルガイド」をご参照ください。

  • 処理するオーディオおよびビデオリソースを、GPUアクセラレーションインスタンスが配置されているリージョンのObject Storage Service (OSS) バケットにアップロードします。 バケット内のオブジェクトに対する読み取りおよび書き込み権限があることを確認してください。 オーディオおよびビデオリソースをアップロードする方法の詳細については、「オブジェクトのアップロード」をご参照ください。 権限の詳細については、「バケットのACLの変更」をご参照ください。

Serverless Devsを使用してGPUアプリケーションをデプロイする

あなたが始める前に

手順

  1. プロジェクトを作成します。

    s init devsapp/start-fc-custom-container-event-python3.9 -d fc-gpu-prj

    次のサンプルコードは、作成されたプロジェクトのディレクトリを示しています。

    fc-gpu-prj
    ├── code
    │   ├── app.py        # Function code.
    │   └── Dockerfile    # Dockerfile: The image Dockerfile that contains the code.
    ├── README.md
    └── s.yaml            # Project configurations, which specify how the image is deployed in Function Compute

    でのイメージのデプロイ方法を指定するプロジェクト設定

  2. プロジェクトディレクトリに移動します。

    cd fc-gpu-prj
  3. ビジネス要件に基づいて、次のファイルのパラメーター設定を変更します。

    • を編集します。Edit thes.yamlファイルを作成します。

      YAMLファイルのパラメーターの詳細については、「YAML仕様」をご参照ください。

      edition: 1.0.0
      name: container-demo
      access: default
      vars:
        region: cn-shenzhen
      services:
        customContainer-demo:
          component: devsapp/fc
          props:
            region: ${vars.region}
            service:
              name: tgpu_ffmpeg_service
              internetAccess: true
            function:
              name: tgpu_ffmpeg_func
              description: test gpu for ffmpeg
              handler: not-used
              timeout: 600
              caPort: 9000
              instanceType: fc.gpu.tesla.1
              gpuMemorySize: 8192
              cpu: 4
              memorySize: 16384
              diskSize: 512
              runtime: custom-container
              customContainerConfig:
                #1. Make sure that the namespace:demo namespace and the repo:gpu-transcoding_s repository are created in advance in Alibaba Cloud Container Registry. 
                #2. Modify the tag from v0.1 to v0.2 when you update the function later and run s build && s deploy again. 
                image: registry.cn-shanghai.aliyuncs.com/demo/gpu-transcoding_s:v0.1
              codeUri: ./code
    • を編集します。Edit theapp.pyファイルを作成します。

      例:

      # -*- coding: utf-8 -*-
      # python2 and python3
      
      from __future__ import print_function
      from http.server import HTTPServer, BaseHTTPRequestHandler
      import json
      import sys
      import logging
      import os
      import time
      import urllib.request
      import subprocess
      
      class Resquest(BaseHTTPRequestHandler):
          def download(self, url, path):
              print("enter download:", url)
              f = urllib.request.urlopen(url)
              with open(path, "wb") as local_file:
                  local_file.write(f.read())
      
          def upload(self, url, path):
              print("enter upload:", url)
              headers = {
                  'Content-Type': 'application/octet-stream',
                  'Content-Length': os.stat(path).st_size,
              }
              req = urllib.request.Request(url, open(path, 'rb'), headers=headers, method='PUT')
              urllib.request.urlopen(req)
      
          def trans(self, input_path, output_path, enable_gpu):
              print("enter trans input:", input_path, " output:", output_path, " enable_gpu:", enable_gpu)
      
              cmd = ['ffmpeg', '-y', '-i', input_path, "-c:a", "copy", "-c:v", "h264", "-b:v", "5M", output_path]
              if enable_gpu:
                  cmd = ["ffmpeg", "-y", "-hwaccel", "cuda", "-hwaccel_output_format", "cuda", "-i", input_path, "-c:v", "h264_nvenc", "-b:v", "5M", output_path]
      
              try:
                  subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
              except subprocess.CalledProcessError as exc:
                  print('\nreturncode:{}'.format(exc.returncode))
                  print('\ncmd:{}'.format(exc.cmd))
                  print('\noutput:{}'.format(exc.output))
                  print('\nstderr:{}'.format(exc.stderr))
                  print('\nstdout:{}'.format(exc.stdout))
      
          def trans_wrapper(self, enable_gpu):
              src_url = "https://your.domain/input.mp4"  # Use the path of the OSS object under your Alibaba Cloud account. You must have the read and write permissions on the object. 
              dst_url = "https://your.domain/output.flv" # Use the path of the OSS object under your Alibaba Cloud account. You must have the read and write permissions on the object. 
              src_path = "/tmp/input_c.flv"
              dst_path = "/tmp/output_c.mp4"
      
              if enable_gpu:
                  src_url = "https://your.domain/input.mp4"  # Use the path of the OSS object under your Alibaba Cloud account. You must have the read and write permissions on the object. 
                  dst_url = "https://your.domain/output.flv" # Use the path of the OSS object under your Alibaba Cloud account. You must have the read and write permissions on the object. 
                  src_path = "/tmp/input_g.flv"
                  dst_path = "/tmp/output_g.mp4"
      
              local_time = time.time()
              self.download(src_url, src_path)
              download_time = time.time() - local_time
      
              local_time = time.time()
              self.trans(src_path, dst_path, enable_gpu)
              trans_time = time.time() - local_time
      
              local_time = time.time()
              self.upload(dst_url, dst_path)
              upload_time = time.time() - local_time
      
              data = {'result':'ok', 'download_time':download_time, 'trans_time':trans_time, 'upload_time':upload_time}
              self.send_response(200)
              self.send_header('Content-type', 'application/json')
              self.end_headers()
              self.wfile.write(json.dumps(data).encode())
      
          def pong(self):
              data = {"function":"trans_gpu"}
              self.send_response(200)
              self.send_header('Content-type', 'application/json')
              self.end_headers()
              self.wfile.write(json.dumps(data).encode())
      
          def dispatch(self):
              mode = self.headers.get('TRANS-MODE')
      
              if mode == "ping":
                  self.pong()
              elif mode == "gpu":
                  self.trans_wrapper(True)
              elif mode == "cpu":
                  self.trans_wrapper(False)
              else:
                  self.pong()
      
          def do_GET(self):
              self.dispatch()
      
          def do_POST(self):
              self.dispatch()
      
      if __name__ == '__main__':
          host = ('0.0.0.0', 9000)
          server = HTTPServer(host, Resquest)
          print("Starting server, listen at: %s:%s" % host)
          server.serve_forever()
    • Dockerfileファイルを編集します。

      例:

      FROM registry.cn-shanghai.aliyuncs.com/serverless_devs/nvidia-ffmpeg:latest
      WORKDIR /usr/src/app
      RUN apt-get update --fix-missing
      RUN apt-get install -y python3
      RUN apt-get install -y python3-pip
      COPY . .
      ENTRYPOINT [ "python3", "-u", "/usr/src/app/app.py" ]
      EXPOSE 9000
  4. イメージを作成します。

    s build --dockerfile ./code/Dockerfile
  5. コードをFunction Computeにデプロイします。

    s deploy
    説明

    上記のコマンドを繰り返し実行し、サービス名と関数名を変更しない場合は、use localコマンドを実行してローカル設定を使用します。

  6. プロビジョニング済みインスタンスの設定

    s provision put --target 1 --qualifier LATEST
  7. プロビジョニング済みインスタンスの準備ができているかどうかを確認します。

    s provision get --qualifier LATEST

    currentの値が1の場合、GPUアクセラレーションインスタンスのプロビジョニングモードは準備完了です。 例:

    [2021-12-14 08:45:24] [INFO] [S-CLI] - Start ...
    [2021-12-14 08:45:24] [INFO] [FC] - Getting provision: tgpu_ffmpeg_service.LATEST/tgpu_ffmpeg_func
    customContainer-demo:
     serviceName:      tgpu_ffmpeg_service
     functionName:      tgpu_ffmpeg_func
     qualifier:       LATEST
     resource:        188077086902****#tgpu_ffmpeg_service#LATEST#tgpu_ffmpeg_func
     target:         1
     current:        1
     scheduledActions:    (empty array)
     targetTrackingPolicies: (empty array)
     currentError:     
  8. 関数を呼び出します。

    • オンライン機能のバージョンを表示する

      s invoke
    • トランスコードにCPUを使用する

      s invoke -e '{"method":"GET","headers":{"TRANS-MODE":"cpu"}}'
    • GPUを使用したトランスコード

      s invoke -e '{"method":"GET","headers":{"TRANS-MODE":"gpu"}}'
  9. GPU高速化インスタンスをリリースします。

    s provision put --target 0 --qualifier LATEST

Function Computeコンソールを使用してGPUアプリケーションをデプロイする

  1. イメージを展開します。

    1. Container Registry Enterprise EditionインスタンスまたはContainer Registry Personal Editionインスタンスを作成します。

      Enterprise Editionインスタンスを作成することを推奨します。 詳細については、「Container Registry Enterprise Editionインスタンスの作成」をご参照ください。

    2. 名前空間とイメージリポジトリを作成します。

      詳細については、「Container Registry Enterprise Editionインスタンスを使用してイメージを構築する」トピックの「手順2: 名前空間の作成」および手順3: イメージリポジトリの作成」をご参照ください。

    3. Container Registryコンソールのプロンプトに従って、Dockerで操作を実行します。 次に、前述のサンプルapp.pyDockerfileをインスタンスイメージリポジトリにプッシュします。 ファイルの詳細については、Serverless Devsを使用してGPUアプリケーションをデプロイする場合、/codeディレクトリのapp.pyおよびDockerfileをご参照ください。

      db-acr-docker

  2. サービスを作成します。 詳細については、「サービスの管理」セクションの「サービスの作成」セクションをご参照ください。

  3. 関数を作成します。 詳細については、「カスタムコンテナー関数の作成」をご参照ください。

    説明

    [インスタンスタイプ][GPUインスタンス][リクエストハンドラタイプ][HTTPリクエストの処理] を選択します。

  4. 関数の実行タイムアウト時間を変更します。

    1. 管理する機能を見つけて、[操作] 列の [設定] をクリックします。

    2. [環境情報] セクションで、[実行タイムアウト期間] の値を変更し、[保存] をクリックします。

      db-gpu-time

    説明

    CPUを使用したトランスコード時間は、デフォルト値の60秒を超えています。 したがって、[実行タイムアウト期間] の値をより大きな値に設定することを推奨します。

  5. プロビジョニングされたGPU高速化インスタンスを設定します。

    1. [機能の詳細] ページで、[自動スケーリング] タブをクリックし、[ルールの作成] をクリックします。

    2. 表示されるページで、次のパラメーターを設定してGPUアクセラレーションインスタンスをプロビジョニングし、[作成] をクリックします。

      プロビジョニング済みインスタンスの設定方法の詳細については、「自動スケーリングルールの設定」をご参照ください。 db-gpu-reserved

      設定が完了したら、プロビジョニングされたGPUアクセラレーションインスタンスの準備ができているかどうかをルールリストで確認できます。 具体的には、Current Reserved Instancesの値が指定されたプロビジョニング済みインスタンスの数であるかどうかを確認します。

  6. cURLを使用して関数をテスト

    1. 関数の詳細ページで、[トリガー] タブをクリックしてトリガーの設定を表示し、トリガーのエンドポイントを取得します。

    2. コマンドラインインターフェイス (CLI) で次のコマンドを実行して、GPU関数を呼び出します。

      • オンライン機能のバージョンを表示する

        curl -v "https://tgpu-ff-console-tgpu-ff-console-ajezot****.cn-shenzhen.fcapp.run"
        {"function": "trans_gpu"}
      • トランスコードにCPUを使用する

        curl "https://tgpu-ff-console-tgpu-ff-console-ajezot****.cn-shenzhen.fcapp.run" -H 'TRANS-MODE: cpu'
        {"result": "ok", "upload_time": 8.75510573387146, "download_time": 4.910430669784546, "trans_time": 105.37688875198364}
      • GPUを使用したトランスコード

        curl "https://tgpu-ff-console-tgpu-ff-console-ajezotchpx.cn-shenzhen.fcapp.run" -H 'TRANS-MODE: gpu'
        {"result": "ok", "upload_time": 8.313958644866943, "download_time": 5.096682548522949, "trans_time": 8.72346019744873}

結果

ブラウザで次のドメイン名にアクセスすると、トランスコード後にビデオを表示できます。

https://cri-zbtsehbrr8******-registry.oss-cn-shenzhen.aliyuncs.com/output.flv

このドメイン名は例として使用されます。 実際のドメイン名が優先されます。