140 lines
6 KiB
Markdown
140 lines
6 KiB
Markdown
<!-- status: canonical -->
|
|
<!-- lastReviewed: 2026-05-29 -->
|
|
<!-- verifiedAgainst: service-llm-private (codebase review 2026-05-29) -->
|
|
|
|
# Private LLM -- Architektur
|
|
|
|
## Überblick
|
|
|
|
Eigenständiger Service für die Verarbeitung sensitiver Daten mit lokalen AI-Modellen (Ollama). Läuft auf einem dedizierten GPU-Server und wird vom Gateway als Provider-Plugin (`aicorePluginPrivateLlm.py`) angesprochen. Kein Datenabfluss an externe Cloud-APIs.
|
|
|
|
## Technologie-Stack
|
|
|
|
| Layer | Technologie |
|
|
|-------|------------|
|
|
| Framework | FastAPI (Python) |
|
|
| AI Runtime | Ollama (lokale Vision/Text/Reasoning-Modelle) |
|
|
| PDF-Support | PyMuPDF (fitz) |
|
|
| Hosting | Aktuell: Infomaniak (GPU L4, 24 GB) / Geplant: FireStorm (RTX PRO 6000, 96 GB) |
|
|
| Deployment | Forgejo Actions → `main` Branch |
|
|
|
|
## Modelle
|
|
|
|
### Aktuell (Infomaniak L4, 24 GB VRAM)
|
|
|
|
| Externer Name | Internes Ollama-Modell | Typ | Zweck |
|
|
|--------------|----------------------|-----|-------|
|
|
| `poweron-text-general` | `qwen2.5:7b` | Text | Neutralisierung, Datenanalyse |
|
|
| `poweron-vision-general` | `qwen2.5vl:7b` | Vision | Bildanalyse, Dokumenten-OCR |
|
|
| `poweron-vision-deep` | `granite3.2-vision` | Vision | Detaillierte Dokumentenanalyse |
|
|
|
|
### Geplant (FireStorm RTX PRO 6000, 96 GB VRAM)
|
|
|
|
| Externer Name | Internes Ollama-Modell | Typ | VRAM | Zweck |
|
|
|--------------|----------------------|-----|------|-------|
|
|
| `poweron-text-reasoning` | `deepseek-r1:70b` | Reasoning | ~40 GB | Chain-of-Thought, Logik, Planung |
|
|
| `poweron-vision-multimodal` | `llama4:scout` | Vision | ~16 GB | Multimodal, Long-Context (10M Tokens) |
|
|
| `poweron-embed` | `nomic-embed-text` | Embedding | ~0.3 GB | Lokales RAG-Embedding (ersetzt OpenAI) |
|
|
| `poweron-transcribe` | `whisper-large-v3-turbo` (faster-whisper) | STT | ~6 GB | Voice-Transkription, 99 Sprachen, Batch |
|
|
|
|
**VRAM-Budget gesamt: ~62 GB** (Reserve 34 GB fuer KV-Cache und Parallelitaet)
|
|
|
|
Die LLM-Modelle sind im Code vorbereitet und werden **automatisch aktiv**, sobald sie in Ollama gepullt sind (`_isModelAvailableInOllama`-Filter). Whisper laeuft als separater Faster-Whisper-Service mit OpenAI-kompatiblem API (`/v1/audio/transcriptions`).
|
|
|
|
## Migrations-Plan: Infomaniak → FireStorm
|
|
|
|
### Vorbedingungen
|
|
1. FireStorm GPU Pro bestellt (CHF 749/Mt., RTX PRO 6000 Blackwell, 96 GB VRAM)
|
|
2. Ubuntu 24.04 LTS mit CUDA-Treibern (vorinstalliert durch FireStorm)
|
|
|
|
### Migrationsschritte
|
|
|
|
```bash
|
|
# 1. Ollama installieren
|
|
curl -fsSL https://ollama.com/install.sh | sh
|
|
|
|
# 2. Service deployen (git clone + venv + systemd)
|
|
git clone git@git.poweron.swiss:PowerOn/service-llm-private.git /srv/llm-private/current
|
|
cd /srv/llm-private/current
|
|
python3.11 -m venv .venv
|
|
.venv/bin/pip install -r requirements.txt
|
|
# systemd service file: siehe docu/setupserver.md
|
|
|
|
# 3. Modelle pullen (aktuell + next-gen)
|
|
ollama pull qwen2.5:7b # ~4.5 GB (Abwaertskompatibilitaet)
|
|
ollama pull qwen2.5vl:7b # ~6 GB
|
|
ollama pull granite3.2-vision # ~2.4 GB
|
|
ollama pull deepseek-r1:70b # ~40 GB (Reasoning)
|
|
ollama pull llama4:scout # ~16 GB (Vision Multimodal)
|
|
ollama pull nomic-embed-text # ~0.3 GB (Embedding)
|
|
|
|
# 4. Whisper STT Service (separater Prozess)
|
|
pip install faster-whisper
|
|
# Oder: git clone https://github.com/Hantok/local-whisper-backend /srv/whisper
|
|
# Env: LOCAL_WHISPER_MODEL=large-v3-turbo, LOCAL_WHISPER_DEVICE=cuda
|
|
# Systemd service auf Port 9000, OpenAI-kompatibel: /v1/audio/transcriptions
|
|
|
|
# 5. config.ini anpassen (API-Key, TLS)
|
|
# 6. DNS umschalten: llm.poweron.swiss -> neue IP
|
|
# 7. TLS-Zertifikat (Let's Encrypt oder manuell)
|
|
```
|
|
|
|
### Nach Migration
|
|
- `MODEL_MAPPING` in `config.py` auf neue Modelle umschalten (auskommentierter Block)
|
|
- Alte Modelle (qwen2.5:7b etc.) koennen parallel weiterlaufen oder entfernt werden
|
|
- Infomaniak GPU-VM kuendigen
|
|
|
|
### Kostenvergleich
|
|
|
|
| | Infomaniak (aktuell) | FireStorm (geplant) |
|
|
|--|---|---|
|
|
| GPU | NVIDIA L4 (24 GB) | RTX PRO 6000 Blackwell (96 GB) |
|
|
| VRAM | 24 GB | 96 GB (+300%) |
|
|
| TFLOPS | ~30 FP32 | 125 FP32 (+316%) |
|
|
| RAM | 16 GB | 256 GB |
|
|
| Storage | 150 GB | 8 TB NVMe RAID 10 |
|
|
| Preis/Mt. | ~CHF 200 (geschaetzt) | CHF 749 |
|
|
| Reasoning-Modell | nicht moeglich (zu wenig VRAM) | DeepSeek R1 70B |
|
|
| Lokales Embedding | nicht moeglich | nomic-embed-text |
|
|
|
|
## API-Routen
|
|
|
|
| Modul | Zweck |
|
|
|-------|-------|
|
|
| `routeApi.py` | Analyse-API: Bild-/PDF-Analyse mit Prompt, Modellauswahl |
|
|
| `routeOpenAi.py` | OpenAI-kompatibles Chat-Completion-API (für Cursor-Integration) |
|
|
| `routeWeb.py` | Web-UI für manuelle Tests |
|
|
|
|
## Integration mit Gateway
|
|
|
|
Der Gateway nutzt das Private LLM über `aicorePluginPrivateLlm.py` als Provider für:
|
|
- **Neutralisierung:** Text-Analyse mit `poweron-text-general` (oder `poweron-text-reasoning`)
|
|
- **Sensitive Datenverarbeitung:** Vision-Analyse von Dokumenten (Rechnungen, Belege, Handschrift)
|
|
- **Reasoning:** Komplexe Logik und Planung mit `poweron-text-reasoning`
|
|
- **Lokales Embedding:** RAG-Indexierung ohne externe API-Kosten
|
|
- **Keine Billing-Kosten** für mandanteninterne LLM-Calls (eigene Infrastruktur)
|
|
|
|
## Sicherheit
|
|
|
|
- API-Key-Authentifizierung (`X-API-Key` Header)
|
|
- Separater Cursor-API-Key für OpenAI-kompatible Endpoints (Bearer Token)
|
|
- Rate-Limiting per API-Key (Token Bucket, konfigurierbar)
|
|
- Konfiguration über `config.ini` + Environment-Variablen (Secrets nie im Code)
|
|
|
|
## Schlüssel-Dateien
|
|
|
|
| Datei | Rolle |
|
|
|-------|-------|
|
|
| `app.py` | FastAPI-Einstieg, Router-Mount |
|
|
| `config.py` | Konfiguration, Model-Mapping, Auth, Rate-Limiting, Request/Response-Modelle |
|
|
| `routeApi.py` | Analyse-Endpunkte (Bild, PDF) |
|
|
| `routeOpenAi.py` | OpenAI-kompatibles Chat-API |
|
|
| `routeWeb.py` | Test-UI |
|
|
|
|
## Regeln / Invarianten
|
|
|
|
- Alle Daten werden **lokal** verarbeitet -- kein Weiterleiten an externe APIs
|
|
- Model-Mapping ist die einzige Stelle für Namensauflösung (`MODEL_MAPPING` in `config.py`)
|
|
- API-Keys werden aus `config.ini` oder Environment gelesen, nie hardcoded
|
|
- PDF-Verarbeitung rendert Seiten als Bilder für Vision-Modelle (max 5 Seiten)
|
|
- Neue Modelle werden automatisch erkannt wenn in Ollama verfuegbar (kein Code-Deploy noetig)
|