Amazon Web Services ブログ
Amazon SageMaker 強化学習と Amazon EKS を使用して、プレイヤーの待機時間を短縮し、コンピューティング割り当てのサイズを適切に設定する
マルチプレイヤーゲームのパブリッシャーは、オンラインゲームを起動または維持するときに、リソースを過剰にプロビジョニングするか、手動でコンピューティング割り当てを管理して、プレイヤーの待機時間を短くする必要があることがよくあります。コンピューティング割り当てのモニタリングと制御に役立つツールを開発、設定、デプロイする必要があります。この記事では、プレイヤーが待機する時間とオーバープロビジョニングを計算する時間の両方を簡単に短縮できる新しい機械学習 (ML) ベースのツールである GameServer Autopilot について説明します。GameServer Autopilot は、手動設定の決定を排除し、人為的エラーが発生する機会を減らします。
GameServer Autopilot の初期バージョンでは、線形回帰を使用して必要なコンピューティング能力を推定していました。詳細については、YouTube で機械学習によるゲームサーバーの自動スケーリングをご覧ください。予測があっても、Amazon EC2 インスタンスの準備にはかなりの時間がかかるため、コンピューティングリソースの割り当てを最適化することは簡単ではありません。割り当てアルゴリズムは、EC2 インスタンスをスピンアップしてゲームアセットをインストールするために必要な時間を考慮する必要があります。絶えず変化する使用パターンには、新しいプレイヤーの習慣に適応するモデルが必要です。システムは、需要の変化に合わせてスケールアップおよびスケールダウンする必要があります。
この記事では、Amazon SageMaker 強化学習を使用して、Amazon EKS、Amazon DynamoDB、AWS Lambda 関数、および Amazon API Gatewayで強化学習 (RL) を適用する方法を説明します。さらに、プレイヤーの使用パターンに応じてリソースを割り当てることを学習する ML システムについて説明します。ホストされているモデルは、プレイヤーの待機時間を短縮するために初期化する必要のあるゲームサーバーインスタンスの数を直接予測します。トレーニングプロセスはゲームエコシステムと統合され、必要な設定は最小限で、それを他のコンピューティングリソース割り当てシナリオに拡張できます。
コンピューティングの割り当て
マルチプレイヤーゲームのアーキテクチャには、ゲームサーバー向けのコンピューティングホスティングと、場所とスキルに基づいてプレイヤーをゲームセッションにマッチングするマッチメイキングシステムが含まれます。プレイヤーは仮想ゲームロビーで対戦を待ちます。現在のマルチプレイヤーゲームシステムでは、さまざまなレベルのプレイヤーの数と、マッチメイキングのようなシステムが、ゲームサーバーの需要を左右します。EKS はホスティングプラットフォームを管理します。ホスティングプラットフォームは、マッチメイキングシステムからリクエストを受信すると、ゲームサーバージョブを事後的にスケジュールします。ゲームサーバーは、利用可能な EC2 インスタンスに垂直に格納されます。EKS クラスターオートスケーラーは、現在の EC2 インスタンスがゲームサーバーで満たされると、新しい EC2 インスタンスをスピンアップします。次の図は、典型的な専用ゲームサーバーファームとアーキテクチャを示しています。これは、プレイヤー、マッチメイキング、およびゲームロビーアプリケーションと、EKS がホストする専用ゲームサーバーとのやり取りを示しています。
自動スケーリングの課題
時間的なピークに備えて過剰にプロビジョニングする必要がある静的な割り当てよりも、反応的な割り当ての方が適しています。Amazon EC2 Auto Scaling グループには、自動スケーリングと自動管理のための論理グループとして扱われる EC2 インスタンスのコレクションが含まれています。この反応的アプローチには、Auto Scaling グループのルールベースの動的スケーリングポリシーが含まれます。たとえば、既存のインスタンスの CPU 使用率が 60% を超えたときに EC2 インスタンスを追加します。
ただし、プレイヤーは Auto Scaling グループが EC2 インスタンスを生成して新しいゲームをホストするのを待つ必要がある場合があるため、反応型スケーリングはフラストレーションになる可能性があります。過度のスケールダウンイベントが発生すると、トラフィックの短い一時停止後の待機時間が長くなったり、さらにはライブゲームセッションをシャットダウンしたりする可能性があります。たとえば、マッチメイキングサービスからのリクエストに基づいてゲームサーバーが割り当てられ、マッチメイキングサービスが停止したり、通信が遅延したりすると、反応型システムがリソースを解放します。マッチメイキングシステムが回復すると、必要な実際の計算割り当てに基づいてシステムに大きな負荷がかかります。
次のグラフは、マッチメイキングシステムの停止シナリオと、GameServer Autopilot などのプロアクティブな割り当てシステムがどれほど停止の影響を軽減できるかを示しています。current_gs_demand
行は、マッチメイキングシステムからのゲームサーバーの需要です。num_of_gs
行は、プレイヤーが接続しているアクティブなゲームサーバーの数を表しています。グラフでは、01:00 から 3:30 の間に、マッチメイキングシステムの停止により、ゲームサーバーの需要が平均 86 から 32 に減少しました。対照的に、オートパイロットは、現在の下落が偽陰性のイベントであることを検出し、プレイヤーのためにコンピューティング能力を準備しました。マッチメイキングの問題が解決されるため、プレイヤーのエクスペリエンスにそれ以上の影響はありません。要約すると、優れた動的スケーリングシステムは、適切な数のゲームサーバーを事前に予測およびスケジュールする必要があります。
GameServer Autopilot
割り当てられたゲームサーバーの数は、プレイヤーがマルチプレイヤーゲームセッションに参加または退出するときにスケーリングする必要があります。上記のアーキテクチャを拡張して、ゲームサーバーのオートパイロットが、マッチメイキングサービスの詳細に基づくコンピューティング割り当てパターンを直接学習できるようにすることができます。Amazon SageMaker RL を使用すると、最先端の強化学習アルゴリズムをトレーニングおよびデプロイできます。
トレーニングフェーズでは、ゲームサーバーのスケジューリングシステムとの統合が必要です。EKS を使用してゲームサーバーをデプロイできます。トレーニングジョブが終了すると、トレーニング済みモデルが Amazon S3 に保存されます。モデルは、安全なアクセスのために API Gateway および Lambda 関数と通信する Amazon SageMaker ホスティングエンドポイントにデプロイされます。Lambda 関数を使用してガードレールを組み込むこともできます。そうするのは、たとえば、既存のゲームセッションを中断するなど、カスタマーエクスペリエンスに重大な悪影響を与える可能性のある決定をオーバーライドするためです。オートパイロットサーバーは DynamoDB テーブルに観測履歴を保存し、Amazon SageMaker エンドポイントへの呼び出しに履歴を使用します。詳細については、GitHub リポジトリをご覧ください。
次の図は、オートパイロットを備えた拡張専用ゲームサーバーアーキテクチャを示しています。
EKS 側では、オートパイロットクライアントが API Gateway エンドポイントにクエリし、ゲームサーバー Kubernetes デプロイのサイズを設定します。Kubernetes スケジューラは、強化学習モデルの決定に基づいて必要なゲームサーバーをデプロイすることにより、プレイヤーのリクエストを積極的に満たします。このメソッドは、EC2 インスタンス割り当てシステムと EC2 Auto Scaling グループによるゲームサーバー割り当てを橋渡しし、ゲームセッションをさまざまな EC2 インスタンスタイプとサイズに変換します。
強化学習の使用
強化学習 (RL) では、エージェントは試行錯誤を繰り返して学習し、一連の意思決定を行って、長期的な総報酬を最大化します。Amazon SageMaker 強化学習では、前のセクションで説明した強化学習 Markov 決定プロセスのほとんどのコンポーネントが環境ファイルで定義されています。この記事では、オープンソースを接続し、OpenAI Gym を使用してカスタム環境を開発しました。OpenAI Gym は、強化学習環境の定義に役立ち、Amazon SageMaker に完全に統合された一般的なインターフェイスのセットです。詳細については、GitHub リポジトリをご覧ください。強化学習モデルは、エージェントが取るすべてのアクションに対して報酬と罰を受ける連続的なプロセスによって学習するため、大規模なオンデマンドインスタンスまたはスポット EC2 インスタンスの可用性が不確実な中で意思決定を行うようにシステムをトレーニングすることが可能です。詳細については、「Amazon SageMaker で強化学習を使用する」を参照してください。
強化学習ベースの意思決定は、たとえ短期的にコストが増加しても、長期的に適切なアクション (たとえば、サーバーの事前割り当て) を促進します。エージェントは、将来の到着と遅延した報酬を予測することが困難な不確実な環境で行動することを学びます。不確実性は、ゲームサーバーの需要と、プレイヤーのニーズに対応するために新しいコンピューティングをプロビジョニングするのにかかる時間に現れます。最初に、強化学習エージェントは、適切なゲームサーバーの割り当てを認識せずにゲームサーバーを割り当てます。強化学習エージェントは、時間をかけて学習し、プレイヤーの待機時間とトレードオフの割り当て超過を減らします。
ファーストパーソンシューティング (FPS) ゲーム、アーケードゲームや大規模マルチプレイヤーオンライン (MMO) ゲームでは、ゲームセッションの所要時間は数分から数十分までさまざまです。ゲームセッションが終了し、ゲームサーバーがアイドル状態になると、サーバーは自身を終了し、使用率が低いために最終的に EC2 インスタンスを終了します。セッションの長さは、スケールのコンピューティングアクションの頻度を決定します。たとえば、EC2 インスタンスの準備には 10〜15 分かかります。これには、ゲームのバイナリとアセットのデプロイ時間が含まれます。大規模なコンピューティングリクエストやスポットインスタンスのリクエストを満たすのに時間がかかることがあります。詳細については、「スポットインスタンスリクエスト」を参照してください。そのため、このアルゴリズムでは、一定期間のサーバー数を予測する必要があります。時間の長さは、ゲームセッションの長さと、必要なゲームサーバーを実行するために EC2 インスタンスを準備するのにかかる時間の両方によって決まります。
モデルの使用
簡単にするために、この記事では、トレーニングとモデルのデプロイという 2 つのユースケースを区別しています。強化学習アプローチは、2 つを 1 つのフェーズに結合します。この記事では、ゲームサーバーのオートパイロットがどのようにトレーニングとデプロイのフェーズを組み合わせることができる安全なオートスケーラーになるかについて後で説明します。
トレーニング
ゲームサーバーのオートパイロットモデルは、GitHub で Amazon SageMaker ノートブックサンプルを使用してトレーニングされます。トレーニングでは、強化学習環境 gameserver_env.py
を使用します。これは、トレーニング期間を通じて、サーバーの現在の需要をリクエストします。詳細については、GitHub リポジトリをご覧ください。環境からリクエストされたときにサーバーの現在の需要を返すエンドポイント gs_inventory
URL を設定できます。詳細については、GitHub リポジトリをご覧ください。
トレーニング中、step()
関数が gameserver_env.py
内で実行されると、アルゴリズムが必要に応じて予測するゲームサーバーの数を示すアクションが生成されます。強化学習環境は、EKS コントロールプレーンおよびマッチメイキングサービスとインターフェイスする外部エンドポイントをクエリします。サーバーの現在の需要は、マッチメイキングサービスから取得します。マッチメイキングサービスへのパブリックアクセスを回避するために、強化学習環境によって行われた呼び出しを保護する Lambda 関数と API ゲートウェイをデプロイできます。本番環境の設定では、API キーを使用してアクセスを制限する必要があります。詳細については、「API キーを使用して使用プランを作成および使用する」を参照してください。
step()
関数に 2 つの数値が含まれるようになりました。 1 つ目は、N_action
で表されるアクションです。これは、必要なゲームサーバー数の現在の予測です。2 番目の数値は、EKS から取得したサーバーの実際の数、N_demand
です。step ()
関数は、偽陰性 (比率が 1 より大きい) と偽陽性 (比率が 1 より小さい) の 2 つのケースを区別して報酬を計算します。容量の不足はプレイヤーの待機時間を長くするため、誤検知はさらに悪いと考えられています。したがって、偽陽性は偽陰性よりも 5 倍悪くなります。これはビジネス上の用途に応じて調整でき、さらに複雑な関数になる場合があります。次のコードを参照してください。
def step(self, action):
...
ratio=self.curr_action/self.curr_demand
print('ratio={}'.format(ratio))
if (ratio>1):
reward = -1 * (self.curr_alloc - self.curr_demand)
if (ratio<1):
reward = -5 * (self.curr_demand - self.curr_alloc)
if (ratio==1):
reward=1
reward -= (self.curr_demand - self.curr_alloc)*self.over_prov_factor
必要なゲームサーバーをホストする EC2 インスタンスの準備にかかる時間は、サーバーの需要が変化する速度よりも長い場合があります。したがって、コントローラーは割引係数 (ガンマ) を選択することにより、将来の需要を適切に考慮する必要があります。そのため、step()
の現在のサーバー割り当て (curr_alloc
) は、需要履歴の最も古い需要 (demand_observation[]
) を考慮します。次のコードを参照してください。
def step(self, action):
...
self.curr_alloc = self.demand_observation[0]
次のグラフは、マッチメーキングによって判明したゲームサーバーの現在の需要 (curr_demand
) と予測される割り当て (curr_alloc
) の 2 つのメトリクスを示しています。このグラフは、需要が増加しているときにモデルがどのように過剰プロビジョニングされるかを示しています (curr_alloc
線が curr_demand
線より先に上昇しています)。また、需要が減少し、誤った否定的な予測が発生するため、プロビジョニングが不十分になります。モデルはプレイヤーの待機時間を短縮するためにスケールアップする場合にのみ重要であるため、この動作は許容可能です。スケールダウンは、ゲームサーバーが完了時に終了し、使用率が低いために EC2 インスタンスが終了することによって自動的に行われます。
次のグラフは、トレーニングの全体的な進行状況を示しています。グラフは、マッチメイキングに必要なゲームサーバーの現在の需要 (curr_demand
)、予測される割り当て (curr_alloc
)、およびモデル reward
の 3 つのメトリクスを示しています。予想される割り当てを学びたいとお思いでしょう。グラフは、reward
値が、トレーニングの進行に応じて現在の需要と生産を収束させるのに役立つことを示しています。
モデルのデプロイ
GameServer Autopilot には、サーバーコンポーネントとクライアントコンポーネントが含まれています。サーバーは、Amazon SageMaker ホスティングを介してデプロイされたエンドポイント、推論の履歴を保持する DynamoDB テーブル、および Amazon SageMaker ランタイムセマンティクスを簡素化する API ゲートウェイと Lambda 関数で設定されます。詳細については、GitHub リポジトリをご覧ください。オートパイロットクライアントは、次の 10 分間に起動する必要があるゲームサーバーの数をオートパイロットサーバーにクエリする Kubernetes ポッドとしてデプロイされます。詳細については、GitHub リポジトリをご覧ください。
ノートブックセクションはモデルをデプロイします。次のコードを参照してください。
オートパイロットサーバーのロジックは、クライアントからのリクエストで始まります。サーバーは、5 つの推論の履歴を last_observation
DynamoDB テーブルから取得します。詳細については、GitHub リポジトリをご覧ください。サーバーは、EKS の現在の割り当てをクエリして、誤検知によって引き起こされる誤ったスケールダウンを回避します。オートパイロットサーバーは安全な推論番号をオートパイロットクライアントに返し、オートパイロットクライアントはゲームサーバーのデプロイのサイズを設定します。Kubernetes は、ゲームサーバーをスケジュールすることにより、必要なサーバーが利用可能であることを確認します。利用可能な EC2 インスタンスが十分にない場合、サーバージョブのステータスは Pending
とマークされます。これは、クラスターオートスケーラーが次の 10〜15 分間により多くの EC2 インスタンスを準備することを示しています。
ゲームサーバーのオートパイロットは安全なオートスケーラーです。トレーニング段階で実サーバーを直接制御できる場合、これは強化学習アプローチに対応します。シナリオがライブサーバーの直接制御を許可しない場合、アルゴリズムは現在のアルゴリズムの割り当てを予測することを学習します。たとえば、アプローチは監視付き回帰または予測に縮小されます。次のコードを参照してください。
ap-server/app.py
if (action<curr_demand):
is_false_positive=1
populate_cloudwatch_metric(namespace,1.0,'false-positive')
new_alloc=curr_demand
new_alloc_norm=curr_demand
else:
new_alloc_norm=action
new_alloc=action
is_false_positive=0
オートパイロットの実装
ゲームサーバーのオートパイロットを実装するには、サーバーを実行するコンピューティングファームと、ゲームサーバーの需要を推論するモデルが必要です。コンピューティングファーム管理に EKS を使用し、Amazon SageMaker を使用して、エンドポイントとして Amazon SageMaker でモデルをトレーニング、評価、デプロイできます。また、Lambda と API Gateway を使用して 2 つの部分を統合し、必要なサーバーの継続的な予測のために予測履歴を保持する DynamoDB テーブルを統合する必要があります。この記事では、サーバーファームが、ゲームサーバーのオートパイロットに関係なく動作する既存のライブシステムであると想定しています。したがって、EKS クラスターを構築し、プレイヤーにサービスを提供するサーバーの例をデプロイできます。詳細については、GitHub リポジトリをご覧ください。
この記事では、以下を含む Jupyter ノートブックを提供します。
- Amazon SageMaker トレーニングジョブに必要なパラメータと、セッションサーバー環境に必要なその他の AWS リソース
- 適切な実行ロールを作成し、特定の AWS リソースに必要なロールにさらに権限を追加する方法を示す IAM ロールのセットアップ
- 中間トレーニングジョブアーティファクトと最終モデルを保存する S3 バケット
- クライアントアプリケーション (環境): セッションサーバー環境
- パブリックエンドポイントを使用したトレーニング済みモデルのデプロイ
- トレーニング全体での Amazon CloudWatch による視覚化
- リソースのクリーンアップ
試用する方法を教えてください。
著者について
Yahav Biran は、AWS のソリューションアーキテクトで、大規模なゲーム技術に集中的に取り組んでいます。Yahav は、オープンソースプロジェクトへ貢献することを楽しんでおり、AWS ブログや学術ジャーナルで公開しています。彼は現在、K8s Helm コミュニティ、AWS データベースと計算ブログ、および Journal of Systems Engineering に貢献しています。Yahav は技術イベントで技術プレゼンテーションを行い、お客様と協力してクラウドでアプリケーションを設計しています。彼はコロラド州立大学で博士号 (システム工学) を取得しました。
Bharathan Balaji は AWS のアプライドサイエンティストで、彼の研究対象は強化学習システムとアプリケーションにあります。彼は Amazon SageMaker RL と AWS DeepRacer の立ち上げに貢献しました。彼はカリフォルニア大学サンディエゴ校でコンピューターサイエンスとエンジニアリングの博士号を取得しました。
Murali は AWS のシニア機械学習サイエンティストです。彼の研究の関心は、AI、最適化、学習、推論の交差点にあり、特に現実世界のアプリケーションにおけるノイズと不確実性を理解し、モデル化し、克服するためにそれらを使用しています。 彼は特に実践的かつ大規模な強化学習に関心があります。 彼は Amazon Personalize と Amazon Forecast の立ち上げに貢献し、Amazon SageMaker 強化学習と連携しています。彼はカーネギーメロン大学で博士号を取得しました。