TECH PLAY

UX

イベント

マガジン

技術ブログ

本記事は 2026 年 5 月 7 日に公開された “ Announcing aggregations on Amazon ElastiCache ” を翻訳したものです。 Amazon ElastiCache が集計クエリをサポートするようになり、単一のクエリでキャッシュ内のデータを直接フィルタリング、グループ化、変換、集計することがより簡単になりました。集計クエリを使用することで、テラバイト規模のデータに対してマイクロ秒単位の低レイテンシーで、最新の書き込みが反映された結果を返す、リアルタイムなアプリケーション体験を構築できます。データがすでに存在する場所で、アプリケーションが要求する速度で分析を行うことができ、別途分析レイヤーを用意する必要はありません。集計機能を使用すると、ElastiCache に保存済みのデータに対して、リアルタイムのリーダーボード、ファセット検索によるカタログブラウジング、運用レポート、探索的な分析クエリなどを構築できます。 ElastiCache 内のメモリ上で集約処理を直接実行することで、アーキテクチャの複雑さを軽減し、応答時間を改善できます。集約クエリはサーバー側で計算を実行するため、アプリケーションはデータをその場で分析し、最終的なサマリーのみを返すことができます。例えば、1 つの集約クエリで、製品カタログをフィルタリングして特定のカテゴリのデータを取得し、結果をブランドごとにグループ化し、各ブランドの平均評価を計算し、パフォーマンス上位 10 件のみを返すといったことが可能です。これらのクエリは、GROUPBY、REDUCE、APPLY、FILTER、SORTBY、LIMIT などのステージをパイプラインに連結することで構築でき、各ステージの出力が次のステージへの入力になります。これらのステージを任意の順序で組み合わせ、繰り返し使用することで、1 つのコマンドで複数ステップの分析ワークフローを構築できます。集約はプライマリ上で Read-after-Write 整合性 (書き込み後読み取り整合性) を提供するため、結果には最新の書き込みが反映され、クライアントコードを変更することなくシャード間でスケールします。本投稿では、集約によって実現できるユースケースを紹介し、ElastiCache for Valkey を使ってファセットブラウジングエンジンを構築しながら、その仕組みを解説します。 これらの集約機能は、ElastiCache version 9.0 for Valkey で、全文検索、完全一致検索、範囲検索、ベクトル検索機能 ( Amazon ElastiCache での全文検索、完全一致検索、範囲検索、ハイブリッド検索 を参照) と並んで利用可能です。ElastiCache version 9.0 for Valkey ではまた、個々のフィールドに対するきめ細やかな TTL 制御を可能にするハッシュフィールドの有効期限機能や、最大 40% 向上したパイプラインスループットも導入されています。リリースの詳細については、 Amazon ElastiCache 向け Valkey 9.0 のお知らせ をご覧ください。 集約の使用が適している場面 アプリケーションは、リアルタイムでフィルタリング、グループ化、集計する必要があるデータを ElastiCache に保存することがよくあります。例えば、E コマースプラットフォームでは、カタログ全体にわたってカテゴリ別の平均評価や商品数を計算します。ストリーミングサービスでは、ジャンル別の総視聴数、平均視聴時間、再生数上位の作品を算出し、トレンドフィードやレコメンデーションランキングを構築します。金融サービスでは、ユーザーや時間枠ごとに取引をグループ化して合計を計算し、しきい値違反を検出し、コンプライアンスレポートを生成します。アプリケーションは、ユーザー向けのエクスペリエンス、ライブ分析、運用レポートを支えるためにこのデータをリアルタイムに分析する必要があり、古いデータや遅い結果はユーザーエクスペリエンスを低下させます。デバッグや単発の調査のためにアドホックなクエリが必要な開発者は、別の分析レイヤーを設定したり、データをアプリケーションレイヤーにエクスポートしたりすることなく、ライブデータに対して直接集計を実行することもできます。集計は、次の 3 つの一般的なユースケースをサポートします。 カタログフィルタリングのためのファセット検索: E コマースプラットフォームでは、買い物客がブラウジングする際に、各フィルタの組み合わせに一致する商品数を表示します。買い物客がカテゴリや価格帯を選択すると、UI は残りのすべてのフィルタ値のカウントを即座に更新します。1 つの集計クエリで、一致するカタログをブランド、色、または評価ごとにグループ化し、グループごとのカウントを返すため、アプリケーションは事前計算や古いカウントのキャッシュなしに正確なファセット数を表示できます。集計はインメモリで直接実行されるため、数百万の商品にまたがる場合でも、これらのカウントはマイクロ秒のレイテンシで返されます。 リアルタイムのトレンドとランキング: ゲームプラットフォーム、ストリーミングサービス、マーケットプレイスでは、ライブのエンゲージメント指標に基づいてトレンドコンテンツや上位ランカーを表示します。従来、これにはスケジュールに従ってランキングを再計算するバックグラウンドジョブが必要で、データの陳腐化を招いていました。あるいは、大量の結果セットに対するアプリケーション側でのソートが必要で、レイテンシーが増加していました。単一の集計クエリで、コンテンツをカテゴリーごとにグループ化し、総視聴回数、エンゲージメントスコア、プレイヤーランクを計算して、上位の結果を返すことができます。インデックスは書き込み時に同期的に更新されるため、集計クエリはポーリング、キャッシュ無効化、定期的な再計算を行うことなく最新のデータを反映します。 運用レポートと分析: ElastiCache を高速アクセスのために利用するアプリケーションでは、同じデータに対する運用分析やレポートが必要になることがよくあります。例えば、セッションストアではデバイスごとの平均セッション時間を計算し、E コマースプラットフォームではステータスやフルフィルメント段階ごとの注文量を計算します。Aggregations は、別途の分析用クラスターをプロビジョニングしたり ETL パイプラインを維持したりすることなく、スケジュールに基づいて、またはオンデマンドで、これらのクエリをインメモリデータに対して直接実行します。 ElastiCache を使ったファセット検索とリアルタイム分析の構築 これらの機能を組み合わせて実演するために、メディアストリーミングプラットフォームである AnyOrganization 向けに、ファセットブラウジングと分析エンジンを構築します。AnyOrganization はコンテンツカタログを ElastiCache にハッシュキーとして保存しており、各映画タイトルにはジャンル、言語、スタジオ、評価、リアルタイムの視聴回数といったメタデータが含まれています。以下のコードでは、このデータに対して 3 つのクエリパターンを構築します。ファセットフィルタリング、ライブトレンドアイテム、そしてスタジオレベルのエンゲージメントレポートです。 前提条件 この記事の例では、Python と valkey-py クライアントライブラリを使用します。手順を実行するには、以下が必要です (所要時間の目安: 30 分): AWS アカウント および AWS Command Line Interface (AWS CLI) ElastiCache レプリケーショングループを作成する権限を持つ AWS IAM ロール Amazon ElastiCache クラスターと同じ VPC 内にある Amazon EC2 インスタンス (または Amazon ElastiCache に接続可能な 任意のアプリケーション) Python 3.9 以降、および valkey-py バージョン 6.1.1 以降 (pip install valkey) この投稿の完全なサンプルコードは、 Amazon ElastiCache samples GitHub リポジトリで入手できます。 git clone https://github.com/aws-samples/amazon-elasticache-samples.git cd amazon-elasticache-samples/blogs/aggregations-blog ElastiCache for Valkey クラスターのセットアップ 集計機能を利用するための ElastiCache クラスターは、 AWS Management Console または AWS CLI で作成できます。集計機能は ElastiCache version 9.0 for Valkey 以降で利用可能です。以下の例では CLI を使用しています。 aws elasticache create-replication-group \ --replication-group-id AnyOrganization-cache \ --replication-group-description "AnyOrganization Valkey cluster" \ --engine valkey \ --engine-version 9.0 \ --transit-encryption-enabled \ --cache-node-type cache.r7g.large \ --num-node-groups 2 \ --replicas-per-node-group 1 \ --multi-az-enabled \ --automatic-failover-enabled # --transit-encryption-enabled が設定されている場合、Python クライアント接続に # ssl=True を追加します: # client = valkey.ValkeyCluster(..., ssl=True) データへのインデックス作成 ElastiCache に保存されているデータに対して、 catalog_index というインデックスを作成します。 Genre 、 language 、 studio は、ファセットフィルタリング用の完全一致タグとしてインデックス化されます。 Release_year 、 rating 、 views_24h は、範囲フィルタやソート用の数値フィールドとしてインデックス化されます。タイトルは、キーワード、プレフィックス、あいまい一致をサポートする全文検索可能なフィールドとしてインデックス化されます。 以下のコードは、valkey-py の search モジュールを使用して Valkey Search コマンドを構築し送信します。各 Python メソッド呼び出しは、ネットワーク越しに送信される Valkey コマンドに直接対応しています。例えば、 client.ft("catalog_index").create_index(...) は FT.CREATE コマンドを送信し、 client.ft("catalog_index").aggregate(req) は FT.AGGREGATE コマンドを送信します。各コードブロックの横に、対応する Valkey コマンドを示しています。 import valkey from valkey.commands.search.field import TextField, TagField, NumericField from valkey.commands.search.indexDefinition import IndexDefinition, IndexType # : Insert your ElastiCache cluster's discovery endpoint VALKEY_CLUSTER_ENDPOINT = "placeholder_cluster.cnxa6h.clustercfg.use1.cache.amazonaws.com" client = valkey.ValkeyCluster( host=VALKEY_CLUSTER_ENDPOINT, port=6379, decode_responses=True, ssl=True) client.ft("catalog_index").create_index(fields=[ TextField("title"), TagField("genre"), TagField("language"), TagField("studio"), NumericField("release_year"), NumericField("rating"), NumericField("views_24h")], definition=IndexDefinition(prefix=["title:"],index_type=IndexType.HASH)) 同等の Valkey コマンド: FT.CREATE catalog_index ON HASH PREFIX 1 title: SCHEMA title TEXT genre TAG language TAG studio TAG release_year NUMERIC rating NUMERIC views_24h NUMERIC ElastiCache for Valkey ストアにカタログデータを投入します。本記事では、ElastiCache GitHub リポジトリのサンプルデータを使用しますが、他のデータソースを使用することもできます。 import csv import urllib.request import io import time response = urllib.request.urlopen( "https://raw.githubusercontent.com/aws-samples/amazon-elasticache-samples/main/blogs/aggregations-blog/catalog_data.csv") reader = csv.DictReader(io.TextIOWrapper(response)) count = 0 for row in reader: key = row.pop("id") client.hset(key, mapping=row) count += 1 print(f"Loaded {count} records") インデックスはデータをロードする前でも後でも作成できます。プレフィックスに一致するキーが既に存在する場合、Valkey Search はそれらを自動的にインデックスにバックフィルします。 ファセットフィルター 以下の集計は、ユーザーが選択したフィルターを受け取り、一致する結果をジャンル、言語、評価、公開年でグループ化し、各グループのタイトル数を返します。これにより、UI は結果と並べてファセットの件数を表示できます。 from valkey.commands.search.aggregation import AggregateRequest, Desc from valkey.commands.search import reducers def get_facet_counts(filters): # Build query string from user-selected filters clauses = [] if "genre" in filters: clauses.append(f"@genre:{{{filters['genre']}}}") if "language" in filters: clauses.append(f"@language:{{{filters['language']}}}") if "min_rating" in filters: clauses.append(f"@rating:[{filters['min_rating']} + inf]") query = " ".join(clauses) if clauses else "@rating:[-inf + inf]" # Run an aggregation for each facet dimension dimensions = ["genre", "language", "rating"] facets = {} for dim in dimensions: req = AggregateRequest(query) \ .load(f"@{dim}") \ .group_by(f"@{dim}", reducers.count().alias("count")) facets[dim] = client.ft("catalog_index").aggregate(req).rows return facets # Example: user filters for dramas in english, get counts for each dimension facets = get_facet_counts({"genre": "drama", "language": "english"}) # Example output: # {'genre': [{'genre': 'drama', 'count': '6'}], # 'language': [{'language': 'english', 'count': '6'}], # 'rating': [{'rating': '4', 'count': '4'}, # {'rating': '5', 'count': '2'}]} 同等の Valkey コマンド (1 つのファセットディメンション、英語のドラマでフィルタリングする場合): FT.AGGREGATE catalog_index "@genre:{drama} @language:{english}" LOAD 1 @genre GROUPBY 1 @genre REDUCE COUNT 0 AS count リアルタイムで急上昇中のアイテム 以下のコードは、ジャンルごとのトップトレンドタイトルを取得します。これは、ユーザーがコンテンツを視聴するとリアルタイムで更新される views_24h フィールドに対する集計によって実現されています。 def get_trending_by_genre(limit=10): # Get the highest view count per genre # sorted by most popular genre first req = AggregateRequest("@rating:[-inf + inf]") \ .load("@genre", "@views_24h") \ .group_by("@genre", reducers.max("@views_24h").alias("max_views")) \ .sort_by(Desc("@max_views"), max=limit) return client.ft("catalog_index").aggregate(req).rows trending_by_genre = get_trending_by_genre() # Example output: # [{'genre': 'action', 'max_views': '4500'}, # {'genre': 'comedy', 'max_views': '3800'}, # {'genre': 'thriller', 'max_views': '3600'}, # {'genre': 'sci-fi', 'max_views': '3400'}, # {'genre': 'drama', 'max_views': '3200'}, # {'genre': 'animation', 'max_views': '3100'}, # {'genre': 'romance', 'max_views': '2800'}, # {'genre': 'horror', 'max_views': '2600'}, # {'genre': 'documentary', 'max_views': '1900'}] 同等の Valkey コマンド (1 つのファセットディメンションで、英語のドラマをフィルタリングする場合): FT.AGGREGATE catalog_index "@rating:[-inf + inf]" LOAD 2 @genre @views_24h GROUPBY 1 @genre REDUCE MAX 1 @views_24h AS max_views SORTBY 2 @max_views DESC MAX 10 リアルタイムトレンドアイテム 以下のコードは、ジャンルごとにトレンドの上位タイトルを取得するもので、ユーザーがコンテンツを視聴するとリアルタイムに更新される views_24h フィールドに対する集計によって実現されています。 def get_trending_by_genre(limit=10): # Get the highest view count per genre # sorted by most popular genre first req = AggregateRequest("@rating:[-inf + inf]") \ .load("@genre", "@views_24h") \ .group_by("@genre", reducers.max("@views_24h").alias("max_views")) \ .sort_by(Desc("@max_views"), max=limit) return client.ft("catalog_index").aggregate(req).rows trending_by_genre = get_trending_by_genre() # Example output: # [{'genre': 'action', 'max_views': '4500'}, # {'genre': 'comedy', 'max_views': '3800'}, # {'genre': 'thriller', 'max_views': '3600'}, # {'genre': 'sci-fi', 'max_views': '3400'}, # {'genre': 'drama', 'max_views': '3200'}, # {'genre': 'animation', 'max_views': '3100'}, # {'genre': 'romance', 'max_views': '2800'}, # {'genre': 'horror', 'max_views': '2600'}, # {'genre': 'documentary', 'max_views': '1900'}] 同等の Valkey コマンド: FT.AGGREGATE catalog_index "@rating:[-inf + inf]" LOAD 2 @genre @views_24h GROUPBY 1 @genre REDUCE MAX 1 @views_24h AS max_views SORTBY 2 @max_views DESC MAX 10 オンデマンドエンゲージメントレポート AnyOrganization は、制作スタジオ別のコンテンツパフォーマンスを測定するために、日次のレポートジョブを実行しています。次のコードは、同じインデックスに対する集計を使用して、タイトル数、平均評価、総エンゲージメントなどのスタジオレベルのメトリクスを計算します。 def get_studio_report(): # Studio performance: title count, average rating, total 24h views req = AggregateRequest("@rating:[-inf + inf]") \ .load("@studio", "@rating", "@views_24h") \ .group_by("@studio", reducers.count().alias("title_count"), reducers.avg("@rating").alias("avg_rating"), reducers.sum("@views_24h").alias("total_views")) \ .sort_by(Desc("@total_views")) return client.ft("catalog_index").aggregate(req).rows studio_report = get_studio_report() # Example output: # [{'studio': 'StreamFlix Originals', 'title_count': '18', # 'avg_rating': '4.3333333333', 'total_views': '46200'}, # {'studio': 'Summit Pictures', 'title_count': '13', # 'avg_rating': '3.8461538462', 'total_views': '30000'}, # {'studio': 'Crimson Studios', 'title_count': '11', # 'avg_rating': '4.4545454545', 'total_views': '23100'}, # {'studio': 'Emerald Films', 'title_count': '8', # 'avg_rating': '4', 'total_views': '13600'}] 同等の Valkey コマンド: FT.AGGREGATE catalog_index "@rating:[-inf + inf]" LOAD 3 @studio @rating @views_24h GROUPBY 1 @studio REDUCE COUNT 0 AS title_count REDUCE AVG 1 @rating AS avg_rating REDUCE SUM 1 @views_24h AS total_views SORTBY 2 @total_views DESC ベストプラクティス 集計クエリのレイテンシーとスループットを改善するには、各パイプラインステージを通過するドキュメント数を減らすために早い段階でフィルタリングします。マッチする範囲が広いクエリは、パイプラインに入るキーの数が増え、初期スキャンと初期ステージのコストが増加します。例えば、上記のファセットフィルタリングの例では、ユーザーのアクティブなフィルターをクエリ文字列で渡すことで、マッチするドキュメントのみが GROUPBY ステージに入ります。また、しきい値を満たさないグループを削除するために GROUPBY ステージの後に FILTER を追加することもできます。例えば、結果を返す前にタイトル数が 5 未満のジャンルを除外する場合などです。さらに、上位の結果のみが必要な場合は、 SORTBY に MAX を追加することで、トレンドアイテムの例で示すように、エンジンはワーキングセット全体をソートするのではなく、上位の結果のみを追跡します。 LOAD を使うと、インデックスに含まれていないフィールドであっても、基となるハッシュデータから直接フィールドを取得して集約パイプラインに取り込むことができます。例えば、ハッシュに actors フィールドを保存しているがインデックス化していない場合、クエリ実行時に LOAD で読み込み、それを使ってグループ化やソートを行うことができます。ただし、 LOAD は一致するドキュメントごとに基となるキーから生データを取得する必要があるため、結果セットのサイズに応じてレイテンシーが増加します。このオーバーヘッドを避けるため、ロードするフィールドの数は最小限に抑えてください。 クリーンアップ このウォークスルーのために ElastiCache クラスターを作成し、不要になった場合は、今後の課金を避けるために、次の AWS CLI コマンドを使用してクラスターを削除してください。 aws elasticache delete-replication-group --replication-group-id AnyOrganization-cache はじめに この記事では、ElastiCache のアグリゲーションについて、ファセットフィルタリング、ライブトレンドのレコメンデーション、オンデマンドのエンゲージメントレポートを取り上げ、これらすべてを単一の Valkey Search インデックス上に構築する方法を解説しました。アグリゲーションは、すべての商用 AWS リージョン、AWS GovCloud (US) リージョン、および中国リージョンにおいて、ElastiCache for Valkey バージョン 9.0 を実行するノードベースのクラスターで追加費用なしでご利用いただけます。Valkey は、Redis に代わる最も寛容なライセンスのオープンソースかつベンダー中立な選択肢であり、ElastiCache で推奨されるエンジンです。使い始めるには、AWS Management Console、AWS SDK、または AWS CLI を使用して、Valkey 9.0 以降の新しいクラスターを作成するか、 既存のクラスターをアップグレード してください。詳細については、 ElastiCache のドキュメント をご覧ください。質問やフィードバックがある場合は、 AWS re:Post for ElastiCache をご覧ください。 著者について Chaitanya Nuthalapati Chaitanya は AWS インメモリデータベースサービスのシニアテクニカルプロダクトマネージャーで、Amazon ElastiCache for Valkey に注力しています。以前は、生成 AI、機械学習、グラフネットワークを活用したソリューションを構築していました。仕事以外の時間では、Chaitanya は趣味を集めるのに忙しく、現在はテニス、スケートボード、パドルボードを楽しんでいます。 Karthik Subbarao Karthik は Amazon ElastiCache のシニアソフトウェアエンジニアであり、オープンソースの Valkey プロジェクトに積極的に貢献しています。分散システム、データベース、Rust、そして全般的にソフトウェア開発/テクノロジーを通じたイノベーションに情熱を注いでいます。 Allen Samuels Allen は AWS のプリンシパルエンジニアです。分散型で高性能なシステムに情熱を注いでいます。世界中を旅したりデュプリケートブリッジをプレイしたりしていない時は、カリフォルニア州サンノゼで過ごしています。 Siva Subramaniam Siva は AWS のシニアソリューションアーキテクトで、技術リーダーシップとデータベースアーキテクチャにおいて 20 年の経験を持っています。お客様が AWS の専用データベースを使用して移行とイノベーションを実現できるよう支援しています。仕事以外では、Siva はクリケット、農作業、そして妻から料理を学ぶことを楽しんでいます。 ご指導いただいた Ian Childress 氏、そしてプロジェクト全体を通じて実装面で貢献いただいた Miles Song 氏に特に感謝いたします。 本記事は、 Announcing aggregations on Amazon ElastiCache を翻訳したものです。翻訳は Solutions Architect の Hayato Tsutsumi が担当しました。
こんにちは、クロスイノベーション本部リーディングエッジテクノロジーセンターの山下です。 最近は、gpt-ossやQwen3.5といったローカルLLM(Local Large Language Model)も注目されており、これらを活用したプロジェクトも増えてきています。 今回の記事では、ローカルLLMのベンチマークソフトウェアである GuideLLM について紹介します。LLMの性能には様々な観点がありますが、GuideLLMはLLMサーバ自体の応答速度などを測るためのベンチマークソフトウェアです。 GuideLLMでは、以下のような観点でLLMサーバの性能を評価します。 レイテンシー(応答時間) スループット(処理能力) 同時リクエスト数に対する性能の変化 エラー率や安定性 GuideLLMは、LLMサーバに対して様々な負荷をかけることで、これらの観点で性能を評価します。例えば、同時に複数のリクエストを送ることで、スループットやレイテンシーの変化を測定します。また、長時間の負荷テストを行うことで、安定性やエラー率も評価します。 LLMサーバの評価項目 LLMサーバの評価には、TTFT(Time To First Token)、ITL(Inter Token Latency)やThroughputなどの指標が用いられます。 TTFT(Time To First Token) : LLMが最初のトークンを生成するまでの時間を測定します。これは、ユーザーが応答を受け取るまでの待ち時間を示す重要な指標です。 ITL(Inter Token Latency) : トークン間の生成時間を測定します。これにより、LLMの応答速度や処理能力を評価できます。 Throughput : 一定時間内に処理できるリクエストの数を測定します。これは、LLMサーバの処理能力を示す指標です。 Latency(レイテンシー) : LLMサーバがリクエストに対して応答するまでの時間を測定します。これはトークンごとではなくすべての生成が完了するまでの時間になります。 同時リクエスト数に対する性能の変化 : 同時に複数のリクエストを送ることで、LLMサーバの性能がどのように変化するかを評価します。これにより、サーバのスケーラビリティや負荷耐性を測定できます。 エラー率や安定性 : 長時間の負荷テストを行うことで、LLMサーバの安定性やエラー率を評価します。 通常のWebサーバのベンチマークソフトウェアは、HTTPリクエストの処理能力や応答時間を測定することが一般的です。しかし、LLMサーバは応答を作成するための時間が長く、しかも生成された結果をリアルタイムに返す仕組みになっています。このため、通常のWebサーバの指標に加えてTTFTやITLといったLLM特有の指標が重要になります。特にTTFTはユーザーが最初の応答を受け取るまでの待ち時間を示し、ITLは1つのトークンが生成されてから次のトークンが生成されるまでの時間になります。これらがユーザーエクスペリエンスに直結する重要な指標となります。 ChatGPTなどのサービスを利用している際に、最初の一文字が出るまでの時間が長いと感じることがあるかもしれませんが、これはTTFTが長いことを意味しています。TTFTが短いほど、ユーザーは迅速に応答を受け取ることができ、より快適な体験を提供できます。 GuideLLMは実際にLLMサーバに対して負荷をかけることで、これらの指標を測定し、LLMサーバの性能を評価します。これにより、LLMサーバの性能を定量的に評価し、改善点を特定することができます。 GuideLLMの使用方法 GuideLLMは、Pythonで実装されたベンチマークソフトウェアです。以下のコマンドでインストールできます。 他のインストール方法については、公式の GitHubリポジトリ を参照してください。 pip install guidellm[recommended] インストール後、例えば以下のコマンドでベンチマークを実行できます。 guidellm benchmark run\ --target "http://<LLMサーバのアドレス:ポート>" \ --profile sweep \ --max-seconds 30 \ --data "prompt_tokens=256,output_tokens=128" ここでは --target オプションでLLMサーバのアドレスとポートを指定します。 --profile オプションでは、ベンチマークのプロファイルを指定します。 sweep プロファイルは、様々な負荷条件でベンチマークを実行するためのプロファイルです。 --max-seconds オプションでは、ベンチマークの最大実行時間を指定します。 --data オプションでは、ベンチマークに使用するデータを指定します。ここでは、プロンプトトークン数と出力トークン数を指定しています。 --profile として今回は sweep を指定しています。これの動作は以下のようなものになっています。 まずは1並列でのベンチマークを行い、ベースラインのレイテンシーを測定します。これにより、LLMサーバが単一リクエストに対してどれくらいの応答時間があるかを把握します。 次に並列アクセスを行い(デフォルトでは512並列)LLMサーバの最大スループットを測定します。これにより、LLMサーバがどれくらいのリクエストを同時に処理できるかを把握します。 2つのベンチマークでベースとなる性能と最大スループットがわかりました。次に、ベースラインのレイテンシーと最大スループットの間の設定でベンチマークを試します。これにより、LLMサーバが異なる負荷条件でどのように性能が変化するかを把握します。 --profile には他にも色々なプロファイルが用意されているので、目的に応じて選択することができます。 公式のページ を参考にしてください。 実行例 ここでは、実際にGuideLLMを使用してベンチマークを実行した例を紹介します。今回は、ローカルで動作しているLLMサーバに対してベンチマークを実行しました。 通信するLLMサーバはDGX Sparkで動作しているvLLMサーバでgpt-oss-120b を使用しています。 以下のコマンドでベンチマークを実行しました。 GUIDELLM__MAX_CONCURRENCY は、guidLLMがベンチマークを実行する際の最大並列数です。 今回の接続先がDGX Sparkなのでそこまで多くの接続はしない想定なので128並列を指定してみました。 また、 --processor オプションで、ベンチマークで使用するデータを生成するために使用するプロセッサを指定しています。ここでは、gpt-oss-120bが接続先になるので、 openai/gpt-oss-120b を指定しています。 export GUIDELLM__MAX_CONCURRENCY=128 guidellm benchmark --target "LLMサーバのアドレス:ポート" \ --output-dir ./output-dir/ \ --profile sweep \ --max-seconds 300 \ --data "prompt_tokens=256,output_tokens=128" \ --processor "openai/gpt-oss-120b" ベンチマークの結果は以下のようになりました。 すべての結果を載せると長すぎるので、ベンチマーク結果のサマリの部分を抜粋しています。 サマリを見てみると全体の数字の傾向として、同時リクエスト数が増えるにつれて、レイテンシー(Lat)が増加し、スループット(Tok gen/s)も増加していることがわかります。 また、TTFTやITLも同様に増加しています。つまりリクエスト数が増えると応答速度が遅くなっていることがわかります。 一方でTTFTは最悪でも500ms程度で、ITLも131ms程度なので、同時リクエスト数が増えても応答速度はまだ許容可能な範囲に収まっていることがわかります。 特に throughput@128 の行を見ると、スループットが約5.1 req/sに達していることがわかります。さらに、123.2並列まで問題なく処理できていることがわかります。この場合でも、TTFTは1506.7ms、ITLは177.3msなので、同時リクエスト数が増えても応答速度はまだ許容可能な範囲と言えるのではないでしょうか。 複数ある constant@数字 の結果は、ベースラインのレイテンシーと最大スループットの間の設定でベンチマークを試した結果になります。 @ の右側の数字はリクエストの頻度になります。 これらの結果から、TTFTがどの程度までなら許容できるのかを基準にして許容可能なリクエスト頻度を決めることもできます。例えば、TTFTで900ms以下に応答してほしいという場合であるなら constant@1.49 、 constant@2.09 の結果が参考になるかもしれません。 constant@1.49 ではTTFTが786.1ms、 constant@2.09 ではTTFTが943.2msとなっています。つまり、1.49リクエスト/秒程度であれば、TTFTが900ms以下に収まる可能性があることがわかります。 利用してみて気が付いた点 ベンチマークの出力形式としては、JSONやCSVに加えてHTMLも選択できます。しかし、今回HTML形式で出力したものを確認したところ、うまく表示されませんでした。生成されているHTMLに問題がありそうですが原因は不明です。JSONやCSV形式で出力したものは問題なく利用できたので今回はそちらを使用しました。 まとめ 今回は、ローカルLLMのベンチマークソフトウェアであるGuideLLMについて紹介しました。GuideLLMは、LLMサーバの性能を様々な観点で評価するためのベンチマークソフトウェアです。GuideLLMを使用することで、LLMサーバの性能を定量的に評価し、改善点を特定することができます。 ローカルLLMを活用したプロジェクトを進める際には、LLMサーバの性能を評価して最適な設定を見つけることが重要です。ぜひ、GuideLLMを活用して、ローカルLLMの性能を評価して最適な設定を見つけてください。 私たちは一緒に働いてくれる仲間を募集しています! 電通総研 キャリア採用サイト 電通総研 新卒採用サイト 執筆: @yamashita.tsuyoshi レビュー: @sato.taichi ( Shodo で執筆されました )
2025 年 8 月に、 AWS User Experience Customization (UXC) 機能を導入しました。これにより、お客様の特定のニーズに合わせてユーザーインターフェイス (UI) を調整し、タスクを効率的に完了できるようになりました。この機能を使用すると、アカウント管理者は AWS マネジメントコンソール の一部の UI コンポーネントをカスタマイズできます。例えば、 AWS アカウントに色を割り当て 識別しやすくすることが可能です。 2026 年 3 月 26 日、UXC に追加されたカスタマイズ機能を発表いたしました。これによりチームメンバー向けに、関連する AWS リージョンとサービスを選択的に表示できるようになりました。未使用のリージョンとサービスを非表示にすることで、認知的な負荷を軽減し、不要なクリックやスクロールを排除できるため、集中力を高め、作業時間を短縮できます。 今回のリリースにより、アカウントの色、リージョン、サービスの表示を一括してカスタマイズできるようになりました。 アカウントを色で分類 アカウントの色を設定して、視覚的に区別できます。開始するには、 AWS マネジメントコンソール にサインインして、ナビゲーションバーでアカウント名を選択します。アカウントの色はまだ設定されていません。色を設定するには、 [アカウント] を選択します。 [アカウント表示設定] で、希望するアカウントの色を選択し、 [更新] を選択します。選択した色がナビゲーションバーに表示されます。 アカウントの色を変更すると、アカウントの目的を明確に区別できます。例えば、開発アカウントにはオレンジ、テストアカウントには水色、本番稼働アカウントには赤を使用できます。 リージョンとサービスの可視性をカスタマイズ リージョンセレクターに表示する AWS リージョン、またはコンソールナビゲーションに表示する AWS サービスを制御できます。つまり、アカウントに関連するリージョンとサービスのみを表示するように設定できます。 はじめに、ナビゲーションバーの歯車アイコンを選択し、 [すべてのユーザー設定を表示] を選択します。管理者ロールの場合は、統合設定に新しい [アカウント設定] タブが表示されます。設定を行っていない場合、すべてのリージョンとサービスが表示されます。 表示されるリージョンを設定するには、 [表示されるリージョン] セクションの [編集] を選択します。表示されているリージョンを選択して [すべての利用可能なリージョン] または [リージョンを選択] を選択し、リストを設定します。 [変更を保存] をクリックします。 表示されるリージョン設定を設定すると、コンソールのナビゲーションバーのリージョンセレクターに選択したリージョンのみが表示されます。 同じ方法で、表示されるサービスを設定することもできます。カテゴリからサービスを検索または選択します。ここでは [人気のサービス] カテゴリを使用してお気に入りを選択しました。選択が終了したら、 [変更を保存] を選択します。 表示されるサービス設定を設定すると、ナビゲーションバーの [すべてのサービス] メニューに選択したサービスのみが表示されます。 検索バーでサービス名を検索する場合、選択できるのは選択されたサービスのみです。 リージョンとサービスの表示設定は、コンソールでのサービスとリージョンの表示のみを制御します。 AWS コマンドラインインターフェイス (AWS CLI) 、 AWS SDK 、AWS API、または Amazon Q Developer を通じたアクセスは制限されません。 新しい visibleServices パラメータおよび visibleRegions パラメータを使用して、これらのアカウントカスタマイズ設定をプログラムで管理することもできます。例えば、 AWS CloudFormation サンプルテンプレートを使用できます。 AWSTemplateFormatVersion: "2010-09-09" Description: Customize AWS Console appearance for this account Resources: AccountCustomization: Type: AWS::UXC::AccountCustomization Properties: AccountColor: red VisibleServices: - s3 - ec2 - lambda VisibleRegions: - us-east-1 - us-west-2 また、Cloudformation テンプレートをデプロイすることもできます。 $ aws cloudformation deploy \ --template-file account-customization.yaml \ --stack-name my-account-customization 詳細については、「 AWS ユーザーエクスペリエンスのカスタマイズ API リファレンス 」と「 AWS CloudFormation テンプレートリファレンス 」を参照してください。 今すぐ AWS マネジメントコンソール で試し、コンソールの下部にある フィードバック リンクを選択するか、 AWS マネジメントコンソールの AWS re:Post フォーラム に投稿するか、AWS サポートの連絡先にフィードバックをお寄せください。 – Channy 原文は こちら です。

動画

書籍