Azure で Unreal Pixel Streaming を動かしてみる

# はじめに

クラウドゲーミング（リモートレンダリングと言ったり）のメリットは『**プラットフォームによる違いをなくす**』です。
ある端末ではスペックが足りないので『動作しない』『映像の品質が悪い』などの差を埋めるためのものです。
特に UE で作成されたアプリケーションはかなり高いスペックを要求しますので、必ずその要求を満たせる環境をサーバー側で用意・実行し、レンダリング結果だけをクライアントに返すだけですので、開発側としても下手にスペックを意識する必要がなくなる（正常動作する環境を自ら用意することができる）ので便利かと思います。

デメリットとしては『ネットワーク環境がないと動作しない』というものがあります。
当たり前なのですが、サーバー側でレンダリングを行いますので、ネットワーク環境がないとレンダリング結果を受け取る事が出来ません。
また、サーバーを設置する必要がありますのでクラウドサーバーであればその分費用がかかります。それだけ高いスペックを要求するということはサーバー費用にも跳ね返りますので注意が必要です。費用については[費用](#費用)で説明します。

## Unreal Pixel Streaming

Unreal Pixel Streaming は Azure Portal のマーケットプレイスで『Unreal Pixel Streaming』から作成を行ないます。
事前にリソースグループを作成しておく必要がありますが『PixelStreaming』などでもよいかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/3f2d88b1-db01-a657-24a8-c7bfca442f80.png)

### 基本

ここからはタグの設定毎に説明していきます。

#### リージョン

Pixel Streaming は VM 以外に以下のリソースを作成しますので、これらが配置されるリージョンを指定します。

- Application Insights
- App Service
- App Service プラン
- Log Analytics
- Traffic Manager
- ストレージ
- キーコンテナー

#### UE4 App GPU VM Size

基本の設定項目でややこしいのは使用する VM の選択です。
Pixel Streaming を動作させるためには GPU 搭載の VM を選択する必要があります。
GPU を搭載している VM は[GPU 最適化済み仮想マシンのサイズ](https://learn.microsoft.com/ja-jp/azure/virtual-machines/sizes-gpu)で記載されている通り、以下の種類があります。

|シリーズ|搭載GPU|説明と用途など|
|---|---|---|
|[NCv3](https://learn.microsoft.com/ja-jp/azure/virtual-machines/ncv3-series)|[NVIDIA V100](https://www.nvidia.com/ja-jp/data-center/v100/)|高性能計算と AI のワークロード|
|[NCasT4_v3](https://learn.microsoft.com/ja-jp/azure/virtual-machines/nct4-v3-series)|[NVIDIA T4](https://www.nvidia.com/en-us/data-center/tesla-t4/)|コンピューティング集中型 GPU 高速化アプリケーション用に最適化されています。 例としては、CUDA および OpenCL ベースのアプリケーションやシミュレーション、AI、ディープ ラーニングなど|
|[ND A100 v4](https://learn.microsoft.com/ja-jp/azure/virtual-machines/nda100-v4-series)|[NVIDIA Ampere A100 40GB Tensor](https://www.nvidia.com/ja-jp/data-center/a100/)|スケールアップとスケールアウトによるディープ ラーニング トレーニングと高速 HPC アプリケーション|
|[NVv3](https://learn.microsoft.com/ja-jp/azure/virtual-machines/nvv3-series)|[NVIDIA Tesla M60](https://images.nvidia.com/content/tesla/pdf/188417-Tesla-M60-DS-A4-fnl-Web.pdf)|リモートの視覚化、ストリーミング、ゲーム、エンコーディング、および OpenGL や DirectX などのフレームワークを使用する VDI シナリオ用に最適化|
|[NDm A100 v4](https://learn.microsoft.com/ja-jp/azure/virtual-machines/ndm-a100-v4-series)|[NVIDIA Ampere A100 80GB Tensor](https://www.nvidia.com/ja-jp/data-center/a100/)|ハイエンドのディープ ラーニング トレーニングと密結合のスケールアップおよびスケールアウトの HPC ワークロード向け|
|[NVadsA10 v5](https://learn.microsoft.com/ja-jp/azure/virtual-machines/nva10v5-series)|[NVIDIA A10](https://www.nvidia.com/en-us/data-center/products/a10-gpu/)|新しく追加されたシリーズです。|

GPU 搭載を搭載した VM としては複数種類ありますが、今回の Unreal Pixel Streaming に使えそうなスペックとしては『NCasT4_v3』シリーズか『NVv3』シリーズの選択になると思います（それ以外のシリーズはディープラーニングや AI などゲーム以外の分野で活躍しそうなスペックです）

デフォルトでは『NV12s v3』が選択されていると思いますが、今回はスペック比較した上で『NCasT4_v3』シリーズにしたいと思います。
※M60 と T4 の比較は以下のサイトで参照してください。

https://technical.city/ja/video/Tesla-M60-vs-Tesla-T4

ただし、NCasT4_v3 もそのまま使えるとは限りません。
理由は GPU 搭載 VM が一般的な VM に比べて使用可能な数が少ないため、選択時にはクォータ増要求を出す必要があります。
私の環境でも T4 は国内のリージョンではデフォルトでは使えなかったためクォータ増要求を出しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/03bdee61-6071-7886-144f-80150b3b5608.png)

#### Matchmaker VM Size

Matchmaker とはクライアントと UE4 アプリとの接続管理用のサーバーです。
Matchmaker を配置することでユーザーごとに異なったゲーム画面を表示する事が可能です。
この VM はデフォルトのままの『F4s v2』利用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/300de2d7-5f5d-b564-20ca-5afa73f74569.png)

接続したユーザーが全員同じ画面を見るということであれば、Matchmaker を立ち上げる必要はありません。

https://docs.unrealengine.com/4.27/en-US/ProductionPipelines/CloudDeployments/AzurePixelStreaming/#packagingapixelstreamingapplication

#### Pixel Streaming Package File Upload (.zip)

この項目には UE プロジェクトをエクスポートしたパッケージ **WindowsNoEditor** を ZIP で圧縮し BLOB ストレージにアップロードしたバイナリを指定します（今回は Pixel Streaming 用のパッケージの出力の手順は割愛します）

ちょっとややこしいのですが、簡単に言うと BLOB ストレージに配置されている ZIP ファイルを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/ccc64be0-5b0b-d060-c731-17295d2f18d1.png)

参照を選択することで BLOB ストレージに配置されているファイルを選択する画面が開きます。
この時点で BLOB ストレージが存在しない場合は、新規に作成して BLOB ストレージに ZIP ファイルをアップロードすることも可能です。

また、このストレージですが Pixel Streaming の**リソースを作成する時だけに必要**になります。
後述する[バイナリのアップデート](#バイナリのアップデート)の際に利用するストレージは Pixel Streaming 側で用意したストレージを利用しますので、リソースが作成できればストレージ自体は削除してもらっても大丈夫です。

ストレージが存在しない場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/39fbcc06-f1c0-cf0d-4819-0a09523a58f4.png)

ストレージの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/0f5c5919-d35e-7a26-5bd1-0389d0c2a464.png)

#### UE4 App name

これには ZIP 圧縮した際のアプリケーション名から拡張子を除いた名前を指定します。
`WindowsNoEditor/Test.exe` の場合、この項目には `Test` と入力します。
ここで少し注意が必要なのですが ZIP ファイルを作成する際には `WindowsNoEditor/<exe name>.exe` 以下の構造になっている必要があります。圧縮時の設定によっては `WindowsNoEditor` のディレクトリが省略されてしまっている場合がありますのでディレクトリ構成には注意してください。

### Scale

今回の設定は以下のようにしました。

|項目|設定値|
|---|---|
|Select regions to deploy|Japan East|
|GPU VM Instances Per Region|3|
|Streams Per GPU VM|1|
|Auto-scaling|Enable|
|Percent Buffer Required Before Scale|0%|
|Instance Count Buffer Required Before Scale|1|
|Idle Minutes Before Scale-Down|60|
|Scale Down Amount|4|
|Min Instance Count While Idle|1|
|Max Node Scale Count|10|

以下に各項目の説明を記載します。

#### Select regions to deploy

アプリケーションや Matchmaker などが配置されるリージョンを複数指定します。
複数選択可能とすることで全世界向けの配信でも接続してきたユーザーから近いサーバーを利用すること可能です。
※リージョンは Azure の Traffic Manager が行います。

#### GPU VM Instances Per Region

リージョン単位の VM 数を設定します。
リソースが作成されれば、この項目に指定した数の VM が起動します。
ただし、この値はオートスケール（詳細は後述する[Auto-scaling](#auto-scaling)を参照）を使用する場合はあくまで初期の設定であって負荷状況などによって変化します。

#### Streams Per GPU VM

VM 単位で実行する希望するストリーム数を設定します。
希望するストリーム数になるように解像度や FPS を下げる必要があります。
1 を指定すると VM 一台につき 1 つのアプリが実行できます。

※Azure Pixel Streaming ではアプリケーションの実行単位を『ストリーム』と呼びます。

#### Auto-scaling

Azure Pixel Streaming では VM のオートスケールに対応しています。
オートスケールを有効にすることで負荷が上がるとスケールアウトし、負荷が下がるとスケールダウンさせることができます。

負荷が上がってきた場合（接続要求数が増えた）に VM に空きがないと自動でスケールアウトするのですが、VM の起動にアプリにもよりますが最低でも 5 分程度かかりますので、設定で事前に余裕を持たせるということも可能です。

オートスケールを有効にする場合はこの項目を `Enable` に設定します。
この項目で `Disable` を選択した場合は `GPU VM Instances Per Region` の設定は固定となります。
`Enable` を選択する場合は以下の項目を設定する必要があります。

- [Percent Buffer Required Before Scale](percent-buffer-required-before-scale)
- [Instance Count Buffer Required Before Scale](#instance-count-buffer-required-before-scale)
- [Idle Minutes Before Scale-Down](#idle-minutes-before-scale-down)
- [Scale Down Amount](#scale-down-amount)
- [Min Instance Count While Idle](#min-instance-count-while-idle)
- [Max Node Scale Count](#max-node-scale-count)

#### Percent Buffer Required Before Scale

利用可能なストリームの割合を設定します。
利用可能とは Pixel Streaming に接続されていない待機中のストリームのことで、

```
GPU VM Instances Per Region * Streams Per GPU VM * Percent Buffer Required Before Scale
```

で算出可能です。
例えば以下のようになります。

- VM 数: 3
- ストリーム数: 1
- 割合: 25%

上記の場合であれば最低でも 1 台の VM の空きがないとスケールアウトします。
また 0% に設定することバッファがなくなりますので、余裕がなくなったとしてもその都度スケールアウトする動作が行われることになります。

#### Instance Count Buffer Required Before Scale

利用可能なストリーム数を設定します。
この設定は [Percent Buffer Required Before Scale](#percent-buffer-required-before-scale) とかぶる部分がありますが、こちらは割合ではなくストリーム数となりますので注意してください。
[Percent Buffer Required Before Scale](#percent-buffer-required-before-scale) 同様に 0 に設定することでこの設定は無視されます。

#### Idle Minutes Before Scale-Down

この設定値に設定された時間の間、スケールアウトが発生しなかった場合にスケールダウンの評価を行います。
例えば 60 を指定した場合、1 時間の間にスケールアウトしなかった場合にスケールダウン出来るか評価を行い、スケールダウン出来る状態であればスケールダウンを実行します。

#### Scale Down Amount

スケールダウンする際に同時に落とす台数を指定します。
1 を指定した場合、同時にスケールダウンは 1 台ずつ行われます。

#### Min Instance Count While Idle

アイドル時間帯（夜間などのアクティビティが低い時間帯）にスケールダウンする最小限の数。

#### Max Node Scale Count

スケールアウトされる VM の最大数を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/0077fc2a-7fe0-bbdf-57a3-b04c4ce82264.png)

この値は

### Stream Configs

|設定名|設定値|
|---|---|
|UE4 App resolution width|1920|
|UE4 App resolution height|1080|
|Frames Per Second|60|

この辺りはほぼ説明は不要かと思いますが、解像度や FPS は低いほどリソースが少なくなり、より多くのストリームをパックする事が可能です。

### Security

この項目ではドメインや HTTPS などの設定を行ないますが、今回はデフォルトの `Disable` のままにしておきます。
商用利用には必ず必要な項目ですが Pixel Streaming とは直接的に関係ありませんので、今回は割愛します。

### Networking

ネットワークの設定です。
この項目も今回はデフォルトのまま利用します。

#### STUN/TURN

ただし、この設定で注意が必要な項目として STUN/TURN です。
デフォルトの WebRTC プロトコル経由ではクライアントが正常に接続できない場合があります。
これはモバイルの場合に特に当てはまるのですが、IP アドレスが固定ではないため中継ポイントが切り替わるなどで切断されてしまう可能性があります。
とは言え、この項目も説明するとかなり大掛かりになりますので今回は割愛します。

### Admin Dashboard

この項目では Pixel Streaming に関する管理が行えるページを有効にするか設定が出来ます。

ダッシュボードで出来ることは以下のようなものがあります。

- 接続数や待機中 VM 数などの確認
- [バイナリのアップデート](#バイナリのアップデート)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/6c7695ae-af30-e761-4058-c3a1296c7a6e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/7ad7ec71-eaa9-b9e0-cc16-a4e1594ee7c7.png)

#### Enable the Admin Dashboard

`Enable` を選択することで管理ダッシュボードが有効になります。

#### Azure AD Application Client ID

この項目はセキュアな環境を構築するために Azure のアプリ登録を行う必要があります。
まず最初に Azure Active Directory にアプリ登録が必要です。
上部の検索欄に『Azure Active Directory』と入力すると表示される『Azure Acitve Directory』を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/19c3f642-08db-b21e-502e-780a45f55bfb.png)

左のサイドバーにある『アプリ登録』を選択すると登録されているアプリ一覧が表示されます。
最初は何も表示されていないと思いますが。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/5ee93a42-1a6a-18eb-ef01-1519c88304ac.png)

上部にある『新規作成』を選択するとアプリ登録画面が表示されますので、ここでは名前に『PixelStreaming』と設定し、サポートされているアカウントの種類は『この組織ディレクトリのみに含まれるアカウント』を選択します。リダイレクト URI には後ほど設定しますのでそのままで構いません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/e6c37872-f918-4af3-03e4-f94de47c9e09.png)

登録を行うことでアプリ画面に遷移します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/73abd760-d218-eaee-135d-28d7f7aa5027.png)

ここで重要なのが『基本』の項目にある『アプリケーション(クライアント)ID』です（見切れていますが…）
この値をコピーして先程の『Azure AD Application Client ID』に指定します。

### Tags

ここは特に何もしなくても大丈夫です。

### 確認および作成

これまでの設定が一覧に表示され検証が成功すれば上部に『検証に成功しました』と表示されるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/185c4527-ef09-c3ce-4edd-fefa7ba1b81b.png)

デプロイ中…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/ede28a4e-0e84-7519-c0f5-9ce35c7d6186.png)

デプロイが完了したらまずは起動確認をします。

#### Pixel Streaming VM の起動確認

リソースグループ一覧ページに飛ぶと事前に作成済みの『PixelStreaming』というリソースグループとは別に『?????-japanease-unreal-rg』というリソースグループが作成されていると思います。これはデプロイ時に自動的に作成されるリソースグループで VM や Matchmaker などはこちらに格納されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/e53b17d5-2e69-745c-315a-2ee7216eb661.png)

この中に『?????-mm-vm-japanease』という VM があると思いますが、これが Matchmaker の VM となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/9cdc2e4c-fc03-6cb8-668c-3e6b581f2fb8.png)

Matchmaker VM の中にある DNS 名が外部から見える URL となりますので、この URL をブラウザで開きます。
セキュリティ設定をしておりませんので、この画像であれば『`http://japaneast-akmfw-mm.japanease.cloudapp.azure.com`』となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/48cbf79c-9f84-6b91-0195-e1fa8c0d0c71.png)

上記のような画面が表示されれば Pixel Streaming は正常起動しています。

ただこの成功画面が出ない場合があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/fa069c5c-8991-41d9-f3e4-6ed899145ff9.png)

このような画面です。

これはデプロイが成功しても正常に起動していない場合です。
通常、この画面は接続先の VM がない場合に出るエラー画面なのですが、デプロイ直後に出る場合があります。
私の環境では成功率は 40% 程度で 60% 程度は接続が出来ず以下の画像のような状態でした（成功率が異様に低い…）
この場合は作成した＆作成されたリソースグループ 2 つを削除して最初からやり直しです。

### Traffic Manager を経由した接続

先程の URL は Matchmaker の URL ですが、クライアントからアクセスする URL ではありません。
実際にはアクセスするのは Matchmaker に直接ではなく Traffic Manager というサーバーを経由して接続を行います。

https://learn.microsoft.com/ja-jp/azure/traffic-manager/traffic-manager-overview

Traffic Manager は接続元の IP アドレスから一番近いサーバーを選択してくれる機能を持っています（それ以外の機能もありますが割愛します）ので、それを経由して接続するほうが効率が良くなります。もちろん、日本国内のみということであれば Traffic Manager を経由しなくても Matchmaker に直接繋ぐことも可能です。

Traffic Manager は最初に作成した『PixelStreaming』というリソースグループに配置されており、『?????-trafficmgr-mm』という名前になっているはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/f9ae80b7-21e4-181a-266a-7d7447515575.png)

Traffic Manager を開くと DNS 名の項目があると思いますが、こちらが実際にアクセスする URL となります。
この URL をブラウザで開くと先程と同じ画面が表示されるはずです。

## バイナリのアップデート

これはこの記事内で書こうかと思っていましたが結構なボリュームになったので別の記事したいと思います。

## 費用

Azure で Pixel Streaming を実行するのにやはり気になるのは費用だと思います。
特に Azure は為替の影響を受けます（執筆時点では $1 = ¥138.79）ので、ある程度流動的な部分はありますが、『NCasT4 v3』を1台丸々一ヶ月稼働しぱなっしで月額9万円程度になります。

以下が Azure 計算ツールでの『NCasT4 v3』の見積もりです。
https://azure.com/e/9260b35f469d457daea3c019ca1c6fe2

まぁ、そこそこの価格になります。
100台起動すると900万円…なかなか…

## 参考リンク

https://github.com/Azure/Unreal-Pixel-Streaming

https://docs.unrealengine.com/4.27/en-US/ProductionPipelines/CloudDeployments/AzurePixelStreaming/