Keep only README, LICENSE, and CHANGELOG as prose at the repo root (tooling/convention) and move the remaining manuals under docs/ next to SECURITY_AND_OPERATIONS.md. - git mv the two files into docs/ (history preserved). - Update all cross-references: README doc-index links, the internal SECURITY_AND_OPERATIONS link and the §12 pointer list in BEDIENUNGSANLEITUNG, and the repo inventory in SECURITY_AND_OPERATIONS §1. - build_archive.py: point REQUIRED_FILES at docs/ and drop the now-redundant INCLUDE_FILES entries (the docs/ dir is included wholesale). - build_archive.py: drop the obsolete requirements.txt<->pyproject dependency mirror check, which broke once requirements.txt was reduced to `.` (pyproject is the single source of truth). Verified by building and re-opening the archive. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
10 KiB
Bedienungsanleitung — llamacppctl
llamacppctl startet, prüft, stoppt, wechselt und promptet einen
llama.cpp-Server, der als Docker-Container läuft — über eine CLI statt
mehrerer Shell-Skripte. Die OpenAI-kompatible API des Servers ist standardmäßig
nur auf 127.0.0.1 erreichbar.
Diese Anleitung deckt Installation und Benutzung vollständig ab. Zur
Installation aus dem fertigen Archiv siehe zusätzlich
INSTALL_FROM_ARCHIVE.md. Details zum Sicherheits-
und Betriebsmodell stehen in SECURITY_AND_OPERATIONS.md;
die vollständige Optionsreferenz in der Manpage (man/llamacppctl.1).
1. Voraussetzungen
- Docker (Daemon läuft, Nutzer in der
docker-Gruppe):docker versionmuss funktionieren. - NVIDIA-GPU + Treiber + NVIDIA Container Toolkit (damit
--gpusim Container greift):nvidia-smifunktioniert, unddocker run --rm --gpus all <cuda-image> nvidia-smizeigt die GPU. - Python ≥ 3.10.
- Ein GGUF-Modell auf dem Host, das read-only in den Container gemountet wird.
- Das Docker-Image, z. B.
ghcr.io/ggml-org/llama.cpp:server-cuda(wird beim ersten Start automatisch gezogen).
2. Installation
2.1 Aus dem Quellcode (empfohlen für Entwicklung)
cd llamacppctl
python3 -m venv .venv
source .venv/bin/activate
pip install -e . # editable: CLI == Quellcode in src/
# optional für Tests:
pip install -e ".[dev]"
Wichtig: Bei
pip install .(ohne-e) läuft das CLI aus einer Kopie insite-packages— Änderungen ansrc/wirken dann NICHT. Für Entwicklung immer-everwenden. Kontrolle:python -c "import llamacppctl.actions as a; print(a.__file__)"muss aufsrc/zeigen.
2.2 Aus dem Archiv
Siehe INSTALL_FROM_ARCHIVE.md.
2.3 Installation prüfen (ohne Docker)
llamacppctl --help
llamacppctl --print-effective-config --config llama.cpp.config --start --dry-run
3. Konfiguration
3.1 Datei anlegen
cp llama.cpp.config.example llama.cpp.config
# llama.cpp.config an den Host anpassen (Pfade, GPU, Ports)
Der Standard-Pfad ist llama.cpp.config im aktuellen Verzeichnis, überschreibbar
mit --config <pfad>.
3.2 Aufbau (INI)
[default]— globale Werte, überschreiben die eingebauten Defaults.[model.<name>]— ein Modell-Profil, gewählt mit--profile <name>.[prompt.<name>]— ein Fallback-Systemprompt, gewählt mit--system-prompt-profile <name>(ein explizites-s/--system-file/--system-urlgewinnt immer).
Auflösungsreihenfolge (niedrig → hoch): eingebaute Defaults → [default] →
[model.<profile>] → CLI-Overrides.
3.3 Wichtige Felder
| Feld / CLI | Bedeutung |
|---|---|
image / --image |
Docker-Image (z. B. ghcr.io/ggml-org/llama.cpp:server-cuda) |
hf_home / --hf-home |
Host-Verzeichnis, read-only gemountet. Env-Variablen erlaubt, z. B. hf_home = ${HF_HOME} |
model_path / --model-path |
Modellpfad, relativ zu hf_home (oder absolut) |
container_name / --container-name |
Pflicht, eindeutig pro parallel laufendem Profil (Identitätsanker für Naming/Lock/Stop/Check) |
host_port / --host-port |
Host-Port (1–65535) |
container_port / --container-port |
Container-interner Port |
model_alias / --model-alias |
Modell-Alias in der API |
gpu_device / --gpu |
GPU-Device für --gpus device=<id> (auch mehrere: 1,2) |
ctx_size / --ctx-size |
Kontextfenster (KV-Cache wächst damit) |
n_predict / --n-predict |
Server-seitige max. Vorhersage-Tokens |
temp, top_p, top_k, min_p, repeat_penalty |
Sampling (beim Start in den Container gebacken) |
expose / --expose / --no-expose |
Port auf allen Interfaces (LAN) statt nur 127.0.0.1. Default: aus |
api_key / --api-key |
API-Key: Server verlangt ihn, Tool sendet ihn als Bearer-Token |
max_tokens / --max-tokens |
Antwortbudget für --chat/--start-Antwort (Default 2048) |
chat_temperature / --chat-temp |
Temperatur des Chat-Requests (leer = Server-temp) |
timeout / --timeout |
Readiness-Timeout in Sekunden |
reasoning / --reasoning {on,off} |
Reasoning-Modus |
Boolean-Schalter mit Paar-Form: --jinja/--no-jinja, --fa/--no-fa,
--kv-unified/--no-kv-unified, --cont-batching/--no-cont-batching,
--no-context-shift/--context-shift.
3.4 Beispiel
[default]
image = ghcr.io/ggml-org/llama.cpp:server-cuda
hf_home = ${HF_HOME}
model_path = models/qwen3/mein-modell-Q4_K_M.gguf
model_alias = mein_llm
container_name = llama_cpp_server
host_port = 8001
gpu_device = 1
ctx_size = 65536
max_tokens = 8192
[prompt.knapp]
system_prompt = Antworte kurz, präzise und technisch.
[model.zweitmodell]
model_path = models/qwen3/anderes-modell.gguf
model_alias = zweit_llm
container_name = llama_cpp_zweit
host_port = 8002
gpu_device = 2
4. Die fünf Aktionen
Genau eine Aktion pro Aufruf ist erforderlich.
--start — Server starten
Entfernt einen vorhandenen Container gleichen Namens, startet neu, wartet per echter Chat-Completion auf Readiness (nicht nur offener Port). Läuft unter Lock.
llamacppctl --start
llamacppctl --start --profile zweitmodell
llamacppctl --start -p "Sag kurz Hallo." # + Testantwort nach dem Start
llamacppctl --start --dry-run # nur das docker-run-Kommando zeigen
--check — Status prüfen
Zeigt Container-/HTTP-Status; mit User-Prompt zusätzlich eine echte Chat-Probe. Scriptbar: Exit 0 = läuft & erreichbar, sonst 5.
llamacppctl --check
llamacppctl --check -p "ping" && echo "OK" || echo "nicht bereit"
--stop — Container stoppen und entfernen
llamacppctl --stop
llamacppctl --stop --force # auch bei Inkonsistenzen entfernen
--change — Modell/Config wechseln
Stoppt, konfiguriert neu, startet — unter Lock. Validiert den Modellpfad, bevor der laufende Container entfernt wird (kein unnötiger Ausfall).
llamacppctl --change --profile zweitmodell
llamacppctl --change --model-path models/qwen3/neues-modell.gguf --ctx-size 32768
--chat — an laufenden Server prompten
llamacppctl --chat -p "Was ist 2+2?"
llamacppctl --chat -s "Du antwortest nur mit Zahlen." -p "Wie viel ist 6*7?"
llamacppctl --chat --stream -p "Schreibe eine kurze Geschichte."
5. Prompts (System & User)
Pro Feld genau eine Quelle:
| System-Prompt | User-Prompt | Quelle |
|---|---|---|
-s, --system |
-p, --prompt |
Literaler Text |
--system-file |
--prompt-file |
Lokale Datei (nur reguläre Dateien, UTF-8, Größenlimit) |
--system-url |
--prompt-url |
HTTPS-URL (SSRF-gehärtet) |
llamacppctl --chat --system-file ./prompts/reviewer.md --prompt-file ./frage.txt
llamacppctl --start --system-prompt-profile knapp -p "Erkläre Backups."
URL-Quellen sind standardmäßig HTTPS-only, blockieren private/loopback/metadata-
IPs und Redirects; Details in docs/SECURITY_AND_OPERATIONS.md.
6. Antwortsteuerung & Reasoning
--max-tokens N— Budget der Antwort (Default 2048).--chat-temp F— Temperatur des Requests (sonst gilt die Server-temp).--stream— Tokens live auf stdout, während sie generiert werden.
Reasoning-Modelle (z. B. Qwen3.x mit
reasoning = on) „denken" erst intern (oft mehrere tausend Tokens) und geben dann die eigentliche Antwort. Ist--max-tokenszu klein, endet die Generierung im Denken und der sichtbarecontentbleibt leer — das Tool warnt dann (finish_reason=length). Für lange Texte großzügig setzen (z. B.--max-tokens 8000).
7. Netzwerk & Sicherheit (Kurz)
- Der Port wird per Default nur auf
127.0.0.1veröffentlicht — die unauthentifizierte API ist nicht im LAN erreichbar. - Für LAN-Zugriff:
--expose/expose = true. Dann unbedingt--api-key/api_keysetzen. - Mit Key schützt llama.cpp
/v1/chat/completions(ohne Key → 401);/healthund/v1/modelsbleiben bewusst offen (für Health-Checks). hf_homewird read-only gemountet; alle Docker-Aufrufe nutzen Argumentlisten (keine Shell-Injection).
8. GPU & Kontextgröße
- Ein Modell muss samt KV-Cache in den GPU-Speicher passen. Der KV-Cache wächst
linear mit
ctx_sizeund wird beim Laden komplett allokiert. - Mehrere GPUs:
gpu_device = 1,2(bzw.--gpu 1,2) verteilt das Modell. - Vor einer Änderung mit
--dry-rundas Kommando prüfen, mit--print-effective-configdie aufgelösten Werte kontrollieren.
9. Exit-Codes
| Code | Bedeutung |
|---|---|
| 0 | Erfolg (bzw. --check: läuft & erreichbar) |
| 1 | Allgemeiner Fehler / leere Antwort trotz Budget |
| 2 | CLI-/Argument-Fehler |
| 3 | Modelldatei nicht gefunden |
| 4 | Docker-Fehler |
| 5 | HTTP/Readiness nicht bereit (auch --check, wenn nicht erreichbar) |
| 6 | Lock belegt (anderer --start/--change läuft; ggf. --force) |
10. Fehlersuche
| Symptom | Ursache | Lösung |
|---|---|---|
docker is not available on PATH |
Docker-CLI/-Daemon fehlt | Docker installieren/starten, Nutzer in docker-Gruppe |
model file not found: … |
model_path/hf_home falsch |
Pfade prüfen; ${HF_HOME} gesetzt? |
Server did not become ready within <n>s |
Modell lädt langsam / OOM | --timeout erhöhen, --logs für Log-Tail, ggf. ctx_size senken |
Leere Antwort + Hinweis finish_reason=length |
Reasoning verbraucht das Budget | --max-tokens erhöhen |
HTTP 401: Invalid API Key |
Server verlangt Key | --api-key/api_key passend setzen |
lock busy: … |
Paralleler --start/--change |
warten oder --force (hängender Lock) |
--check zeigt health=unhealthy, Server antwortet aber |
bildeigener Docker-Healthcheck ≠ HTTP-Probe | unkritisch: HTTP: OK + Exit 0 zählt |
11. Tests
pip install -e ".[dev]"
pytest -q # Unit-Tests (kein Docker nötig)
End-to-End gegen einen echten Server (opt-in, braucht Docker + GPU + Modell):
SMOKE_GPU=1 scripts/smoke.sh
12. Weiterführend
man/llamacppctl.1— vollständige Optionsreferenz (man ./man/llamacppctl.1).docs/SECURITY_AND_OPERATIONS.md— Architektur, Sicherheits- und Betriebsmodell.README.md— Kurzüberblick.docs/INSTALL_FROM_ARCHIVE.md— Installation aus dem.tar.gz-Archiv.