Tryb routera Llama-Server – dynamiczne przełączanie modeli bez restartu

Serwuj i przełączaj modele LLM bez restartów.

Page content

Przez długi czas llama.cpp miała rażący ograniczenie:
można było obsłużyć tylko jeden model na proces, a przełączanie wymagało ponownego uruchomienia.

Ta epoka dobiegła końca.

Ostatnie aktualizacje wprowadziły tryb routera w llama-server, co przyniosło coś znacznie bliższego temu, czego ludzie oczekują od nowoczesnych lokalnych środowisk uruchomieniowych LLM:

  • dynamiczne ładowanie modeli
  • odciążanie na żądanie
  • przełączanie dla każdego żądania
  • brak konieczności ponownego uruchamiania procesu

llm router on the table

Innymi słowy: zachowanie podobne do Ollamy, ale bez kółek zapomagających.

Jeśli wciąż wahasz się między lokalnymi środowiskami uruchomieniowymi, API chmurowymi a samodzielnie hostowaną infrastrukturą, ogólny przegląd hostingu LLM jest dobrym punktem wyjścia.


Wymagania wstępne

Tryb routera wymaga najnowszej wersji llama-server — mniej więcej z pośrodku 2024 r. Starsze wersje nie mają flag --models-preset ani --models-dir.

Opcje instalacji (menedżer pakietów, wstępnie skompilowane binaria lub pełna kompilacja z kodu źródłowego z CUDA) są opisane w quickstarcie llama.cpp.

Gdy już masz llama-server, upewnij się, że Twoja wersja obsługuje tryb routera:

llama-server --help | grep -i models

Jeśli pojawiają się --models-preset lub --models-dir, wszystko jest w porządku. Jeśli ich brakuje, zaktualizuj do nowszej wersji.

Moja bieżąca odpowiedź z pomocami dotyczącymi modeli:

-cl,   --cache-list                     show list of models in cache
                                        Prefix/Suffix/Middle) as some models prefer this. (default: disabled)
                                        models with dynamic resolution (default: read from model)
                                        models with dynamic resolution (default: read from model)
                                        embedding models (default: disabled)
--models-dir PATH                       directory containing models for the router server (default: disabled)
                                        (env: LLAMA_ARG_MODELS_DIR)
--models-preset PATH                    path to INI file containing model presets for the router server
                                        (env: LLAMA_ARG_MODELS_PRESET)
--models-max N                          for router server, maximum number of models to load simultaneously
                                        (env: LLAMA_ARG_MODELS_MAX)
--models-autoload, --no-models-autoload
                                        for router server, whether to automatically load models (default:
                                        (env: LLAMA_ARG_MODELS_AUTOLOAD)

Co faktycznie robi tryb routera

Tryb routera zamienia llama-server w dispatcher modeli.

Zamiast przypisywania do jednego modelu za pomocą -m, serwer:

  • startuje bez żadnego załadowanego modelu
  • otrzymuje żądanie wskazujące konkretny model
  • ładuje ten model, jeśli nie znajduje się jeszcze w pamięci
  • wykonuje inferencję
  • opcjonalnie odciąża model po odpowiedzi lub utrzymuje go w stanie gorącym dla następnego żądania

Kluczowa idea

Nie uruchamiasz już:

./llama-server -m model.gguf

Uruchamiasz:

./llama-server --models-preset models.ini --port 8080

I pozwalasz serwerowi zdecydować co załadować i kiedy, w oparciu o to, o co faktycznie prosi klient.

To ma znaczenie, ponieważ oznacza, że jeden trwały proces może obsługiwać całą flotę modeli, z klientami wybierającymi właściwy do zadania — model do kodowania, model do czatu, model do streszczania — bez żadnego nakładu na koordynację po Twojej stronie.


Konfiguracja: definiowanie modeli

Tutaj sprawy wciąż są nieco surowe.

Nie ma jeszcze w pełni stabilnego oficjalnego formatu, ale bieżące wersje obsługują definicje modeli w stylu INI za pomocą pliku konfiguracyjnego.

Przykładowy models.ini

[llama3]
model = /opt/models/llama-3-8b-instruct.Q5_K_M.gguf
ctx-size = 8192
ngl = 35
threads = 8

[mistral]
model = /opt/models/mistral-7b-instruct-v0.3.Q4_K_M.gguf
ctx-size = 4096
ngl = 20
threads = 8

[qwen]
model = /opt/models/qwen2.5-coder-7b-instruct.Q5_K_M.gguf
ctx-size = 16384
ngl = 35
threads = 8

Każda nazwa sekcji staje się identyfikatorem modelu, którego klienci używają w polu "model" swoich żądań API.

Kluczowe parametry konfiguracyjne

Parametr Czego dotyczy
model Bezpośrednia ścieżka do pliku GGUF
ctx-size Rozmiar okna kontekstowego w tokenach. Większe wartości zużywają więcej pamięci VRAM.
ngl Liczba warstw GPU offloadowanych. Ustaw na 0 dla tylko CPU; zwiększaj, aż osiągniesz limity VRAM.
threads Wątki CPU dla warstw pozostających na procesorze.

Wybór odpowiedniej wartości ngl zależy od dostępnej pamięci VRAM Twojej karty graficznej — w celu doboru sprzętu GPU i analizy opłacalności sprzętowej, przewodnik po sprzęcie obliczeniowym jest użytecznym odniesieniem. Aby obserwować zużycie pamięci VRAM na żywo podczas kalibracji, zobacz narzędzia do monitorowania GPU w Linuksie.

Uruchamianie serwera z konfiguracją

./llama-server --models-preset /opt/llama.cpp/models.ini --port 8080

Upewnij się, że serwer wystartował poprawnie:

curl http://localhost:8080/v1/models | jq '.data[].id'

Powinieneś zobaczyć każdą nazwę sekcji z Twojego models.ini jako identyfikator modelu.

Uwaga na temat stabilności

Interfejs konfiguracyjny INI jest wciąż w fazie rozwoju:

  • flagi mogą się zmieniać między commitami
  • niektóre parametry są rozpoznawane tylko przez specyficzne konfiguracje builda
  • dokumentacja nie nadąża za implementacją

Przypnij się do konkretnego commita llama.cpp, jeśli potrzebujesz odtwarzalności po ponownym uruchomieniu.


Używanie API: przełączanie modeli na żądanie

Gdy serwer działa, przełączanie modeli odbywa się przez standardowe zgodne z OpenAI API. Po prostu ustawiasz pole "model".

Lista zarejestrowanych modeli

curl http://localhost:8080/v1/models

Żądanie komplementacji — pierwszy model

curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama3",
    "messages": [
      {"role": "user", "content": "Explain router mode in one paragraph"}
    ]
  }'

Przełączenie na inny model — ten sam endpoint, ten sam port

curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen",
    "messages": [
      {"role": "user", "content": "Write a Python function that reads a CSV file"}
    ]
  }'

Serwer obsługuje cykl odciążania/ładowania transparentnie. Kod Twojego klienta się nie zmienia — zmienia się jedynie pole model.

Przykład w Pythonie

Jeśli używasz klienta Python openai:

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8080/v1", api_key="not-needed")

# Use the coding model
response = client.chat.completions.create(
    model="qwen",
    messages=[{"role": "user", "content": "Write a Go HTTP handler"}],
)
print(response.choices[0].message.content)

# Switch to the chat model — same client, different model name
response = client.chat.completions.create(
    model="llama3",
    messages=[{"role": "user", "content": "What is the capital of Australia?"}],
)
print(response.choices[0].message.content)

Co dzieje się wewnątrz

Gdy przychodzi żądanie dla qwen, a llama3 jest obecnie załadowany:

  1. llama3 jest odciążony z pamięci VRAM
  2. wagi qwen są odczytywane z dysku i ładowane do pamięci VRAM
  3. wykonywana jest inferencja
  4. kolejne żądanie decyduje, czy utrzymać qwen w załadowanym stanie, czy ponownie przestawić

To bezpośrednio odpowiada na powszechne pytanie:

Jak serwer lokalnych LLM może przełączać modele bez ponownego uruchomienia

Przez dynamiczne ładowanie modeli dla każdego żądania, a nie przez przypisywanie przy starcie.


Usługa Systemd: gotowe do produkcji wdrożenie

Utworzenie dedykowanego użytkownika i katalogów

sudo useradd --system --shell /usr/sbin/nologin --home-dir /opt/llama.cpp llm
sudo mkdir -p /opt/llama.cpp/models
sudo chown -R llm:llm /opt/llama.cpp

Skopiuj swoje binaria i konfigurację modeli w wyznaczone miejsce:

sudo cp build/bin/llama-server /opt/llama.cpp/
sudo cp models.ini /opt/llama.cpp/

/etc/systemd/system/llama-server.service

[Unit]
Description=Llama.cpp Router Server
After=network.target

[Service]
Type=simple
User=llm
WorkingDirectory=/opt/llama.cpp
ExecStart=/opt/llama.cpp/llama-server --models-preset /opt/llama.cpp/models.ini --port 8080
Restart=always
RestartSec=5

Environment=LLAMA_LOG_LEVEL=info

[Install]
WantedBy=multi-user.target

Włączanie i uruchamianie

sudo systemctl daemon-reload
sudo systemctl enable llama-server
sudo systemctl start llama-server

Weryfikacja i inspekcja logów

sudo systemctl status llama-server
journalctl -u llama-server -f

Po pomyślnym starcie zobaczysz linie wskazujące, że serwer nasłuchuje i rejestr modeli została załadowana. Szybka weryfikacja:

curl -s http://localhost:8080/v1/models | jq '.data[].id'

Teraz masz trwałą usługę z automatycznym ponownym uruchamianiem i scentralizowanym przełączaniem modeli — bez ręcznego zarządzania procesami. Jeśli chcesz zastosować ten sam wzorzec do innych binariów, hostowanie dowolnego wykonywalnego jako usługi w Linuksie omawia ogólne podejście.

Flaga --metrics w llama-server udostępnia endpoint zgodny z Prometheus. Dla dashboardów specyficznych dla llama.cpp, zapytań PromQL i reguł alertujących, zobacz przewodnik po monitorowaniu inferencji LLM. Dla szerszej konfiguracji obserwowalności, przewodnik po obserwowalności obejmuje cały stack.


Ograniczenia, które musisz zrozumieć

Tryb routera jest naprawdę przydatny, ale wiąże się z kompromisami, o których powinieneś wiedzieć, zanim będziesz na nim polegać w produkcji.

Tylko jeden model w pamięci naraz

Mimo że wiele modeli jest zdefiniowanych w models.ini, w danej chwili tylko jeden rezyduje w pamięci VRAM per worker. Przełączanie oznacza pełny cykl odciążenia i ponownego załadowania.

  • przełączanie oznacza ponowne załadowanie
  • skok opóźnienia jest nieunikiony
  • dla typowego modelu 7B w Q5, ponowne załadowanie może trwać 3–10 sekund, w zależności od prędkości dysku i przepustowości VRAM

To odpowiada na kolejne kluczowe pytanie:

Czy llama.cpp obsługuje serowanie wielu modeli jednocześnie

Nie do końca. Obsługuje wiele definicji, a nie jednoczesną rezydencję. Jeśli potrzebujesz dwóch modeli faktycznie załadowanych równolegle, potrzebujesz dwóch procesów na dwóch osobnych GPU.

Dla zmierzonych zużyć pamięci VRAM i tokenów na sekundę dla różnych rozmiarów modeli, benchmarki wydajności LLM obejmują pełny obraz. Dla liczb specyficznych dla llama.cpp na GPU 16 GB — modele gęste i MoE przy różnych rozmiarach kontekstu — zobacz benchmarki llama.cpp na 16 GB VRAM.

Brak inteligentnego cache’owania

W przeciwieństwie do Ollamy, która utrzymuje ciepły pool i wyrzuca modele na podstawie czasu ostatniego użycia:

  • nie ma automatycznej strategii wyrzucania modeli
  • brak tła pre-warming
  • brak kolejki priorytetowej dla często używanych modeli

Jeśli wysyłasz naprzemiennie żądania dla llama3 i mistral, każde pojedyncze żądanie wywołuje ponowne załadowanie. To jest fundamentalny koszt bycia bliżej metali.

Opóźnienia są nieprzewidywalne dla mieszanych obciążeń

Dobrze zachowujące się obciążenie używające jednego modelu konsekwentnie będzie szybkie. Obciążenie przeplatające wiele modeli będzie wolne. Zaplanuj logikę routingu klienta odpowiednio — grupuj żądania wg modelu tam, gdzie to możliwe.

Konfiguracja nie jest stabilna

Obsługa INI istnieje i działa w większości najnowszych buildów, ale nie jest w pełni ustandaryzowana. Nazwy flag i parametrów zmieniały się między wersjami. Jeśli aktualizujesz llama-server, przetestuj swój models.ini przeciwko nowemu buildowi przed wdrożeniem.


Llama.cpp vs Ollama

Tryb routera zawęża dawną lukę w cyklu życia w porównaniu z Ollamą — dynamiczne ładowanie i przełączanie na żądanie istnieją teraz natywnie w llama-server — ale jej nie zamyka. Zarządzanie pamięcią pozostaje podstawowe (brak polityki wyrzucania, brak ciepłego poola), stabilność konfiguracji jest wciąż eksperymentalna, a przełączanie między dwiema różnymi modelami zawsze płaci pełny koszt odciążenia i ponownego załadowania, w przeciwieństwie do opartej o TTL utrzymującej przy życiu Ollamy. W skrócie: tryb routera daje Ci maksymalną kontrolę i hackowalną bazę; Ollama daje Ci bardziej dopracowane, zdeterminowane doświadczenie z mniej konfiguracji.

Dla pełnego porównania parzystego — instalacja, zarządzanie modelami, rozmieszczenie GPU, kontrola KV cache, API, wydajność, tryby awaryjne i konkretne przyczyny wyboru jednego lub migracji między nimi — zobacz llama.cpp vs Ollama w 2026, co jest kanonicznym porównaniem między tymi dwoma środowiskami uruchomieniowymi na tej stronie.

Jeśli wybierasz Ollamę, ściągawka CLI Ollama obejmuje codzienne polecenia. Dla szerszego porównania, które zawiera również vLLM, LM Studio i LocalAI, zobacz jak porównują się różne lokalne środowiska uruchomieniowe w 2026.


Llama.cpp vs llama-swap

llama-swap jest zewnętrznym orkiestratorem, który znajduje się przed jednym lub więcej instancjami llama-server:

  • przechwytuje żądania i inspekcjonuje pole model
  • uruchamia odpowiedni proces llama-server dla tego modelu
  • zamyka bezczynne instancje po konfigurowalnym czasie oczekiwania
  • przekierowuje żądanie, gdy model jest gotowy

Dla praktycznej konfiguracji, zobacz quickstart llama-swap.

Kluczowa różnica

Aspekt tryb routera llama-swap
Wbudowane Tak Nie (osobne binaria)
Dojrzałość Eksperymentalne Bardziej stabilne
Elastyczność Ograniczona Wysoka
Warstwa kontroli Wewnętrzna Zewnętrzny proxy
Konfig per model Plik INI Plik YAML
Model procesowy Jeden proces Jeden proces per model

Kiedy używać llama-swap

llama-swap daje Ci izolację na poziomie procesów per model, co oznacza, że crash w jednej instancji modelu nie wpływa na inne. Pozwala też każdemu modelowi działać z całkowicie niezależnymi flagami llama-server.

Użyj go, jeśli potrzebujesz:

  • lepszej kontroli cyklu życia i izolacji
  • sprytniejszej logiki przełączania z konfigurowalnym czasem bezczynności
  • bardziej przewidywalnych opóźnień (każdy model ma ciepły proces po pierwszym załadowaniu)
  • stabilności produkcyjnej dzisiaj, a nie w przyszłości

Kiedy natywny tryb routera wystarczy

Użyj wbudowanego routera, jeśli chcesz:

  • zero zewnętrznych zależności
  • jednego procesu do zarządzania
  • prostszego wdrożenia (jedno binaria, jeden plik konfiguracyjny)
  • minimalnego stacka dla rozwoju lub ustawień użytkownika pojedynczego

Ostateczne przemyślenia

Tryb routera jest znaczącym krokiem naprzód dla llama-server.

Odpowiada na wieloletnie żądanie:

Czym jest tryb routera w serwerze llama.cpp

To jest brakująca warstwa, która zamienia statyczne binaria w dynamiczną usługę inferencji — jeden proces, który może obsługiwać żądania dla całego katalogu modeli.

Ale nie jest skończony.

Dziś jest:

  • wystarczająco potężny dla rzeczywistych obciążeń
  • obiecujący jako fundament dla bardziej wyrafinowanego routingu
  • nieco chropowaty na krawędziach konfiguracji i stabilności

Jeśli Twoje obciążenie jest przewidywalne i możesz grupować żądania wg modelu, tryb routera działa dobrze dziś. Jeśli potrzebujesz niezawodności na poziomie produkcyjnym i izolacji per model, sięgnij po llama-swap, podczas gdy natywna implementacja dojrzewa.

Gdy potrzebujesz uwolnić pamięć VRAM bez ponownego uruchamiania — dla benchmarku, okna serwisowego lub czystego resetu deweloperskiego — skryptyfikowanym podejściem jest wylądowanie listy załadowanych modeli i wywołanie endpointu odciążania dla każdego z nich. Pełen wzorzec curl-and-jq jest opisany w Odciąż wszystkich modeli routera llama.cpp bez ponownego uruchamiania.

W każdym przypadku otrzymujesz zachowanie podobne do Ollamy, bez ukrywania mechanizmów.

Subskrybuj

Otrzymuj nowe wpisy o systemach, infrastrukturze i inżynierii AI.