Function Computeコンソール、SDK、またはServerless Devsを使用して、GPU高速化インスタンスのベストプラクティスを体験できます。 このトピックでは、Serverless DevsまたはFunction Computeコンソールを使用して、関数コードを使用してエッジ検出を実行してrawイメージを処理する方法について説明します。 このトピックでは、Pythonを例として使用します。
シナリオと利点
このセクションでは、Function ComputeにGPUアクセラレーションがないインスタンスと比較した、GPUアクセラレーションインスタンスの利点について説明します。
リアルタイムおよび準リアルタイムのアプリケーションシナリオ
GPU高速化されたインスタンスは、グラフィックスとイメージを数倍高速に処理し、より効率的な方法でプロダクションコンテンツをユーザーにプッシュできます。
コスト優先の画像処理シナリオ
ビジネス要件に基づいてGPU高速化インスタンスを予約します。 このように、Function ComputeのGPU高速化インスタンスは、自作GPUクラスターよりもはるかに高いコスト効率を提供します。
GPU仮想化テクノロジを使用して、1/2モードまたは排他モードでGPUリソースを使用します。 このようにして、GPU高速化インスタンスをきめ細かく構成できます。
効率優先の画像処理シナリオ
ドライバーとCUDAのバージョン管理、マシンの運用管理、欠陥のあるGPU管理など、GPUクラスターでO&Mを実行することなく、コード開発とビジネス目標に焦点を当てます。
GPU高速化インスタンスの詳細については、「インスタンスタイプとインスタンスモード」をご参照ください。
チュートリアルの説明
次の表は、Function Computeでソースイメージ (左) でエッジ検出を実行して新しいイメージ (右) を生成する例を示しています。
ソースイメージ | 新しい画像エッジ検出 |
準備
OpenCVをコンパイルします。
OpenCVは、GPUアクセラレーションを使用する前にコンパイルする必要があります。 次の項目では、OpenCVのコンパイル方法について説明します。
(推奨) Dockerを使用してコンパイル済みOpenCVを使用する。 ダウンロードアドレス: opencv-cuda-dockerまたはcuda-opencv。
OpenCVを手動でコンパイルします。 詳細については、「コンパイルガイド」をご参照ください。
処理するオーディオおよびビデオリソースを、GPUアクセラレーションインスタンスが配置されているリージョンのObject Storage Service (OSS) バケットにアップロードします。 バケット内のオブジェクトに対する読み取りおよび書き込み権限があることを確認してください。 オーディオおよびビデオリソースをアップロードする方法の詳細については、「オブジェクトのアップロード」をご参照ください。 権限の詳細については、「バケットのACLの変更」をご参照ください。
Serverless Devsを使用してGPUアプリケーションをデプロイする
あなたが始める前に
GPUアクセラレーションインスタンスが存在するリージョンで、次の操作を実行します。
Container Registry Enterprise EditionインスタンスまたはPersonal Editionインスタンスを作成します。 Enterprise Editionインスタンスを作成することを推奨します。 詳細については、「手順1: Container Registry Enterprise Editionインスタンスの作成」をご参照ください。
名前空間とイメージリポジトリを作成します。 詳細については、「手順2: 名前空間の作成」および「手順3: イメージリポジトリの作成」をご参照ください。
手順
プロジェクトを作成します。
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
でのイメージのデプロイ方法を指定するプロジェクト設定
プロジェクトディレクトリに移動します。
cd fc-gpu-prj
ビジネス要件に基づいてディレクトリファイルの設定を変更します。
s.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_opencv_service internetAccess: true function: name: tgpu_opencv_func description: test gpu for opencv 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-opencv-canny_s repository are created in advance in Alibaba Cloud Container Registry. #2. Change the tag from v0.1 to v0.2 when you update the function later and run s build && s deploy again. image: registry.cn-shenzhen.aliyuncs.com/demo/gpu-opencv-canny_s:v0.1 codeUri: ./code triggers: - name: httpTrigger type: http config: authType: anonymous methods: - GET
app.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 numpy as np import cv2 import urllib.request class MyRequest(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 core(self): msg = "" mode = "" if not cv2.cuda.getCudaEnabledDeviceCount(): msg = "No CUDA-capable device is detected |" mode = "Mat" else: msg = "CUDA-capable device supported |" mode = "UMat" # Use the path of the OSS object in your Alibaba Cloud account. You must have the read and write permissions on the object. # Download the source image from your OSS bucket. path = "/tmp/target.jpg" self.download("https://your_public_oss/f.png", path) img = cv2.imread(path) if mode=='UMat': img = cv2.UMat(img) img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img = cv2.GaussianBlur(img, (7, 7), 1.5) img = cv2.Canny(img, 0, 50) if type(img) == 'cv2.UMat': img = cv2.UMat.get(img) cv2.imwrite(path, img) # Use the path of the OSS object in your Alibaba Cloud account. You must have the read and write permissions on the object. # Upload the new image after edge detection to the OSS bucket. Note that the name of the new image cannot be the same as the name of the source image. self.upload("https://your_public_oss/target.jpg", path) msg = msg + " process image ok!" data = {'result': msg} 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":"opencv_edge_canny"} 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('RUN-MODE') if mode == "ping": self.pong() elif mode == "normal": self.core() 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, MyRequest) print("Starting server, listen at: %s:%s" % host) server.serve_forever()
Dockerfileファイルを編集します。
例:
FROM registry.cn-shanghai.aliyuncs.com/serverless_devs/opencv-cuda:cuda-10.2-opencv-4.2 WORKDIR /usr/src/app RUN apt-get install -y build-essential RUN apt-get install -y python3 COPY . . CMD [ "python3", "-u", "/usr/src/app/app.py" ] EXPOSE 9000
イメージを作成します。
s build --dockerfile ./code/Dockerfile
コードをFunction Computeにデプロイします。
s deploy
説明上記のコマンドを繰り返し実行し、サービス名と関数名を変更しない場合は、
use local
コマンドを実行してローカル設定を使用します。プロビジョニング済みインスタンスの設定
s provision put --target 1 --qualifier LATEST
プロビジョニング済みインスタンスの準備ができているかどうかを確認します。
s provision get --qualifier LATEST
current
の値が1の場合、GPUアクセラレーションインスタンスのプロビジョニングモードは準備完了です。 例:[2021-11-01T13:43:28.308] [INFO ] [S-CLI] - Start ... [2021-11-01T13:43:28.521] [INFO ] [FC] - Getting provision: tgpu_opencv_service.LATEST/tgpu_opencv_func customContainer-demo: serviceName: tgpu_opencv_service functionName: tgpu_opencv_func qualifier: LATEST resource: 188077086902****#tgpu_opencv_service#LATEST#tgpu_opencv_func target: 1 current: 1 scheduledActions: [] targetTrackingPolicies: []
関数を呼び出します。
オンライン版を見る
FC Invoke Result: {"function": "opencv_edge_canny"}
画像のエッジ検出を実行する
s invoke -e '{"method":"GET","headers":{"RUN-MODE":"normal"}}' enter download: https://your_public_oss/c1.png enter upload: https://your_public_oss/target.jpg # View the file to check the result of edge detection. FC Invoke Result: {"result": "CUDA-capable device supported | process image ok!"}
GPU高速化インスタンスをリリースします。
s provision put --target 0 --qualifier LATEST
Function Computeコンソールを使用してGPUアプリケーションをデプロイする
イメージを展開します。
Container Registry Enterprise EditionインスタンスまたはContainer Registry Personal Editionインスタンスを作成します。
Enterprise Editionインスタンスを作成することを推奨します。 詳細については、「Container Registry Enterprise Editionインスタンスの作成」をご参照ください。
名前空間とイメージリポジトリを作成します。
詳細については、「Container Registry Enterprise Editionインスタンスを使用してイメージを構築する」トピックの「手順2: 名前空間の作成」および手順3: イメージリポジトリの作成」をご参照ください。
Container Registryコンソールのプロンプトに従って、Dockerで操作を実行します。 次に、前述のサンプルapp.pyとDockerfileをインスタンスイメージリポジトリにプッシュします。 ファイルの詳細については、Serverless Devsを使用してGPUアプリケーションをデプロイする場合、/codeディレクトリのapp.pyおよびDockerfileをご参照ください。
サービスを作成します。 詳細については、「サービスの管理」セクションの「サービスの作成」セクションをご参照ください。
関数を作成します。 詳細については、「カスタムコンテナー関数の作成」をご参照ください。
説明[インスタンスタイプ] に [GPUインスタンス] 、[リクエストハンドラタイプ] に [HTTPリクエストの処理] を選択します。
関数の実行タイムアウト時間を変更します。
管理する機能を見つけてクリックします設定で、アクション列を作成します。
では、環境変数セクションの値を変更します。実行タイムアウト期間をクリックし、保存をクリックします。
説明CPUを使用したトランスコード時間は、デフォルト値の60秒を超えています。 したがって、[実行タイムアウト期間] の値をより大きな値に設定することを推奨します。
プロビジョニングされたGPU高速化インスタンスを設定します。
関数の詳細ページで、自動スケーリングタブをクリックし、ルールの作成をクリックします。
表示されるページで、次のパラメーターを設定してGPUアクセラレーションインスタンスをプロビジョニングし、作成をクリックします。
プロビジョニング済みインスタンスの設定方法の詳細については、「プロビジョニング済みインスタンスと自動スケーリングルールの設定」をご参照ください。
設定が完了したら、プロビジョニングされたGPUアクセラレーションインスタンスの準備ができているかどうかをルールリストで確認できます。 具体的には、Current Reserved Instancesの値が指定されたプロビジョニング済みインスタンスの数であるかどうかを確認します。
cURLを使用して関数をテストします。
関数の詳細ページで、トリガータブでトリガー設定を表示し、トリガーエンドポイントを取得します。
CLIで次のコマンドを実行して、GPUアクセラレーション機能を呼び出します。
オンライン機能バージョンの表示
curl "https://tgpu-op-console-tgpu-op-console-ajezokddpx.cn-shenzhen.fcapp.run" {"function": "opencv_edge_canny"}
画像のエッジ検出を実行する
curl "https://tgpu-op-console-tgpu-op-console-ajezokddpx.cn-shenzhen.fcapp.run" -H "RUN-MODE: normal" {"result": "CUDA-capable device supported | process image ok!"}
実行結果
ブラウザで次のドメイン名にアクセスすることで、エッジ検出後に画像を表示できます。
https://cri-zfen7xhpsx******-registry.oss-cn-shenzhen.aliyuncs.com/cats2.png
このドメイン名は例として使用されます。 実際のドメイン名が優先されます。