Modellruttning: Sluta använda en modell för allt

Rätt modell för rätt uppgift.

Sidinnehåll

Att köra en modell med 70 miljarder parametrar för att sammanfatta ett 200-ord långt e-postmeddelande är slöseri. Att använda en 3-miljardsmodell för att granska produktionskod är riskabelt. De flesta system hamnar någonstans emellan – och det är här modellruttning kommer in i bilden.

Det handlar om att matcha uppgiftens komplexitet med modellens kapacitet. Kompromisserna är verkliga, men besparingarna är det också.

Diagram över strategier för LLM-modellruttning

Ruttproblemet

De flesta börjar med en modell och håller fast vid den. Det fungerar tills man märker kostnaden, eller latensen, eller båda. Alternativet är att bygga en ruttare – något som bestämmer vilken modell som hanterar vilken förfrågan.

Fyra strategier fungerar i praktiken:

  1. Kapacitetsbaserad – rutt baserat på vad modellen kan göra
  2. Kostnadsmedveten – rutt baserat på vad du är villig att betala
  3. Latensmedveten – rutt baserat på hur snabbt du behöver svaret
  4. Hybrid – kombinera dem

Var och en optimerar något annat. Att välja en handlar oftast om vad som gör mest ont.

Kapacitetsbaserad ruttning

Det enklaste tillvägagångssättet. Klassificera uppgiften, skicka den till modellen som hanterar den.

Uppgift Modellt Storlek Exempel
Klassificering, taggning 1-3B Qwen2.5-1.5B, Gemma-2-2B
Sammanfattning, extraktion 3-7B Qwen2.5-7B, Llama-3.1-8B
Kodgenerering 7-14B Qwen2.5-Coder-7B, DeepSeek-Coder-V2
Komplex resonemang 14-32B Qwen2.5-32B, Llama-3.1-70B
Kreativt skrivande, analys 32B+ Qwen2.5-72B, Claude, GPT-4

Om uppgiften inte behöver den större modellen, använd den inte. En 1.5B-modell hanterar sentimentklassificering bra. Den skriver bara ingen sammanhängande essay.

Implementeringen är rakt fram:

ROUTING_RULES = {
    "classify": {"model": "qwen2.5-1.5b", "max_tokens": 100},
    "summarize": {"model": "qwen2.5-7b", "max_tokens": 500},
    "code_review": {"model": "qwen2.5-coder-7b", "max_tokens": 2000},
    "reason": {"model": "qwen2.5-32b", "max_tokens": 4000},
    "creative": {"model": "claude-sonnet-4", "max_tokens": 8000},
}

def route_request(task_type: str) -> dict:
    return ROUTING_RULES.get(task_type, ROUTING_RULES["reason"])

Fånget är klassificeringen i sig. Om du tar fel på uppgiftstypen ruttar du till fel modell. Jag har sett system klassificera kodgranskning som “sammanfattning” och förlora kvalitet i smyg.

Kostnadsmedveten ruttning

Lokal inferens skiner här. Lokala modeller är effektivt gratis efter att hårdvaran amorteras. En RTX 5080 betalar sig själv på cirka sex månader vid måttlig API-användning.

Modell Input ($/M tokens) Output ($/M tokens) Lokal kostnad/timme
GPT-4o $2.50 $10.00
Claude Sonnet 4 $3.00 $15.00
Qwen2.5-72B (API) $0.50 $2.00
Qwen2.5-32B (lokal) $0.00 $0.00 ~$0.10
Qwen2.5-7B (lokal) $0.00 $0.00 ~$0.05

Om du bearbetar tusentals förfrågningar per session slår även $0.05 i elkostnad $15/M tokens.

Budgetbaserad ruttning faller tillbaka när du spenderar:

class CostAwareRouter:
    def __init__(self, budget_per_session: float = 0.10):
        self.budget = budget_per_session
        self.spent = 0.0
        self.models = {
            "cheap": {"model": "qwen2.5-7b", "cost": 0.0},
            "medium": {"model": "qwen2.5-32b", "cost": 0.0},
            "expensive": {"model": "claude-sonnet-4", "cost": 0.000015},
        }

    def route(self, task: str) -> str:
        ratio = self.spent / self.budget
        if ratio < 0.5:
            return self.models["expensive"]["model"]
        elif ratio < 0.8:
            return self.models["medium"]["model"]
        return self.models["cheap"]["model"]

Kvaliteten försämras när du faller tillbaka. Du börjar med Claude, går över till Qwen-32B, sedan till Qwen-7B. Vid slutet av en lång session är utdata märkbart sämre. Om det spelar roll beror på vad du bygger.

Latensmedveten ruttning

Interaktiva verktyg behöver snabba första tokens. Batchjobb kan vänta. Skillnaden är oftast en faktor fem i modellstorlek.

Användningsfall Första token Klar Max modellstorlek
Realtid-chat < 200ms < 2s < 7B
Interaktiva verktyg < 500ms < 5s < 14B
Batchbearbetning < 1s < 30s Valfri
Forskning/analys < 2s < 60s Valfri

När du strömmar tokens till en användare är det latensen för den första token som de känner. En 32B-modell som tar halva en sekund att starta känns seg jämfört med en 1.5B-modell som avlossar direkt.

class LatencyAwareRouter:
    def __init__(self):
        self.model_latencies = {
            "qwen2.5-1.5b": {"first_token": 0.05, "complete": 0.5},
            "qwen2.5-7b": {"first_token": 0.15, "complete": 2.0},
            "qwen2.5-32b": {"first_token": 0.5, "complete": 10.0},
            "claude-sonnet-4": {"first_token": 0.3, "complete": 5.0},
        }

    def route(self, target_latency: float) -> str:
        for model, latencies in sorted(
            self.model_latencies.items(),
            key=lambda x: x[1]["complete"]
        ):
            if latencies["complete"] <= target_latency:
                return model
        return "qwen2.5-1.5b"

Latenssiffrorna är ungefärliga – de beror på din hårdvara, kvantisering och batchstorlek. Mät på din egen miljö.

Återfallsstrategier

Modeller misslyckas. API:er begränsar hastigheten. Timeout-händelser inträffar. Mönstret som fungerar är en återfallskedja, sorterad från bäst till mest pålitlig:

class FallbackRouter:
    def __init__(self):
        self.fallback_chain = [
            {"model": "claude-sonnet-4", "timeout": 30},
            {"model": "qwen2.5-72b", "timeout": 60},
            {"model": "qwen2.5-32b", "timeout": 120},
            {"model": "qwen2.5-7b", "timeout": 300},
        ]

    def route_with_fallback(self, prompt: str) -> str:
        for config in self.fallback_chain:
            try:
                return self.call_model(
                    config["model"], prompt,
                    timeout=config["timeout"]
                )
            except (TimeoutError, APIError) as e:
                log.warning(f"Modell {config['model']} misslyckades: {e}")
                continue
        raise RuntimeError("Alla återfallsmodeller misslyckades")

Den sista modellen i kedjan bör vara lokal. Den är långsammare, men den kommer inte att misslyckas på grund av ett nätverksproblem eller en API-nyckel.

När ruttning hjälper

Ruttning ger mening när din arbetsbelastning är blandad. Om du gör klassificering, sammanfattning och resonemang i samma system sparar en ruttare pengar och latens.

Det ger inte mening när allt du gör har samma komplexitet. Använd bara modellen som är bra på den uppgiften. Ruttaren lägger till komplexitet du inte behöver.

Tidig prototypning är en annan anledning att hoppa över det. Få uppgiften att fungera med en modell, lägg sedan till ruttning när kostnad eller latens faktiskt blir ett problem.

Kompromisser

Varje ruttstrategi optimerar något och offrar något annat:

  • Enkel modell – enklast, dyrast, konsekvent kvalitet
  • Kapacitetsbaserad – bättre kostnad, högre kvalitet per uppgift, måttlig komplexitet
  • Kostnadsmedveten – billigast, varierande kvalitet, måttlig komplexitet
  • Latensmedveten – snabbast, kan offra kvalitet, måttlig komplexitet
  • Hybrid – bäst av allt, mest komplex att implementera

Produktionssystem konvergerar oftast mot hybrid. Börja med kapacitetsbaserad ruttning, lägg till kostnadsmedvetenhet när räkningen kommer, lägg till latensmedvetenhet när användare klagar över långsamhet.

Relaterat

Prenumerera

Få nya inlägg om system, infrastruktur och AI-ingenjörskonst.