# 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)