Files
LLM-Server/.env.example
T
haylanandClaude-Bot 23e90fe8fb fix(llama-server): cap concurrent slots at 2 to curb prefill contention
Default --parallel of 4 let concurrent subagent requests split GPU
compute, pushing large-context prefill past OmniRoute's stream-idle
timeout and triggering cancel-on-both-sides.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 11:26:30 +02:00

87 lines
4.9 KiB
Bash

# Copy to .env and adjust — or just run ./scripts/update.sh, which creates
# .env from this file and fills in every secret/key below it can generate
# itself (see each var's comment). All values below are defaults baked into
# docker-compose.yml — only uncomment/change what you actually want to
# override.
# --- llama.cpp / model ---
LLAMA_MODEL_FILE=Qwen3.8-27B-UD-Q4_K_XL.gguf
# 999 = every layer on GPU (this model is dense, not MoE, and already fits
# fully in 32GB VRAM — see docs/research/qwen3.8-27b-quant.md). Lower this
# to leave that many fewer layers on GPU and push the rest to CPU/system RAM
# if something else is contending for VRAM — llama.cpp has no separate
# "RAM offload" flag, --n-gpu-layers *is* the RAM-offload knob for a dense
# model. Don't reach for --n-cpu-moe/--cpu-moe/--override-tensor "exps" —
# those target Mixture-of-Experts models (e.g. Qwen3.8-2.4T-A95B), not this
# one, and are no-ops here.
# There's no separate "then SSD" tier to enable either: llama.cpp mmaps the
# model file by default (no --no-mmap here), so if GPU+RAM ever can't hold
# the working set, the OS pages the rest in from disk automatically — an
# implicit, slow last resort, not a config knob. An explicit tiered SSD
# offload has been an open llama.cpp feature request since 2025 (still
# unimplemented): https://github.com/ggml-org/llama.cpp/discussions/12507
LLAMA_GPU_LAYERS=999
# 262144 = this model's true max (max_position_embeddings in Qwen/Qwen3.8-27B's
# config.json) — the largest --ctx-size llama.cpp will even accept for it.
# fp16 KV cache at full context is ~16GB (262,144 x 64KiB/token), on top of
# 17.6GB weights = ~33.6GB, which does NOT fit the 32GB R9700 — expect
# llama-server to fail to allocate and refuse to start at this setting.
# Chosen anyway per explicit request to run at the model's real ceiling
# rather than a VRAM-safe value. To actually get a working max: quantize the
# KV cache (--cache-type-k/v q8_0, roughly halves it to ~8GB, fits with room
# to spare) or drop back to 131072 (128K), the last known-good value
# (~25.6GB total, ~6GB headroom) — see docs/research/qwen3.8-27b-quant.md.
LLAMA_CTX_SIZE=262144
# Concurrent request slots. Was implicitly 4 (llama.cpp's compiled-in
# default) with no flag set — under concurrent subagent fan-out, 4 requests
# split the same GPU compute, so a large-context prefill can queue behind
# others long enough to blow past OmniRoute's stream-idle timeout, which then
# cancels the request (see issue-tracker notes on the timeout/cancel loop).
# Dropped to 2 so each slot gets more compute and finishes prefill sooner;
# raise back toward 4 if throughput (not latency) becomes the bottleneck
# instead.
LLAMA_PARALLEL=2
# --- Lazytainer ---
# Seconds of inactivity before llama-server is stopped. 900 = 15 min.
LAZYTAINER_INACTIVE_TIMEOUT=900
# --- SearXNG web search (see docs/research/litellm-searxng-search.md) ---
# Resolved automatically by ./scripts/update.sh from search.home on this
# host — leave blank. Only set by hand if that resolution fails (e.g.
# search.home isn't a static DHCP reservation and its IP drifted).
SEARXNG_LAN_IP=
# --- OmniRoute gateway (see docs/proxy-key-onboarding.md, docs/network-access.md) ---
# OMNIROUTE_PORT is the host-published port (reverse-proxied by NPM) — kept
# at 4000, same as the old LiteLLM setup, so existing NPM/firewall config
# doesn't need to change. It's mapped via plain Docker port publishing onto
# API_PORT, omniroute's own container-internal port (left at its default,
# not reconfigured to match). The dashboard (DASHBOARD_PORT) is never
# published at all — see docker-compose.yml's omniroute service comment.
OMNIROUTE_API_PORT=20129
OMNIROUTE_DASHBOARD_PORT=20128
# Random values, filled in automatically by ./scripts/update.sh — leave
# blank. Bootstrap dashboard admin password (log in at the dashboard port,
# change it there afterwards — this is only the first-boot value):
OMNIROUTE_INITIAL_PASSWORD=
# Signs dashboard session cookies:
OMNIROUTE_JWT_SECRET=
# Encrypts API key values at rest in omniroute's SQLite DB:
OMNIROUTE_API_KEY_SECRET=
# Encrypts the whole SQLite DB at rest. Do not change after first run —
# existing encrypted data becomes unreadable if you do (same caveat as
# LiteLLM's old LITELLM_SALT_KEY):
OMNIROUTE_STORAGE_ENCRYPTION_KEY=
# Per-deployment salts — random is fine, just needs to be stable:
OMNIROUTE_MACHINE_ID_SALT=
OMNIROUTE_CLI_SALT=
# Required (production) — shared secret for the internal Codex Responses
# WebSocket bridge. Random value, filled in automatically:
OMNIROUTE_WS_BRIDGE_SECRET=
# Per-workload virtual keys (one per client that calls the gateway) have no
# scripted /key/generate equivalent yet — omniroute's key-creation endpoint
# needs a dashboard login session, not a static bearer key (see issue #37).
# Mint them by hand in the dashboard, add a KEY=value line here per workload
# as you onboard one. See docs/proxy-key-onboarding.md.