Initial import: bare-metal stacks, Server UI, GPU fan, tutorials.

Infrastructure configs for GMKtec K11 (Docker, vLLM, LocalAI, ComfyUI,
control-plane, gpu-fan agent, Server UI with CLI/file explorer/GPU fan curve).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
tomasz-syn-grzegorza
2026-07-05 12:02:04 +00:00
commit 359afb3a59
153 changed files with 18169 additions and 0 deletions
+182
View File
@@ -0,0 +1,182 @@
# vLLM stack
Serwer inference vLLM z API kompatybilnym z OpenAI. **Brak panelu UI** — konfiguracja przez plik `.env`, profile i katalog modeli.
## Jak to działa
```mermaid
flowchart LR
client["Klient curl / OpenAI SDK"]
api["vLLM :8000 /v1/*"]
gpu["RTX 3090 Ti"]
data["/data/apps/vllm/huggingface"]
client --> api
api --> gpu
api --> data
```
| Element | Opis |
|---------|------|
| Obraz | `vllm/vllm-openai` |
| Port | `8000` (OpenAI-compatible) |
| Konfiguracja | `.env` + profile + `models.catalog.yaml` |
| Modele vLLM | Hugging Face AWQ → `/data/apps/vllm/huggingface` |
| Modele GGUF | Katalog + `/data/apps/gguf/` → przyszły [`stacks/llamacpp/`](../llamacpp/) |
| UI | **Brak** — opcjonalnie Open WebUI w przyszłości |
## GGUF vs AWQ (ważne)
| Źródło | Format | Runtime |
|--------|--------|---------|
| [lmstudio-community GGUF](https://huggingface.co/lmstudio-community) | `.gguf` Q4 | **llama.cpp** (planowany) |
| Hugging Face AWQ | safetensors INT4 | **vLLM** (teraz) |
Standardowy `vllm/vllm-openai` **nie ładuje plików `.gguf`**. Linki GGUF z katalogu są pod przyszły host llama.cpp. Na vLLM używamy `Qwen/Qwen3.6-27B-Instruct-AWQ` jako odpowiednika Q4.
vLLM = **jeden model w VRAM** na kontener. Kilka modeli może leżeć na dysku — przełączanie = zmiana profilu + restart.
## Mapowanie z LM Studio / Ollama
| LM Studio / Ollama | vLLM |
|--------------------|------|
| Model GGUF Q4 (lmstudio) | AWQ z HF + `QUANTIZATION=awq` (interim) |
| K Cache Q4_0 | `KV_CACHE_DTYPE=fp8` |
| V Cache Q4_0 | j.w. — vLLM nie ma flagi `Q4_0` |
| Context 128K | `MAX_MODEL_LEN=131072` |
| 1 wątek / 1 request | `MAX_NUM_SEQS=1` |
| GPU layers max | `GPU_MEMORY_UTILIZATION=0.95` |
Docelowo GGUF + natywne K/V `q4_0`: [`stacks/llamacpp/README.md`](../llamacpp/README.md).
## Struktura katalogów
```
stacks/vllm/
├── README.md
├── models.catalog.yaml # lista modeli (bez auto-pobierania)
├── docker-compose.yml
├── .env.example
├── profiles/
│ ├── _template.env
│ └── qwen3.6-27b-awq-128k.env
└── scripts/
├── catalog-lib.sh
├── list-models.sh
├── download-model.sh
├── switch-model.sh
├── start.sh
└── vllm-entrypoint.sh
```
Na dysku `/data`:
```
/data/apps/
├── vllm/huggingface/ # cache HF (AWQ)
└── gguf/ # przyszłe GGUF (puste katalogi tworzone przez skrypty)
├── qwen3.6-27b/
└── gemma-4-12b/
```
## Model catalog
Plik `models.catalog.yaml` zawiera modele docelowe (GGUF) i interim (vLLM AWQ). **Nic nie pobiera się przy instalacji.**
```bash
./scripts/list-models.sh
```
| ID | Runtime | Opis |
|----|---------|------|
| `qwen3.6-27b-q4-gguf` | llamacpp | Qwen3.6-27B Q4_K_M z lmstudio-community |
| `gemma-4-12b-q4-gguf` | llamacpp | Gemma 4 12B Q4_0 (+ mmproj) |
| `qwen3.6-27b-awq-vllm` | vllm | AWQ interim — użyj teraz |
## Workflow
### 1. Przygotuj stack (bez modelu)
```bash
cd /home/tomasz-syn-grzegorza/cursor/ubuntu-bare-metal/stacks/vllm
cp .env.example .env
```
### 2. Zobacz katalog
```bash
./scripts/list-models.sh
```
### 3. Pobierz model na żądanie
```bash
# vLLM interim (AWQ → cache HF)
./scripts/download-model.sh qwen3.6-27b-awq-vllm
# później — GGUF do /data/apps/gguf (dla llama.cpp)
# ./scripts/download-model.sh qwen3.6-27b-q4-gguf
```
### 4. Przełącz profil i uruchom
```bash
./scripts/switch-model.sh qwen3.6-27b-awq-128k
# lub pierwszy start:
./scripts/start.sh qwen3.6-27b-awq-128k
```
`start.sh` odrzuca `.gguf` w `VLLM_MODEL` i wskazuje katalog.
### 5. Logi i test
```bash
docker compose --profile vllm logs -f vllm
curl -s http://localhost:8000/v1/models | jq .
```
## Switching models (A / B na dysku)
1. Model B może już być pobrany (`download-model.sh`) — leży na dysku, nie w VRAM.
2. Przełącz profil: `./scripts/switch-model.sh <profile>` — kopiuje profil → `.env`, restartuje kontener.
3. Tylko **jeden** model aktywny w VRAM naraz.
Nowy profil vLLM: skopiuj `profiles/_template.env`, dostosuj `VLLM_EXTRA_ARGS` i `QUANTIZATION`.
## Zmienne `.env`
| Zmienna | Opis | Domyślnie |
|---------|------|-----------|
| `VLLM_MODEL` | **Wymagane** — ID modelu Hugging Face | *(pusty)* |
| `SERVED_MODEL_NAME` | Nazwa w API | `qwen3.6-27b` |
| `MAX_MODEL_LEN` | Okno kontekstu (tokeny) | `131072` (128K) |
| `MAX_NUM_SEQS` | Równoległe sekwencje | `1` |
| `GPU_MEMORY_UTILIZATION` | % VRAM dla vLLM | `0.95` |
| `KV_CACHE_DTYPE` | Kwantyzacja KV cache | `fp8` |
| `QUANTIZATION` | Typ kwantyzacji wag (`awq` lub pusty) | `awq` |
| `VLLM_EXTRA_ARGS` | Dodatkowe flagi vLLM (spacje) | `--language-model-only --enforce-eager --reasoning-parser qwen3` |
| `DATA_ROOT` | Mount dysku danych | `/data` |
| `HF_TOKEN` | Token Hugging Face (gated) | *(pusty)* |
`QUANTIZATION` puste = model pełnej precyzji (bez `--quantization`). Flagi buduje `scripts/vllm-entrypoint.sh`.
## Tuning po OOM
1. `MAX_MODEL_LEN=98304` lub `65536`
2. `GPU_MEMORY_UTILIZATION=0.90`
3. `KV_CACHE_DTYPE=turboquant_k8v4`
## Zarządzanie
```bash
docker compose --profile vllm ps
docker compose --profile vllm logs -f vllm
docker compose --profile vllm restart vllm
docker compose --profile vllm down
```
## Dokumentacja
Pełny tutorial: [manual-tutorial/04-vllm-stack.md](../../manual-tutorial/04-vllm-stack.md) (część B).
GGUF (planowany): [stacks/llamacpp/README.md](../llamacpp/README.md).