359afb3a59
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>
316 lines
7.4 KiB
Markdown
316 lines
7.4 KiB
Markdown
# 05 — LocalAI stack
|
||
|
||
> **Cel rozdziału:** uruchomić [LocalAI](https://github.com/mudler/LocalAI) w Dockerze z GPU (CUDA 13), wbudowanym UI na porcie **8070** i pustym katalogiem modeli. Modele dodasz później (GGUF, galeria).
|
||
|
||
**Szacowany czas:**
|
||
- Pobranie obrazu Docker: 10–30 minut
|
||
- Start bez modelu: 1–2 minuty
|
||
|
||
**Wymagania:** ukończone rozdziały [01](01-system-update-and-docker.md)–[04](04-vllm-stack.md) (część A — dysk `/data` zamontowany)
|
||
|
||
---
|
||
|
||
## Spis treści
|
||
|
||
1. [LocalAI vs vLLM](#1-localai-vs-vllm)
|
||
2. [Porty i architektura](#2-porty-i-architektura)
|
||
3. [Struktura plików stacku](#3-struktura-plików-stacku)
|
||
4. [Przygotowanie `.env`](#4-przygotowanie-env)
|
||
5. [Clone upstream (opcjonalnie)](#5-clone-upstream-opcjonalnie)
|
||
6. [Instalacja obrazu (bez modelu)](#6-instalacja-obrazu-bez-modelu)
|
||
7. [Start stacku](#7-start-stacku)
|
||
8. [Weryfikacja UI i API](#8-weryfikacja-ui-i-api)
|
||
9. [Zarządzanie stackiem](#9-zarządzanie-stackiem)
|
||
10. [Troubleshooting](#10-troubleshooting)
|
||
11. [Następny krok](#11-następny-krok)
|
||
|
||
---
|
||
|
||
## 1. LocalAI vs vLLM
|
||
|
||
| | vLLM (`stacks/vllm/`) | LocalAI (`stacks/localai/`) |
|
||
|--|----------------------|----------------------------|
|
||
| UI | Brak (tylko API) | **Wbudowany chat w przeglądarce** |
|
||
| Port | 8000 | **8070** (host) → 8080 (kontener) |
|
||
| Modele skwantyzowane | AWQ / HF (nie GGUF) | **GGUF, AWQ**, wiele backendów |
|
||
| Ten krok | Obraz pobrany, bez modelu OK | Start **bez modelu** — pusty `/models` |
|
||
|
||
Oba stacki mogą współistnieć na dysku, ale **nie ładuj dużych modeli na GPU równocześnie** (24 GB VRAM).
|
||
|
||
---
|
||
|
||
## 2. Porty i architektura
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
browser["Przeglądarka :8070"]
|
||
curl["curl / OpenAI SDK"]
|
||
localai["Kontener localai"]
|
||
gpu["RTX 3090 Ti"]
|
||
disk["/data/apps/localai/models"]
|
||
|
||
browser --> localai
|
||
curl --> localai
|
||
localai --> gpu
|
||
localai --> disk
|
||
```
|
||
|
||
| Element | Wartość |
|
||
|---------|---------|
|
||
| Obraz | `localai/localai:v4.4.3-gpu-nvidia-cuda-13` |
|
||
| UI + API (LAN / tunel) | `http://127.0.0.1:8070` lub publicznie przez NPMPlus (rozdział 07) |
|
||
| Modele | `/data/apps/localai/models` |
|
||
| Docker data | `/data/docker` |
|
||
|
||
---
|
||
|
||
## 3. Struktura plików stacku
|
||
|
||
```
|
||
stacks/localai/
|
||
├── README.md
|
||
├── docker-compose.yml
|
||
├── .env.example
|
||
├── .gitignore
|
||
├── upstream/ # opcjonalny shallow clone (gitignored)
|
||
└── scripts/
|
||
├── clone-upstream.sh
|
||
├── pull.sh
|
||
└── start.sh
|
||
```
|
||
|
||
Katalogi na dysku 1 TB (tworzone przez skrypty):
|
||
|
||
```
|
||
/data/apps/localai/
|
||
├── models/
|
||
├── backends/
|
||
├── configuration/
|
||
├── images/
|
||
└── data/
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Przygotowanie `.env`
|
||
|
||
```bash
|
||
cd /home/tomasz-syn-grzegorza/cursor/ubuntu-bare-metal/stacks/localai
|
||
cp .env.example .env
|
||
cat .env
|
||
```
|
||
|
||
Oczekiwane:
|
||
|
||
```env
|
||
DATA_ROOT=/data
|
||
LOCALAI_PORT=8070
|
||
LOCALAI_API_KEY=your-secret-key
|
||
LOCALAI_IMAGE=localai/localai:v4.4.3-gpu-nvidia-cuda-13
|
||
CUDA_VISIBLE_DEVICES=0
|
||
DEBUG=false
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Clone upstream (opcjonalnie)
|
||
|
||
Shallow clone repozytorium GitHub — **tylko referencja** (przykładowe YAML modeli). Runtime idzie z oficjalnego obrazu Docker, nie z buildu lokalnego.
|
||
|
||
```bash
|
||
./scripts/clone-upstream.sh
|
||
```
|
||
|
||
Powstaje `stacks/localai/upstream/` (ignorowane przez git).
|
||
|
||
---
|
||
|
||
## 6. Instalacja obrazu (bez modelu)
|
||
|
||
Pobiera wyłącznie obraz Docker — **nie startuje kontenera**, **nie pobiera modeli LLM**.
|
||
|
||
```bash
|
||
./scripts/pull.sh
|
||
```
|
||
|
||
Alternatywa ręczna:
|
||
|
||
```bash
|
||
docker compose --profile localai pull
|
||
```
|
||
|
||
Weryfikacja:
|
||
|
||
```bash
|
||
docker images | grep localai
|
||
docker compose --profile localai ps
|
||
```
|
||
|
||
Oczekiwane: obraz widoczny, kontener **nie** działa.
|
||
|
||
---
|
||
|
||
## 7. Start stacku
|
||
|
||
```bash
|
||
./scripts/start.sh
|
||
```
|
||
|
||
Skrypt sprawdza: `/data` zamontowany, Docker działa, tworzy katalogi w `/data/apps/localai/`.
|
||
|
||
Logi:
|
||
|
||
```bash
|
||
docker compose --profile localai logs -f localai
|
||
```
|
||
|
||
---
|
||
|
||
## 8. Weryfikacja UI i API
|
||
|
||
### 8.1 Health check
|
||
|
||
```bash
|
||
curl -s http://localhost:8070/readyz
|
||
```
|
||
|
||
Oczekiwane: odpowiedź HTTP 200 (tekst potwierdzający gotowość).
|
||
|
||
### 8.2 UI w przeglądarce
|
||
|
||
Otwórz na swoim PC (z sieci LAN):
|
||
|
||
```
|
||
http://127.0.0.1:8070
|
||
```
|
||
|
||
Adres IP serwera:
|
||
|
||
```bash
|
||
hostname -I | awk '{print $1}'
|
||
```
|
||
|
||
UI powinno się załadować — lista modeli będzie **pusta** (to OK na tym etapie).
|
||
|
||
### 8.3 API (opcjonalnie)
|
||
|
||
```bash
|
||
curl -s http://localhost:8070/v1/models -H "Authorization: Bearer $LOCALAI_API_KEY" | jq .
|
||
```
|
||
|
||
Pusta lista modeli — normalne bez pobranego modelu.
|
||
|
||
---
|
||
|
||
## 9. Zarządzanie stackiem
|
||
|
||
```bash
|
||
cd /home/tomasz-syn-grzegorza/cursor/ubuntu-bare-metal/stacks/localai
|
||
|
||
docker compose --profile localai ps
|
||
docker compose --profile localai logs -f localai
|
||
docker compose --profile localai restart localai
|
||
docker compose --profile localai down
|
||
```
|
||
|
||
Przed testem modelu w LocalAI — zatrzymaj vLLM jeśli działa:
|
||
|
||
```bash
|
||
cd ../vllm
|
||
docker compose --profile vllm down
|
||
```
|
||
|
||
---
|
||
|
||
## 10. Troubleshooting
|
||
|
||
### 10.1 `/data` is not mounted
|
||
|
||
Wróć do [04-vllm-stack.md — część A](04-vllm-stack.md) i dokończ setup dysku.
|
||
|
||
### 10.2 GPU niewidoczne w kontenerze
|
||
|
||
```bash
|
||
docker run --rm --gpus all nvidia/cuda:12.6.0-base-ubuntu24.04 nvidia-smi
|
||
```
|
||
|
||
Upewnij się, że używasz obrazu `-cuda-13`, nie `-cuda-12`.
|
||
|
||
### 10.3 Healthcheck failing / restarting
|
||
|
||
```bash
|
||
docker compose --profile localai logs --tail 100 localai
|
||
```
|
||
|
||
Pierwszy start może trwać 1–2 minuty. Healthcheck ma `start_period: 2m`.
|
||
|
||
### 10.4 UI niedostępne z innego komputera
|
||
|
||
LocalAI nasłuchuje na `127.0.0.1:8070`. Dostęp z LAN/internetu — przez NPMPlus (rozdział 07) lub SSH tunnel:
|
||
|
||
```bash
|
||
# na swoim PC:
|
||
ssh -L 8070:127.0.0.1:8070 tomasz-syn-grzegorza@<IP-serwera>
|
||
# potem: http://localhost:8070
|
||
```
|
||
|
||
### 10.5 Brak modeli w UI
|
||
|
||
Zamierzone na tym kroku. Modele dodasz w kolejnym etapie (Model Gallery, GGUF, CLI).
|
||
|
||
---
|
||
|
||
## 11. KV cache (po dodaniu modelu chat)
|
||
|
||
Domyślnie KV cache w llama.cpp jest w **f16** — zajmuje dużo VRAM przy długim kontekście. Na RTX 3090 Ti (24 GB) rekomendujemy **q8_0** dla K i V.
|
||
|
||
Ustawienia są w YAML modelu na `/data/apps/localai/models/<nazwa>.yaml`, sekcja `parameters:`:
|
||
|
||
| Pole | Wartość startowa |
|
||
|------|------------------|
|
||
| `cache_type_k` | `q8_0` |
|
||
| `cache_type_v` | `q8_0` |
|
||
| `flash_attention` | `true` |
|
||
| `context_size` | `8192` |
|
||
|
||
Zastosowanie z repo:
|
||
|
||
```bash
|
||
cd /home/tomasz-syn-grzegorza/cursor/ubuntu-bare-metal/stacks/localai
|
||
./scripts/apply-kv-profile.sh gemma-4-12b-it-qat-q4_0
|
||
docker compose --profile localai restart localai
|
||
```
|
||
|
||
Skrypt tworzy backup YAML. Pliki w `/data/apps/localai/models/` są często **root-owned** — skrypt używa wtedy `docker exec localai` (volume `/models`).
|
||
|
||
Szczegóły: [`stacks/localai/coding-agent/KV-CACHE.md`](../stacks/localai/coding-agent/KV-CACHE.md)
|
||
|
||
Po załadowaniu modelu sprawdź VRAM:
|
||
|
||
```bash
|
||
nvidia-smi
|
||
docker compose --profile localai logs localai 2>&1 | tail -50
|
||
```
|
||
|
||
---
|
||
|
||
## 12. Następny krok
|
||
|
||
Po przejściu weryfikacji:
|
||
|
||
1. Zgłoś w rozmowie z Cursorem, że krok 05 jest gotowy.
|
||
2. Pobierz model (np. GGUF Qwen z katalogu vLLM) — osobny krok.
|
||
3. Później: rozdział **06 — sterowanie wentylatorami GPU** lub **07 — ComfyUI stack**.
|
||
|
||
---
|
||
|
||
## Checklist
|
||
|
||
- [ ] `.env` utworzony z `.env.example`
|
||
- [ ] `docker compose --profile localai pull` — obraz pobrany
|
||
- [ ] `./scripts/start.sh` — kontener `localai` running
|
||
- [ ] `curl http://localhost:8070/readyz` — OK
|
||
- [ ] UI otwiera się w przeglądarce na `:8070` (lub przez tunel SSH)
|
||
- [ ] Katalogi istnieją pod `/data/apps/localai/`
|
||
- [ ] (Po modelu chat) KV cache q8_0 w YAML + restart
|