Amazon Web Services ブログ

Amazon Bedrock 上で基盤モデルのコストと利用状況を追跡できる社内 SaaS サービスを構築する

この記事は、Build an internal SaaS service with cost and usage tracking for foundation models on Amazon Bedrock を翻訳したものです。

企業は、各事業部門 (LOB) に基盤モデルへのアクセスを提供することで、生成 AI の可能性を迅速に引き出そうとしています。IT チームは、集中管理とオブザーバビリティを提供しながら、事業部門が迅速かつ俊敏にイノベーションを起こせるよう支援する責任があります。例えば、チーム間の基盤モデルの使用状況を追跡し、使用料を請求し、事業部門の関連するコストセンターに可視性を提供する必要があるかもしれません。さらに、チームごとに異なるモデルへのアクセスを規制する必要があるかもしれません。例えば、特定の基盤モデルのみが使用を承認されている場合などです。

Amazon Bedrock は、AI21 Labs、Anthropic、Cohere、Meta、Stability AI、Amazon などの大手 AI 企業が提供する高性能な基盤モデルを単一の API で利用できるフルマネージドサービスです。また、セキュリティ、プライバシー、責任ある AI を備えた生成 AI アプリケーションを構築するための幅広い機能も提供します。Amazon Bedrock はサーバーレスであるため、インフラストラクチャを管理する必要がなく、すでにご利用中の AWS サービスを使用して生成 AI 機能を安全にアプリケーションに統合およびデプロイできます。

基盤モデルのための software as a service (SaaS) レイヤーは、アクセスと利用状況の一元管理を維持しながら、エンドユーザーにシンプルで一貫したインターフェイスを提供できます。API ゲートウェイは、モデルの利用者とモデルエンドポイントサービスの間の疎結合を可能にし、変化するモデル、アーキテクチャ、呼び出し方法に適応できる柔軟性を提供します。

この記事では、組織内のチームをテナントとして捉えた場合の、マルチテナントアーキテクチャで Amazon Bedrock を使用して基盤モデルにアクセスするための内部 SaaS レイヤーの構築方法をご紹介します。特に、テナントごとの使用量とコストの追跡、およびテナントごとの使用量制限などのコントロールに焦点を当てています。このソリューションと Amazon Bedrock の利用プランが、一般的な SaaS ジャーニーフレームワークにどのように対応するかについて説明します。ソリューションのコードと AWS Cloud Development Kit (AWS CDK) テンプレートは、GitHub リポジトリで入手できます。

課題

AI プラットフォーム管理者は、複数の開発チームに対して基盤モデルへの標準化された簡単なアクセスを提供する必要があります。

基盤モデルへの管理されたアクセスを提供する上で、以下のような課題があります。

  • コストと使用状況の追跡 – 個々のテナントの基盤モデルのコストと使用状況を追跡・監査し、特定のコストセンターに費用を振り分けます
  • 予算と使用量の制御 – テナントごとに定義された頻度での基盤モデルの許可された使用に対して、API クォータ、予算、使用制限を管理します
  • アクセス制御とモデルガバナンス – テナントごとに承認された特定のモデルに対するアクセス制御を定義します
  • マルチテナント標準化 API – OpenAPI 標準に準拠した基盤モデルへの一貫したアクセスを提供します
  • API の一元管理 – モデルへのアクセスのための API キーを管理する単一のレイヤーを提供します
  • モデルのバージョンと更新 – 新規および更新されたモデルバージョンの展開を行います

ソリューションの概要

このソリューションでは、マルチテナントアプローチについて説明します。ここでのテナントは、個人のユーザー、特定のプロジェクト、チーム、あるいは部門全体まで、さまざまな単位を指します。このアプローチについて説明する際、最も一般的なケースであるため、チームという用語を使用します。チームの API アクセスを制限し監視するために、API キーを使用します。各チームには 基盤モデル へのアクセス用の API キーが割り当てられます。組織内には、さまざまなユーザー認証および承認メカニズムが導入されている場合があります。簡略化のため、このソリューションではこれらは扱っていません。既存の ID プロバイダーをこのソリューションと統合することも可能です。

次の図は、ソリューションのアーキテクチャと主要コンポーネントを示しています。異なるコストセンターに割り当てられたチーム (テナント) は、API サービスを介して Amazon Bedrock 基盤モデル を利用します。チームごとの使用量とコストを追跡するために、このソリューションは、呼び出されたモデル、テキスト生成モデルのトークン数、マルチモーダルモデルの画像サイズなど、個々の呼び出しに関するデータを記録します。さらに、モデルごとの呼び出し回数とチームごとのコストを集計します。

AWS CDK を使用して、お客様のアカウントにこのソリューションをデプロイできます。AWS CDK は、使い慣れたプログラミング言語を使用してクラウドアプリケーションリソースをモデル化およびプロビジョニングするためのオープンソースのソフトウェア開発フレームワークです。AWS CDK のコードは GitHub リポジトリで入手できます。

以下のセクションでは、このソリューションの主要なコンポーネントについて詳しく説明します。

チーム別の基盤モデル利用状況の把握

各チームの基盤モデル使用状況を収集するワークフローは、以下のステップで構成されています (前述の図の番号に対応):

  1. チームのアプリケーションは、Amazon API Gateway に POST リクエストを送信し、model_id クエリパラメータで呼び出すモデルを指定し、リクエストボディにユーザープロンプトを含めます。
  2. API Gateway は、リクエストを AWS Lambda 関数 (bedrock_invoke_model) にルーティングします。この関数は、Amazon CloudWatch でチームの使用情報をログに記録し、Amazon Bedrock モデルを呼び出す役割を担います。
  3. Amazon Bedrock は、AWS PrivateLink を利用した VPC エンドポイントを提供します。このソリューションでは、Lambda 関数は PrivateLink を使用して Amazon Bedrock にリクエストを送信し、アカウントの VPC と Amazon Bedrock サービスアカウント間のプライベート接続を確立します。PrivateLink の詳細については、Use AWS PrivateLink to set up private access to Amazon Bedrockをご覧ください。
  4. Amazon Bedrock の呼び出し後、Amazon CloudTrailCloudTrail イベントを生成します。
  5. Amazon Bedrock の呼び出しが成功すると、Lambda 関数は呼び出されたモデルのタイプに応じて以下の情報をログに記録し、生成されたレスポンスをアプリケーションに返します:
    • team_id – リクエストを発行するチームの一意の識別子
    • requestId – リクエストの一意の識別子
    • model_id – 呼び出すモデルの ID
    • inputTokens – プロンプトとしてモデルに送信されたトークン数(テキスト生成および埋め込みモデル用)
    • outputTokens – モデルによって生成される最大トークン数(テキスト生成モデル用)
    • height – リクエストされた画像の高さ(マルチモーダルモデルおよびマルチモーダル埋め込みモデル用)
    • width – リクエストされた画像の幅(マルチモーダルモデルのみ)
    • steps – リクエストされたステップ数( Stability AI モデル用)

チームごとのコスト追跡

別のフローでは、使用状況情報を集約し、チームごとのオンデマンドコストを日次で計算して保存します。フローを分離することで、コストの追跡がモデル呼び出しフローのレイテンシーとスループットに影響を与えないようにしています。
ワークフローのステップは以下の通りです:

  1. Amazon EventBridge ルールが毎日 Lambda 関数 (bedrock_cost_tracking) をトリガーします。
  2. Lambda 関数は前日の使用情報を CloudWatch から取得して関連するコストを計算し、team_idmodel_id で集計されたデータを CSV 形式で Amazon Simple Storage Service (Amazon S3) に保存します。

Amazon S3 に保存されたデータのクエリと可視化には、S3 SelectAmazon Athena と Amazon QuickSight など、さまざまなオプションがあります。

チームごとの使用量の制御

使用プランは、1 つまたは複数のデプロイされた API にアクセスできるユーザーを指定し、オプションでリクエストのスロットリングを開始するためのターゲットリクエストレートを設定します。このプランは API キーを使用して、各キーに関連付けられた API にアクセスできる API クライアントを識別します。API Gateway の使用プランを使用して、事前に定義されたしきい値を超えるリクエストをスロットリングできます。また、API キーとクォータ制限を使用して、指定された時間間隔内に各チームが発行できる API キーごとのリクエストの最大数を設定できます。これは、アカウントレベルでのみ割り当てられる Amazon Bedrock サービスクォータに加えて設定できます。

前提条件

このソリューションをデプロイする前に、以下のものを準備してください:

AWS CDK スタックのデプロイ

GitHub リポジトリの README ファイルの手順に従って、AWS CDK スタックを設定およびデプロイしてください。

このスタックは以下のリソースをデプロイします:

  • プライベートネットワーク環境 (VPC、プライベートサブネット、セキュリティグループ)
  • モデルアクセスを制御する IAM ロール
  • 必要な Python モジュール用の Lambda レイヤー
  • Lambda 関数 invoke_model
  • Lambda 関数 list_foundation_models
  • Lambda 関数 cost_tracking
  • REST API (API Gateway)
  • API Gateway 使用量プラン
  • 使用量プランに関連付けられた API キー

チームのオンボーディング

新しいチームにアクセス権を付与するには、以下の 2 つの方法があります。 API キーを異なるチーム間で共有し、API 呼び出し時に異なる team_id を指定してモデルの使用状況を追跡する、もしくは、 README の手順に従って、Amazon Bedrock リソースにアクセスするための専用の API キーを作成する、という方法です。

このスタックは以下のリソースをデプロイします:

  • 先に作成した REST API に関連付けられた API Gateway 使用量プラン
  • 新しいチーム用の使用量プランに関連付けられた API キー (API のスロットリングとバースト設定が予約済み)

API Gateway のスロットリングとバースト設定の詳細については、スループット向上のための API リクエストのスロットリングを参照してください。

スタックをデプロイすると、team-2 の新しい API キーも作成されていることが確認できます。

モデルアクセス制御の設定

プラットフォーム管理者は、Lambda 関数 invoke_model に関連付けられた IAM ポリシーを編集することで、特定の基盤モデルへのアクセスを許可できます。

IAM アクセス許可は setup/stack_constructs/iam.py ファイルで定義されています。以下のコードをご覧ください:

self.bedrock_policy = iam.Policy(
            scope=self,
            id=f"{self.id}_policy_bedrock",
            policy_name="BedrockPolicy",
            statements=[ 
                iam.PolicyStatement(
                    effect=iam.Effect.ALLOW,
                    actions=[ 
                        "sts:AssumeRole",
                    ],
                    resources=["*"],
                ),
                iam.PolicyStatement(
                    effect=iam.Effect.ALLOW,
                    actions=[ 
                        "bedrock:InvokeModel",
				"bedrock:ListFoundationModels",

                    ],
                    resources=[ 
  	"arn:aws:bedrock:*::foundation-model/anthropic.claude-v2.1",
	"arn:aws:bedrock:*::foundation-model/amazon.titan-text-express-v1",
	"arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v1"
 ],
                )
            ],
        )

…

 self.bedrock_policy.attach_to_role(self.lambda_role)

サービスの呼び出し

ソリューションをデプロイした後、コードから直接サービスを呼び出すことができます。以下は、POST リクエストを通じてテキスト生成のための invoke_model API を Python から使用した例です:

api_key="abcd1234"

 model_id = "amazon.titan-text-express-v1" #the model id for the Amazon Titan Express model 
 
 model_kwargs = { # inference configuration 
    "maxTokenCount": 4096,
    "temperature": 0.2 
}

 prompt = "What is Amazon Bedrock?"

 response = requests.post(
    f"{api_url}/invoke_model?model_id={model_id}",
    json={"inputs": prompt, "parameters": model_kwargs},
    headers={
        "x-api-key": api_key, #key for querying the API 
        "team_id": team_id #unique tenant identifier 
    }
)

 text = response.json()[0]["generated_text"] 

 print(text)

出力: Amazon Bedrock is an internal technology platform developed by Amazon to run and operate many of their services and products. Some key things about Bedrock …

(参考訳) Amazon Bedrock は、Amazon が多くのサービスや製品を稼働・運用するために開発した内部技術プラットフォームです。Bedrock に関する主なポイントは…

以下は、POST リクエストを通じてエンベディングを生成するために invoke_model API を使用した Python の別の例です。

model_id = "amazon.titan-embed-text-v1" #the model id for the Amazon Titan Embeddings Text model 

 prompt = "What is Amazon Bedrock?"

 response = requests.post(
    f"{api_url}/invoke_model?model_id={model_id}",
    json={"inputs": prompt, "parameters": model_kwargs},
    headers={
        "x-api-key": api_key, #key for querying the API 
        "team_id": team_id #unique tenant identifier,
	"embeddings": "true" #boolean value for the embeddings model 
    }
)

 text = response.json()[0]["embedding"] 

出力: 0.91796875, 0.45117188, 0.52734375, -0.18652344, 0.06982422, 0.65234375, -0.13085938, 0.056884766, 0.092285156, 0.06982422, 1.03125, 0.8515625, 0.16308594, 0.079589844, -0.033935547, 0.796875, -0.15429688, -0.29882812, -0.25585938, 0.45703125, 0.044921875, 0.34570312 …

基盤モデルへのアクセス拒否

以下は、POST リクエストを使用して invoke_model API でテキスト生成を行う Python の例で、アクセス拒否応答の場合の例です。

model_id = " anthropic.claude-v1" #the model id for Anthropic Claude V1 model 
 
 model_kwargs = { # inference configuration 
    "maxTokenCount": 4096,
    "temperature": 0.2 
}

 prompt = "What is Amazon Bedrock?"

 response = requests.post(
    f"{api_url}/invoke_model?model_id={model_id}",
    json={"inputs": prompt, "parameters": model_kwargs},
    headers={
        "x-api-key": api_key, #key for querying the API 
        "team_id": team_id #unique tenant identifier 
    }
)

 print(response)
 print(response.text)

<Response [500]> “Traceback (most recent call last):\n File \”/var/task/index.py\”, line 213, in lambda_handler\n response = _invoke_text(bedrock_client, model_id, body, model_kwargs)\n File \”/var/task/index.py\”, line 146, in _invoke_text\n raise e\n File \”/var/task/index.py\”, line 131, in _invoke_text\n response = bedrock_client.invoke_model(\n File \”/opt/python/botocore/client.py\”, line 535, in _api_call\n return self._make_api_call(operation_name, kwargs)\n File \”/opt/python/botocore/client.py\”, line 980, in _make_api_call\n raise error_class(parsed_response, operation_name)\nbotocore.errorfactory.AccessDeniedException: An error occurred (AccessDeniedException) when calling the InvokeModel operation: Your account is not authorized to invoke this API operation.\n

コスト見積もりの例

オンデマンド料金で Amazon Bedrock モデルを呼び出す場合、総コストは入力コストと出力コストの合計として計算されます。
入力コストはモデルに送信される入力トークン数に基づき、出力コストは生成されるトークン数に基づいて計算されます。
料金は、入力トークン 1,000 個あたりと出力トークン 1,000 個あたりで設定されています。
詳細および具体的なモデル料金については、Amazon Bedrock の料金をご参照ください。

2 つのチーム (team1 と team2) が、このポストで紹介するソリューションを通じて Amazon Bedrock にアクセスする例を見てみましょう。
Amazon S3 に保存された 1 日分の使用量とコストデータを、次の表に示します。

input_tokens 列と output_tokens 列には、特定の日におけるモデルごと、チームごとのモデル呼び出しにおける入力トークンと出力トークンの合計が保存されます。

input_cost 列と output_cost 列には、モデルごとおよびチームごとの各コストが格納されます。これらは以下の計算式を使用して算出されます。

input_cost = input_token_count * model_pricing["input_cost"] / 1000
output_cost = output_token_count * model_pricing["output_cost"] / 1000

チーム ID モデル ID 入力トークン数 出力トークン数 呼び出し回数 入力コスト 出力コスト
Team1 amazon.titan-tg1-large 24000 2473 1000 0.0072 0.00099
Team1 anthropic.claude-v2 2448 4800 24 0.02698 0.15686
Team2 amazon.titan-tg1-large 35000 52500 350 0.0105 0.021
Team2 ai21.j2-grande-instruct 4590 9000 45 0.05738 0.1125
Team2 anthropic.claude-v2 1080 4400 20 0.0119 0.14379

実践的なマルチテナントサーバーレス SaaS 環境の全体像

エンドツーエンドで機能するマルチテナントのサーバーレス SaaS 環境がどのようなものか見ていきましょう。以下は参考アーキテクチャの図です。

このアーキテクチャ図は、投稿の前半で示した前回のアーキテクチャ図を俯瞰したバージョンです。前回のアーキテクチャ図では、言及されたマイクロサービス (基盤モデルサービス) の 1 つの詳細を説明しました。この図は、基盤モデルサービス以外にも、機能的でスケーラブルなプラットフォームを実装するためには、マルチテナント SaaS プラットフォームに他のコンポーネントも必要であることを説明しています。

アーキテクチャの詳細について説明していきましょう。

テナントアプリケーション

テナントアプリケーションは、環境と連携するフロントエンドアプリケーションです。
ここでは、複数のテナントが異なるローカル環境や AWS 環境からアクセスしている様子を示しています。フロントエンドアプリケーションは、新規テナントが自身で登録できる登録ページや、SaaS サービスレイヤーの管理者向けの管理コンソールを含むように拡張できます。テナントアプリケーションが SaaS 環境とのやり取りを必要とするカスタムロジックを実装する必要がある場合、アプリケーションアダプターマイクロサービスの仕様を実装することができます。例えば、SaaS 環境の認可仕様に従いながら、カスタムの認可ロジックを追加するようなシナリオが考えられます。

共有サービス

以下は共有サービスです:

  • テナントとユーザー管理サービス – これらのサービスは、テナントの登録と管理を担当します。アプリケーションサービスとは分離され、すべてのテナントで共有される共通機能を提供します。
  • 基盤モデルサービス – このマイクロサービスは、この投稿の冒頭で説明したソリューションアーキテクチャ図で示されており、API Gateway から Lambda 関数へのやり取りがこのマイクロサービスの範囲内で行われます。すべてのテナントは、このマイクロサービスを使用して、Anthropic、AI21、Cohere、Stability、Meta、Amazon からの基盤モデル、およびファインチューニングされたモデルを呼び出します。また、CloudWatch ログで使用状況を追跡するために必要な情報も収集します。
  • コスト追跡サービス – このサービスは、各テナントのコストと使用状況を追跡します。このマイクロサービスはスケジュールに従って実行され、CloudWatch ログをクエリして集計された使用状況の追跡と見積もりコストをデータストレージに出力します。コスト追跡サービスは、さらなるレポートや可視化を構築するように拡張できます。

アプリケーションアダプターサービス

このサービスは、テナントが SaaS 環境にカスタムロジックを統合するために実装できる仕様と API のセットを提供します。必要なカスタム統合の程度に応じて、このコンポーネントはテナントにとってオプションとなります。

マルチテナントデータストア

共有サービスは、個々のテナントと DynamoDB アイテムを関連付けるテナントパーティショニングキーを持つ、単一の共有 Amazon DynamoDB テーブルなどのデータストアにデータを保存します。コスト追跡の共有サービスは、集計された使用量とコスト追跡データを Amazon S3 に出力します。ユースケースに応じて、アプリケーション固有のデータストアを設けることもできます。

マルチテナント SaaS 環境には、さらに多くのコンポーネントが含まれる可能性があります。詳細については、AWS のサーバーレスサービスを利用したマルチテナント SaaS ソリューションの構築を参照してください。

複数のデプロイメントモデルのサポート

SaaS フレームワークは通常、プールとサイロの 2 つのデプロイメントモデルを定義しています。プールモデルでは、すべてのテナントが共有ストレージと共有コンピューティングインフラストラクチャを持つ共有環境から基盤モデルにアクセスします。サイロモデルでは、各テナントが専用のリソースセットを持ちます。分離モデルについては、SaaS テナント分離戦略ホワイトペーパーをご参照ください。

提案されたソリューションは、両方の SaaS デプロイメントモデルに採用できます。プールアプローチでは、集中管理された AWS 環境が API、ストレージ、およびコンピューティングリソースをホストします。サイロモデルでは、各チームが専用の AWS 環境内の API、ストレージ、およびコンピューティングリソースにアクセスします。

このソリューションは、Amazon Bedrock が提供する利用プランにも対応しています。

AWS では、推論用に 2 つの利用プランを選択できます:

  • On-Demand – このモードでは、利用期間にコミットメントせずに、従量課金ベースで基盤モデルを利用できます
  • Provisioned Throughput – このモードでは、利用期間にコミットメントすることで、アプリケーションのパフォーマンス要件を満たすのに十分なスループットをプロビジョニングできます

これらのオプションの詳細については、Amazon Bedrock の料金をご参照ください。

この記事で説明するサーバーレス SaaS リファレンスソリューションでは、Amazon Bedrock の利用プランを適用して、エンドユーザーにベーシックとプレミアムの階層オプションを提供できます。

ベーシックプランには、Amazon Bedrock のオンデマンドまたはプロビジョンドスループット消費が含まれ、特定の使用量と予算の制限を設定できます。テナントの制限は、リクエスト数、トークンサイズ、または予算配分に基づいてリクエストを制御することで実現できます。プレミアムティアのテナントは、Amazon Bedrock のプロビジョンドスループット消費による専用リソースを持つことができます。これらのテナントは通常、高スループットと低レイテンシーでの Amazon Bedrock 基盤モデルへのアクセスを必要とする本番環境のワークロードに関連付けられます。

まとめ

この投稿では、マルチテナント環境で Amazon Bedrock を使用して基盤モデルにアクセスする社内 SaaS プラットフォームの構築方法について説明しました。その際、各テナントのコストと使用状況の追跡、およびスロットリング制限に焦点を当てました。さらに探求すべきトピックとしては、組織内の既存の認証・認可ソリューションの統合、双方向のクライアントサーバー通信のための WebSocket を含む API 層の強化、コンテンツフィルタリングやその他のガバナンスガードレールの追加、複数のデプロイ層の設計、SaaS アーキテクチャにおける他のマイクロサービスの統合などがあります。

このソリューションのコード全体は、GitHub リポジトリで入手できます。

SaaS ジャーニーフレームワークの詳細については、SaaS Journey Framework: Building a New SaaS Solution on AWS を参照してください。

翻訳はソリューションアーキテクトの福本が担当しました。

著者について

Hasan Poonawala は、AWS のシニア AI/ML スペシャリストソリューションアーキテクトとして、ヘルスケアおよびライフサイエンスのお客様を担当しています。
Hasan は、AWS 上での生成 AI および機械学習アプリケーションの設計、デプロイ、スケーリングを支援しています。
クラウドにおける機械学習、ソフトウェア開発、データサイエンスの分野で 15 年以上の実務経験を持っています。
余暇には、自然を探索したり、友人や家族と時間を過ごすことを楽しんでいます。

Anastasia Tzeveleka は、AWS のシニア AI/ML スペシャリストソリューションアーキテクトです。
EMEA 地域のお客様が AWS サービスを使用してファンデーションモデルを構築し、スケーラブルな生成 AI および機械学習ソリューションを作成するお手伝いをしています。

Bruno Pistone は、ミラノを拠点とする AWS の生成 AI および ML スペシャリストソリューションアーキテクトです。
大規模な顧客と協力して、技術的なニーズを深く理解し、AWS クラウドと Amazon Machine Learning スタックを最大限に活用する AI および機械学習ソリューションの設計を支援しています。
専門分野は、機械学習の一連のプロセス、機械学習の実用化、生成 AI です。
友人と時間を過ごしたり、新しい場所を探索したり、旅行を楽しんでいます。

Vikesh Pandey は、金融サービスを専門とする生成系 AI/ML ソリューションアーキテクトで、金融系のお客様が数百から数千人規模のユーザーに対応できる生成系 AI/ML プラットフォームとソリューションの構築とスケーリングを支援しています。
余暇には、さまざまなブログフォーラムで記事を書いたり、子供と一緒に LEGO を組み立てたりして過ごしています。