マルチモデルシステム設計:単一のモデルでは不十分な場合

最もシンプルなパターンを選びましょう。

目次

シングルモデルシステムはシンプルです。マルチモデルシステムは強力です。課題となるのはモデルの選択ではなく、それらをオーケストレーションするアーキテクチャの設計です。

マルチモデルシステムとは、単にモデルを増やすことではありません。正しいモデルを、正しいタスクに、正しいタイミングで適用することです。

マルチモデルLLMシステムの設計パターン

アーキテクチャパターン

5つのパターンが、ほとんどのユースケースをカバーします。

パターン 複雑度 使用する場合 トレードオフ
シングルモデル 最低 プロトタイピング、単純なタスク 機能に制限がある
シーケンシャル 複数ステップのワークフロー レイテンシが高くなる
パラレル 独立したタスク コストが高くなる
階層型 複雑な推論 オーケストレーションが複雑
アンサンブル 最高 重要な意思決定 コストが最も高い

動作する最もシンプルなパターンを選択してください。複雑さは実在し、累積していきます。

シーケンシャルアーキテクチャ

モデルのチェーンを通じてタスクを処理し、各モデルが特定のステップを専門に行います。

パターン1: パイプライン

パイプラインパターン — 各モデルの出力が次のモデルに入力されます。

class ModelPipeline:
    def __init__(self):
        self.models = [
            {"model": "qwen2.5-1.5b", "task": "classify"},
            {"model": "qwen2.5-7b", "task": "extract"},
            {"model": "qwen2.5-32b", "task": "reason"},
        ]

    def process(self, input: str) -> str:
        current = input
        for model_config in self.models:
            current = self.call_model(
                model_config["model"],
                self.create_prompt(model_config["task"], current)
            )
        return current

レイテンシは累積します。3つのモデルをシーケンシャルに配置すると、レイテンシは3倍になります。各ステップが実際に異なるモデルを必要とする場合にのみ、このパターンを使用してください。

パターン2: ラ우ター

ルーティングパターン — タスクを分類し、専門モデルへルーティングします。

class ModelRouter:
    def __init__(self):
        self.classifier = "qwen2.5-1.5b"
        self.specialists = {
            "code": "qwen2.5-coder-7b",
            "math": "qwen2.5-32b",
            "creative": "claude-sonnet-4",
            "general": "qwen2.5-7b",
        }

    def route(self, prompt: str) -> str:
        task_type = self.classify(prompt)
        model = self.specialists.get(task_type, self.specialists["general"])
        return self.call_model(model, prompt)

分類器が弱点となります。誤分類されると、間違ったモデルへルーティングされ、品質が損なわれます。十分に機能する分類器を使用してください。カテゴリが明確であれば、小さなモデルでも機能します。

パラレルアーキテクチャ

独立したタスクを同時に処理します。

パターン1: ファンアウト

ファンアウト — 同じプロンプトを複数のモデルで実行します。

import asyncio

class ModelFanOut:
    def __init__(self):
        self.models = [
            "qwen2.5-7b",
            "qwen2.5-32b",
            "claude-sonnet-4",
        ]

    async def process(self, prompt: str) -> list[str]:
        tasks = [self.call_model(model, prompt) for model in self.models]
        return await asyncio.gather(*tasks)

比較、A/Bテスト、または最良の出力を選択したい場合に有用です。コストは高くなりますが、重要な意思決定においては品質向上に見合う価値があります。

パターン2: ボーティング

ボーティング — コンセンサス(合意)を通じて出力を統合します。

class ModelVoting:
    def __init__(self):
        self.models = [
            "qwen2.5-7b",
            "qwen2.5-32b",
            "claude-sonnet-4",
        ]

    def vote(self, prompt: str) -> str:
        responses = [self.call_model(model, prompt) for model in self.models]
        from collections import Counter
        votes = Counter(responses)
        return votes.most_common(1)[0][0]

多数決は分類タスクに適しています。生成タスクでは困難です。正確な一致ではなく、意味的な類似性が必要です。

階層型アーキテクチャ

異なる抽象レベルでモデルを使用します。

パターン1: プランナー-エグゼキューター

プランナー-エグゼキューター — 強力なモデルが計画し、小規模なモデルが実行します。

class PlannerExecutor:
    def __init__(self):
        self.planner = "qwen2.5-32b"
        self.executors = {
            "code": "qwen2.5-coder-7b",
            "search": "qwen2.5-7b",
            "math": "qwen2.5-7b",
        }

    def process(self, task: str) -> str:
        plan = self.call_model(self.planner, f"Plan: {task}")
        results = []
        for step in self.parse_plan(plan):
            executor = self.executors.get(step["type"], "qwen2.5-7b")
            result = self.call_model(executor, step["prompt"])
            results.append(result)
        return self.call_model(self.planner, f"Synthesize: {results}")

プランナーが主要な処理を行います。エグゼキューターが特定のタスクを処理します。このパターンは、計画ステップがコスト高くても、実行ステップが安価な場合に効果的です。

パターン2: スーパーバイザー-ワーカー

スーパーバイザー-ワーカー — スーパーバイザーが委任し、レビューします。

class SupervisorWorker:
    def __init__(self):
        self.supervisor = "qwen2.5-32b"
        self.workers = ["qwen2.5-7b", "qwen2.5-coder-7b"]

    def process(self, task: str) -> str:
        assignments = self.call_model(self.supervisor, f"Assign: {task}")
        results = []
        for assignment in self.parse_assignments(assignments):
            result = self.call_model(
                assignment["worker"], assignment["task"]
            )
            results.append(result)
        return self.call_model(self.supervisor, f"Review: {results}")

スーパーバイザーがボトルネックとなります。計画、委任、レビューを行います。十分な速度があることを確認し、全体システムが遅延しないよう配慮してください。

アンサンブルアーキテクチャ

重要な意思決定のために複数のモデルを組み合わせます。

パターン1: 重み付きアンサンブル

重み付きアンサンブル — 各モデルの出力にスコアを付け、最高スコアのものを選択します。

class WeightedEnsemble:
    def __init__(self):
        self.models = {
            "qwen2.5-32b": 0.5,
            "claude-sonnet-4": 0.3,
            "qwen2.5-7b": 0.2,
        }

    def decide(self, prompt: str) -> str:
        responses = {
            model: self.call_model(model, prompt)
            for model in self.models
        }
        scores = {}
        for model, response in responses.items():
            score = self.evaluate(response) * self.models[model]
            scores[response] = scores.get(response, 0) + score
        return max(scores, key=scores.get)

重みは、各モデルへの信頼度を示します。ベンチマークではなく、実際の性能に基づいて調整してください。

パターン2: コンセンサスアンサンブル

コンセンサスアンサンブル — 合意を必要とし、合意がない場合はエスカレーションします。

class ConsensusEnsemble:
    def __init__(self, threshold: float = 0.7):
        self.threshold = threshold
        self.models = [
            "qwen2.5-32b",
            "claude-sonnet-4",
            "qwen2.5-7b",
        ]

    def decide(self, prompt: str) -> str:
        responses = [
            self.call_model(model, prompt)
            for model in self.models
        ]
        from collections import Counter
        votes = Counter(responses)
        max_votes = max(votes.values())

        if max_votes / len(self.models) >= self.threshold:
            return votes.most_common(1)[0][0]

        return self.call_model("qwen2.5-32b", prompt)

閾値がコンセンサスの厳格さを制御します。0.7は3分の2の合意を意味します。より迅速な決定には閾値を下げ、より高い自信を得るには閾値を上げます。

マルチモデルシステムが適している場合

混合ワークロードがある場合、重要な意思決定に高品質を必要とする場合、またはコストやレイテンシを最適化する必要がある場合に、マルチモデルシステムは理にかなっています。

すべてのタスクが同様の複雑度である場合、プロトタイピング中である場合、または最適化よりもシンプルさが優先される場合は、マルチモデルシステムは適していません。

経験則として、1つのモデルから始めましょう。コスト、レイテンシ、品質といった実際の制約に直面した時点で、モデルを追加してください。必要な前に複雑なアーキテクチャを採用しないでください。

トレードオフ

パターン コスト レイテンシ 品質 複雑度
シングルモデル 最低 最低 変動 最低
シーケンシャル
パラレル
階層型 最高
アンサンブル 最高 最高 最高

すべてのパターンは何かをトレードオフします。あなたの制約に適合するものを選択してください。

関連リンク

購読する

システム、インフラ、AIエンジニアリングの新記事をお届けします。