論文概要(Abstract)
MetaLLMは、複数のLLMの中からクエリごとに最適なモデルを動的に選択するルーティングフレームワークである。LLMルーティング問題をマルコフ決定過程(MDP)として定式化し、Multi-Armed Bandit(MAB)アルゴリズムを意思決定エンジンとして活用する。クエリの埋め込みベクトルを状態、LLM選択をアクション、正解率/コスト比を報酬として設計し、UCB・Thompson Sampling・Linear UCBの3手法を評価。MMLU・GSM8Kベンチマークで、GPT-4oの約1/5のコストで77.5%の精度を達成した。
この記事は Zenn記事: 2026年2月版 日本語LLM選定ガイド の深掘りです。
情報源
- arXiv ID: 2406.12320
- URL: https://arxiv.org/abs/2406.12320
- 著者: Quang H. Nguyen, Duy C. Hoang, Juliette Decugis, Saurav Manchanda, Nitesh V. Chawla, Khoa D. Doan
- 発表年: 2024
- 分野: cs.LG, cs.AI, cs.CL
背景と動機(Background & Motivation)
LLM APIの料金体系は性能と正比例する。Zenn記事で示した通り、GPT-5.2は入力$1.75/1Mトークン、DeepSeek-V3.2は$0.28/1Mトークンと6倍以上の価格差がある。しかし全てのクエリにフロンティアモデルが必要なわけではない。「東京の天気は?」のような単純クエリに$1.75/1Mを支払う必要はなく、より安価なモデルで十分である。
この課題に対する既存アプローチには以下の制約があった。
- FrugalGPT: 複数モデルに順次問い合わせ、最初に満足な回答が得られたモデルを採用するカスケード方式。各モデルへの問い合わせ自体にコストが発生する
- RouterLLM: GPT-4の選好データで学習した二値分類器。「強モデル/弱モデル」の二択に限定され、3つ以上のモデルに対応できない
- LLM-Blender: 複数モデルの出力をアンサンブルするが、全モデルの推論コストが発生する
MetaLLMはこれらの制約を解消し、(1) 3つ以上のモデルへの対応、(2) オンライン学習による継続的改善、(3) 高価な選好データ不要、を実現する。
主要な貢献(Key Contributions)
- MDPとしてのLLMルーティング定式化: クエリ特徴を状態、LLM選択をアクション、正解率/コスト比を報酬とするMDP
- 3つのMABアルゴリズムによるルーティング: 文脈非依存(UCB, Thompson Sampling)と文脈依存(LinUCB)の比較評価
- MMLU・GSM8Kでの実証: GPT-4oの約1/5のコストで、GPT-3.5-turboを9ポイント上回る精度を達成
技術的詳細(Technical Details)
MDP定式化
LLMルーティングを以下のMDPとして定式化する。
\[\mathcal{M} = (S, A, R, T, \gamma)\]ここで、
- $S$: 状態空間。クエリの埋め込みベクトル$\mathbf{x}_t \in \mathbb{R}^{1536}$(text-embedding-ada-002で生成)
- $A$: アクション空間。LLMの集合${a_1, a_2, \dots, a_N}$(例: GPT-4o, GPT-3.5-turbo, Llama-3 8B)
- $R$: 報酬関数。$R(s, a) = \frac{\text{correctness}(s, a)}{\text{cost}(s, a)}$
- $T$: 遷移関数。決定論的(同一クエリを同一LLMに送ると同一結果)
- $\gamma = 1$: 割引率(エピソディックタスク)
報酬関数の設計が特に重要である。correctnessは正解なら1、不正解なら0の二値。costは最安モデル(Llama-3 8B)のコストで正規化される。これにより不正解は常に報酬0、正解は安価なモデルほど高い報酬$\in (0, 1]$を得る。
Upper Confidence Bound(UCB)
UCBは探索と活用のバランスをとるバンディットアルゴリズムである。各アーム(LLM)$a$のスコアを以下で計算する。
\[\text{Score}(a) = Q(a) + c\sqrt{\frac{\log t}{N(a)}}\]ここで、
- $Q(a)$: アーム$a$の推定報酬値(これまでの平均報酬)
- $c$: 探索定数
- $t$: 全試行回数
- $N(a)$: アーム$a$が選択された回数
$\sqrt{\log t / N(a)}$の項は、あまり試されていないアーム(LLM)の探索を促進する。UCBはクエリの内容(文脈)を考慮しない。
Thompson Sampling
Thompson Samplingはベイズ的アプローチである。各LLM $i$について、成功回数$\alpha_i$と失敗回数$\beta_i$からBeta分布を維持する。
\[\theta_i \sim \text{Beta}(\alpha_i, \beta_i)\]各ステップで各アームからサンプル$\theta_i$を抽出し、最大のサンプルを持つアームを選択する。報酬に応じて$\alpha_i$(成功時+1)、$\beta_i$(失敗時+1)を更新する。
Linear UCB(LinUCB)— 最高性能
LinUCBはUCBを文脈バンディットに拡張し、クエリ埋め込みを活用する。アーム$a$の文脈$\mathbf{x}_t$に対するスコアは以下で計算される。
\[\text{Score}(a, \mathbf{x}_t) = \hat{\boldsymbol{\theta}}_a^\top \mathbf{x}_t + \alpha \sqrt{\mathbf{x}_t^\top \mathbf{A}_a^{-1} \mathbf{x}_t}\]ここで、
- $\hat{\boldsymbol{\theta}}_a$: アーム$a$のパラメータ推定値
- $\mathbf{A}_a$: アーム$a$の設計行列($\mathbf{A}_a = \mathbf{I} + \sum_t \mathbf{x}_t \mathbf{x}_t^\top$)
- $\alpha$: 探索パラメータ
LinUCBはクエリの意味的特徴から「この数学的クエリにはGPT-4oが必要」「この事実確認クエリにはLlama-3 8Bで十分」といった文脈依存のルーティング判断を学習する。
次元削減: ada-002の1536次元埋め込みは$\mathbf{A}_a^{-1}$の計算が重い。PCA(32, 64, 128次元)で圧縮し、精度と計算コストのバランスを取る。
アルゴリズム全体フロー
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
from dataclasses import dataclass
import numpy as np
@dataclass
class LinUCBArm:
"""Linear UCB arm for a single LLM.
Args:
d: Feature dimension after PCA
alpha: Exploration parameter
"""
d: int
alpha: float = 1.0
def __post_init__(self) -> None:
self.A = np.eye(self.d) # Design matrix
self.b = np.zeros(self.d) # Reward vector
self.theta = np.zeros(self.d) # Parameter estimate
def score(self, x: np.ndarray) -> float:
"""Compute UCB score for this arm given context x.
Args:
x: Context vector (d,)
Returns:
UCB score (higher = more promising)
"""
A_inv = np.linalg.inv(self.A)
self.theta = A_inv @ self.b
exploitation = self.theta @ x
exploration = self.alpha * np.sqrt(x @ A_inv @ x)
return exploitation + exploration
def update(self, x: np.ndarray, reward: float) -> None:
"""Update arm parameters with observed reward.
Args:
x: Context vector used for this selection
reward: Observed reward (correctness / cost)
"""
self.A += np.outer(x, x)
self.b += reward * x
def route_query(
query_embedding: np.ndarray,
arms: dict[str, LinUCBArm],
) -> str:
"""Route a query to the optimal LLM using LinUCB.
Args:
query_embedding: PCA-reduced query embedding
arms: Dictionary mapping LLM names to LinUCB arms
Returns:
Name of the selected LLM
"""
scores = {name: arm.score(query_embedding) for name, arm in arms.items()}
return max(scores, key=scores.get)
ブートストラップ(Cold Start対策)
オンライン学習の開始時、各LLMの性能推定値がない状態(Cold Start)では不適切なルーティングが生じる。MetaLLMはベンチマークの訓練セットをプロキシデータとしてブートストラップフェーズを実行し、初期推定値を構築する。
実装のポイント(Implementation)
実装上の主要な注意点は以下の通りである。
- 埋め込みのキャッシュ: text-embedding-ada-002のAPI呼び出しは1回/クエリに限定し、結果をキャッシュすることで追加コストを抑制
- PCA次元の選択: 32次元は高速だが精度低下、128次元は精度最高だが$\mathbf{A}^{-1}$計算が重い。実験では128次元が最良のコスト-精度バランス
- 報酬の正規化: 最安モデルのコストで割ることで、報酬を$[0, 1]$に正規化。これによりMABアルゴリズムの収束が安定
- バッチ更新: 1クエリごとの逐次更新だけでなく、バッチ単位の更新も可能(ただし論文では逐次更新を評価)
Production Deployment Guide
AWS実装パターン(コスト最適化重視)
LLMルーターを本番環境にデプロイする際の構成を示す。
| 規模 | 月間リクエスト | 推奨構成 | 月額コスト | 主要サービス |
|---|---|---|---|---|
| Small | ~3,000 (100/日) | Serverless | $50-150 | Lambda + Bedrock + DynamoDB |
| Medium | ~30,000 (1,000/日) | Hybrid | $300-800 | Lambda + ECS Fargate + ElastiCache |
| Large | 300,000+ (10,000/日) | Container | $2,000-5,000 | EKS + Karpenter + EC2 Spot |
Small構成(月額$50-150):
- Lambda: ルーター処理(埋め込み生成 → LinUCB判定 → LLM呼び出し)($20/月)
- Bedrock: Claude 3.5 Haiku + Sonnetの2モデル切替 ($80/月)
- DynamoDB: バンディットパラメータ・埋め込みキャッシュ ($10/月)
- API Gateway: REST API ($5/月)
コスト削減テクニック:
- ルーターによるモデル切替で最大85%コスト削減(常時高性能モデル使用比)
- Prompt Caching有効化で30-90%削減
- Bedrock Batch API使用で50%割引(非リアルタイム処理)
コスト試算の注意事項: 上記は2026年2月時点のAWS ap-northeast-1(東京)リージョン料金に基づく概算値です。最新料金は AWS料金計算ツール で確認してください。
Terraformインフラコード
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "llm-router-vpc"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-1a", "ap-northeast-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
enable_nat_gateway = false
enable_dns_hostnames = true
}
resource "aws_iam_role" "lambda_router" {
name = "lambda-llm-router-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }
}]
})
}
resource "aws_iam_role_policy" "bedrock_multi_model" {
role = aws_iam_role.lambda_router.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"]
Resource = [
"arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-haiku*",
"arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet*"
]
}]
})
}
resource "aws_lambda_function" "llm_router" {
filename = "router.zip"
function_name = "llm-router"
role = aws_iam_role.lambda_router.arn
handler = "index.handler"
runtime = "python3.12"
timeout = 120
memory_size = 1024
environment {
variables = {
DYNAMODB_TABLE = aws_dynamodb_table.bandit_state.name
PCA_DIMENSION = "128"
ALPHA_PARAMETER = "1.0"
}
}
}
resource "aws_dynamodb_table" "bandit_state" {
name = "llm-router-bandit-state"
billing_mode = "PAY_PER_REQUEST"
hash_key = "arm_id"
attribute { name = "arm_id"; type = "S" }
}
運用・監視設定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import boto3
cloudwatch = boto3.client('cloudwatch')
# ルーティング精度監視アラート
cloudwatch.put_metric_alarm(
AlarmName='router-accuracy-drop',
ComparisonOperator='LessThanThreshold',
EvaluationPeriods=3,
MetricName='RoutingAccuracy',
Namespace='Custom/LLMRouter',
Period=3600,
Statistic='Average',
Threshold=0.70,
AlarmDescription='ルーティング精度が70%未満に低下'
)
# モデル別コスト監視
cloudwatch.put_metric_alarm(
AlarmName='expensive-model-overuse',
ComparisonOperator='GreaterThanThreshold',
EvaluationPeriods=1,
MetricName='ExpensiveModelRatio',
Namespace='Custom/LLMRouter',
Period=3600,
Statistic='Average',
Threshold=0.5,
AlarmDescription='高コストモデル使用率が50%超過(ルーター性能劣化の可能性)'
)
コスト最適化チェックリスト
- ~100 req/日 → Lambda + Bedrock (Serverless) - $50-150/月
- ~1000 req/日 → ECS Fargate + Bedrock (Hybrid) - $300-800/月
- 10000+ req/日 → EKS + Spot (Container) - $2,000-5,000/月
- ルーターにより高コストモデル使用率を50%未満に維持
- 埋め込みキャッシュでAPI呼び出し削減
- Bedrock Batch API使用(50%割引)
- Prompt Caching有効化(30-90%削減)
- AWS Budgets月額予算設定
- CloudWatch ルーティング精度監視
- 日次コストレポート
実験結果(Results)
MMLU(14,042サンプル、57科目)
| 手法 | 精度 | コスト($) | Llama-3 8B比 |
|---|---|---|---|
| GPT-4o | 85.0% | $9.63 | 100x |
| GPT-3.5-turbo | 68.7% | $1.18 | 12x |
| Llama-3 8B | 59.5% | $0.097 | 1x |
| Random Routing | 71.1% | $3.60 | 37x |
| Optimal Routing(oracle) | 89.8% | $2.32 | 24x |
| MetaLLM (UCB) | 73.8% | $1.40 | 14.4x |
| MetaLLM (TS) | 75.3% | $1.63 | 16.8x |
| MetaLLM (LinUCB-128) | 77.5% | $2.11 | 21.7x |
MetaLLM (LinUCB-128) はGPT-4oの78%の精度を22%のコストで達成。GPT-3.5-turboを8.8ポイント上回り、追加コストは約80%に留まる。
Oracle(上界)の89.8%に対して77.5%であり、理論的にはさらなる改善余地がある。Random Routingの$3.60に対しMetaLLMは$2.11と41%安く、精度も6.4ポイント高い。
アルゴリズム比較
LinUCBがUCB・Thompson Samplingを一貫して上回る。これはクエリ埋め込みの活用(文脈依存)により、「この数学クエリにはGPT-4oが必要」「この事実確認クエリにはLlama-3 8Bで十分」という意味的パターンを学習できるためである。
PCA次元の増加は性能向上につながる(32→64→128で精度が約1ポイントずつ改善)が、$\mathbf{A}^{-1}$計算コストも増加するため、128次元が実用的な上限である。
実運用への応用(Practical Applications)
Zenn記事の「用途別モデル選定コード」は静的なルールベースの選定だが、MetaLLMの手法を適用することで動的かつ適応的なモデル選定が実現できる。
具体的な応用パターンは以下の通りである。
- マルチモデルAPIゲートウェイ: リクエストごとにLinUCBで最適モデルを選択。チャットボットの月額APIコストを70-85%削減
- AB テストの代替: 従来は人手でABテストを行いモデル切替を判断していたが、MABベースのルーティングは自動的に最適モデルに収束
- 新モデル導入の段階的評価: 新モデルをアームとして追加するだけで、MABが自動的に性能を評価し適切なクエリにルーティング
関連研究(Related Work)
- FrugalGPT (arXiv:2305.05176): カスケード方式のLLMコスト最適化。各モデルに順次問い合わせるため追加コストが発生
- RouterLLM (arXiv:2406.18665): GPT-4選好データで学習した二値ルーター。MetaLLMはN個のモデルに対応し、高価な選好データが不要
- LLM-Blender (arXiv:2306.02561): 複数LLM出力のアンサンブル。品質は向上するが全モデルの推論コストが必要
| 特性 | FrugalGPT | RouterLLM | MetaLLM |
|---|---|---|---|
| ルーティング方式 | カスケード | 二値分類 | N個マルチモデル |
| 学習データ | 不要 | GPT-4選好データ | タスク訓練セットのみ |
| 文脈認識 | なし | あり(BERT) | あり(LLM埋め込み+MAB) |
| オンライン学習 | なし | なし | あり |
まとめと今後の展望
MetaLLMは、LLMルーティングをMDP+Multi-Armed Banditとして定式化し、文脈依存のLinUCBで動的モデル選択を実現した。Zenn記事の「用途別モデル選定」をさらに発展させ、GPT-4oの約1/5のコストで77.5%の精度を達成している。今後はZenn記事で触れた日本語LLMベンチマーク(Qualiteg等)のスコアをLinUCBの文脈特徴量に組み込むことで、日本語特化のコスト最適ルーティングが実現可能である。
参考文献
- arXiv: https://arxiv.org/abs/2406.12320
- Related Zenn article: https://zenn.dev/0h_n0/articles/3a4f2089113d8e