Files
infra-phytron/server/phy-srv-gpu01/notes/20260710-projektplan.md
T

19 KiB
Raw Blame History

Projektplan — Setup phy-srv-gpu01 (LLM-Server mit SMB-Wissensbasis)

Date: 2026-07-10 (Stand-Update: 2026-09-03) Status: In Umsetzung — Server geliefert, Basis-Setup + GPU-Treiber fertig Basiert auf: 20260706-hardware-assessment.md, 20260706-software-assessment.md, 20260707-deep-dive.md


Stand 2026-09-03 (Kurzfassung — Details in den jeweiligen Abschnitten)

Erledigt: Server geliefert und im Rack; Basis-Setup (Ubuntu 24.04.4, Nutzer, Netz, RAID/Filesystem — s. SETUP.md im Repo-Root); GPU-Treiber via Ansible-Rolle nvidia_gpu (595er-Branch, open Kernel-Module — Blackwell läuft nicht mit den proprietären Modulen, s. manuals/20260714-nvidia-driver-install.md); Docker installiert. Share-Analyse gelaufen (§2.1).

Als Nächstes: CIFS-Mounts + Container-Stack (Rollen cifs_mounts, llm_stack) — entspricht Phasen 35 in §3.

Kritischer offener Punkt: Der Bestand ist rund 12× größer als die in §1 gesetzte Schwelle. Ohne Eingrenzung des Korpus (Kundengespräch) ist Phase 5 nicht sinnvoll umsetzbar — s. §2.1 und §2.6.

0. Rahmenbedingungen (fixiert)

Punkt Entscheidung
Hardware HPE DL380 Gen12, 2× Xeon 6714P, 128 GB RAM, RTX PRO 6000 96 GB, 2× 960 GB NVMe — s. HW.md
Betrieb Bare Metal, keine Virtualisierung des LLM-Stacks
Nutzer ~25, gemischt (technisch versiert + Nicht-Techniker)
Auth AD/LDAP (Details Service-Account/Basis-DN als Pre-Work klären)
Berechtigungen Einfach: alle Nutzer sehen den gesamten indizierten Bestand (Kunde bestätigt; Shares ohne HR-/Personal-Inhalte halten)
Sprache Dokumente & Nutzer überwiegend Deutsch → Modell- und Embedding-Wahl daran ausrichten
Inference vLLM mit fester GPU-Auslastung (kein Ollama als Basis)
Wissensbasis SMB-Shares (einige TB, PDF/Office), Sync ist die Kernanforderung
Später Jira-Anbindung u. a. Workloads; dafür ggf. MIG
Vorgehen Setup vollständig über Ansible (dieses Repo), PoC vorab: nein — reine Planung

1. Produktentscheidung: Open WebUI statt Onyx

Empfehlung: Open WebUI (bestätigt und verschärft die Empfehlung aus dem Deep Dive §4.7). Ausschlaggebend, Stand 2026-07-10 verifiziert:

  1. Onyx' File-Connector ist reiner manueller Upload — kein Verzeichnis-Watching, kein periodischer Re-Sync eines gemounteten Shares (Doku). Die Kernanforderung „Shares synchron halten" hieße bei Onyx: Eigenbau gegen deren API. Open WebUI hat dafür das offizielle Sync-Tool oikb (inkrementell, Löschungen, Cron-fähig — Deep Dive §4.3).
  2. Onyx: SSO (OIDC/SAML), User Groups, RBAC, Permission-Sync = Enterprise Edition (kostenpflichtig) (Doku). Open WebUI: LDAP/AD-Anbindung und Gruppen sind frei.
  3. Onyx bringt einen zweiten schweren Stack mit (Vespa-Index, Postgres, Worker) — auf 128 GB RAM neben vLLM spürbar; widerspricht „it just works".
  4. Bedienung: ein UI im ChatGPT-Stil, vorkonfigurierte Assistenten mit fester Knowledge Base → passt für den gemischten Nutzerkreis.

Wann die Entscheidung zu revidieren ist (Trigger, nach der Share-Analyse §2.1):

  • Der relevante Bestand liegt deutlich über ~10⁵ Dokumenten und lässt sich nicht sinnvoll filtern → Suchqualität/Skalierung von Open WebUI prüfen, Onyx (mit Eigenbau-Sync) oder Eigenbau-Pipeline (Deep Dive §4.5) neu bewerten.
  • Datei-genaue NTFS-ACLs werden doch Anforderung → Neubewertung (Deep Dive §4.4/4.5).

Status 2026-09-03: Trigger 1 ist eingetreten (1,26 Mio. Office-Dateien, §2.1). Die Produktentscheidung bleibt dennoch bei Open WebUI — aber nur unter der Bedingung, dass der Korpus auf einen kuratierten Teilbestand eingegrenzt wird (§2.6). Ein ungefilterter Vollindex über 1,26 Mio. Dokumente ist mit Open WebUI nicht sinnvoll zu betreiben (und liefert auch inhaltlich schlechte Antworten — RAG über einen kompletten, ungeordneten Fileserver retourniert überwiegend Rauschen).

Jira später: für Indizierung von Jira-Inhalten hat Onyx zwar native Konnektoren, Open WebUI deckt das aber über Tools/MCP (Atlassian-MCP) bzw. API-Workloads direkt gegen vLLM ab — kein Entscheidungskriterium für heute.

2. Phase 0 — Pre-Work (jetzt, ohne Server)

2.1 Share-Analyse (wichtigster Punkt — ja, unbedingt vorab)

Read-only-Skript auf einer beliebigen Maschine mit Share-Zugriff (kein GPU-Server nötig). Zu erheben:

  • Volumen & Dateianzahl pro Share und Dateityp (pdf/docx/xlsx/…)
  • Anteil gescannter PDFs (Stichprobe: PDFs ohne Textlayer) → OCR-Bedarf
  • Duplikate/Altversionen („Kopie von …", Versionsordner) → Filterregeln
  • Änderungsrate (mtime-Verteilung) → Sync-Frequenz
  • Anteil nicht extrahierbarer Formate (CAD, Bilder, Archive) → Erwartungsmanagement
  • Sonderzeichen/Pfadlängen, Encoding (Umlaute!)

Ergebnis bestimmt: Korpus-Umfang (→ §1-Trigger), OCR-Pipeline ja/nein, Index-Größe (→ Storage-Check §2.3), Erst-Indexierungsdauer.

Ergebnis (Lauf 2026-09-03, Skript scripts/share-analysis.ps1 auf D: des Fileservers Z-FILESERVER; Zahlen ggü. dem Erstlauf 2026-07-14 leicht gewachsen):

Kennzahl Wert Konsequenz
Gesamt 3.338.643 Dateien, 2.231 GB Scan lief über D: gesamt, nicht je Share → Obergrenze, enthält evtl. nicht freigegebene Daten
office (extrahierbar) 1.271.467 Dateien, 591 GB 12× über der §1-Schwelle → Eingrenzung zwingend (§2.6)
other (unklassifiziert) 1.576.747 Dateien, 919 GB größter Block, noch unidentifiziertD-file-types.csv auswerten
Bilder / CAD / Archive / Medien 403k / 60k / 12,6k / 6,2k Dateien nicht extrahierbar → Erwartungsmanagement
PDFs 935.186, davon ~22 % ohne Textlayer (Stichprobe 200) 200.000 Scan-PDFs → OCR; eigener Zeit-/GPU-Aufwand, konkurriert mit vLLM
Änderungsrate 94 % älter als 1 Jahr; nur ~158k in den letzten 365 Tagen Sync-Frequenz unkritisch; Alter ≠ Irrelevanz (Datenblätter, Normen) → Filter primär ordner-/inhaltsbasiert, Aktualität nur sekundär
Duplikat-/Altversions-Muster 33.378 Dateien Filterregeln
Pfade > 240 Zeichen 25.866 Extraktions-Toolchain gezielt testen
Nicht-ASCII-Dateinamen 126.899 UTF-8 durchgängig (CIFS-Mount-Optionen → Extraktion → Index)

Bug im Erstlauf: Beim Lauf über D: wurden keine CSVs geschrieben (Export-Csv scheiterte an D: im Dateinamen). Behoben am 2026-09-03; für die Ordner-Aufschlüsselung neu laufen lassen mit:

.\share-analysis.ps1 -Paths "D:" -OutDir .\file-analysis -FolderDepth 2

-FolderDepth 2 liefert Größe/Anzahl je Abteilungen\<Share> — genau die Granularität der Freigaben (s. §2.7) und die Grundlage für die Include-/ Exclude-Liste. Ebenfalls auszuwerten: D-file-types.csv zur Auflösung der other-Kategorie (1,58 Mio. Dateien, größter unidentifizierter Block).

2.2 Mit dem Kunden zu klären (Checkliste) — Stand 2026-09-03

  • AD/LDAP: AD-Gruppe llm_users wird angelegt. Offen: Bind-Service-Account und Basis-DN (werden für die LDAP-Konfiguration in Open WebUI gebraucht)
  • SMB-Service-Account read-only wird separat angelegt (kein Nutzer-Account)
  • Welche Shares/Unterordner in den Index? — offen, wird besprochen; wichtigster Punkt, s. §2.1/§2.6
  • DNS-Name chat.phytron.local (vorerst); kein TLS/keine lokalen Zertifikate zu Beginn → reines HTTP im LAN. Hinweis: AD-Passwörter gehen damit im Klartext über das Netz; für später ein internes CA-Zertifikat einplanen (Reverse Proxy ist vorbereitet, nur Zertifikat fehlt)
  • Internetzugang: unbeschränkt, keine Einschränkung nötig
  • Protokollierung/Datenschutz: noch zu besprechen (Chat-Logs = Verhaltensdaten; Betriebsrat/DSGVO) — vor dem Rollout klären, nicht vor der technischen Umsetzung
  • Betrieb/Wartung/Updates: wir (Softbox)
  • „Andere Workloads": Jira vorerst nicht relevant → MIG bleibt aus, die volle GPU geht an den LLM-Stack

2.3 Storage-Check — erledigt, unkritisch

Ist-Stand auf dem Server: 876 GB nutzbar (/, LVM), davon 818 GB frei. Gegenrechnung mit §2.1: selbst ein Vollindex des office-Bestands (1,26 Mio. Dokumente → grob 150250 GB inkl. extrahiertem Text, Embeddings und Index-Overhead) plus Modelle (~100 GB) passt. Strategie bleibt: kein lokaler Spiegel der Shares, nur Index. Keine zusätzlichen NVMe nötig.

Der begrenzende Faktor ist damit nicht der Plattenplatz, sondern Retrieval-Qualität und Indexgröße (§2.6).

2.4 Ansible — Stand 2026-09-03

  • run.yml: Play für phy_srv_gpu01 (security, docker, nvidia_gpu, compose)
  • nvidia_gpu — Treiber (595 open), Container Toolkit; läuft auf dem Server
  • LLM-Stack als Compose-Templates statt eigener Rolle: über ironicbadger.docker_compose_generator (auf 2.0.1 gepinnt), analog zum Homelab-Repo. Fragmente unter ansible/services/phy-srv-gpu01/: 01-vllm, 02-embeddings, 03-openwebui (+ pgvector), 99-network. Die Rolle schreibt nur ~/docker/compose.yaml; das Starten bleibt ein bewusster manueller Schritt.
  • cifs_mounts — ro-Mounts, Credentials aus group_vars/secrets.yml (erst sinnvoll, wenn die Freigaben-Auswahl steht, §2.6/§2.7)
  • oikb-Sync (Share → Knowledge Base), ebenfalls nach der Auswahl
  • Reverse Proxy + TLS — bewusst zurückgestellt (§2.2), Stack 04-proxy
  • group_vars/phy_srv_gpu01.yml: Overrides (Modell, VRAM-Quoten, LDAP, Compose-Pfade). Offen: echte LDAP-DNs und drei Vault-Secrets (vault_owui_secret_key, vault_owui_db_password, vault_ldap_bind_password)

Warum Compose-Templates und keine eigene llm_stack-Rolle: gleiche Konvention wie im Homelab-Repo (ein Ordner je Stack, NN--Präfix bestimmt die Reihenfolge), dadurch weniger Eigenbau und für den Wiedereinstieg vertraut.

2.5 Modell-Shortlist — Entscheidung 2026-09-03

Startmodell: Qwen3-32B FP8. Begründung: ~35 GB VRAM, damit reichlich Reserve für KV-Cache (~25 parallele Nutzer) und das Embedding-Modell daneben; gutes Deutsch; hoher Durchsatz. Alternative bei Qualitätsbedarf: gpt-oss-120b (MoE, ~6065 GB) — weniger Parallelität, engerer Fit. Embeddings: bge-m3 / multilingual-e5 (mehrsprachig, zwingend für Deutsch).

Das ist der Startwert als Rollen-Variable, keine endgültige Festlegung: Die finale Wahl fällt gegen das Eval-Set (s. u.) und nach dem vLLM-Smoke-Test.

⚠️ Offener technischer Punkt: Die offiziellen vLLM-Docker-Images unterstützen SM120 (Blackwell Workstation/Server) laut aktueller Quellenlage nicht zuverlässig out of the box; auf RTX-PRO-6000-Systemen werden verbreitet Nightly- oder Community-Builds eingesetzt (vLLM-Forum, rtx6kpro). Vor dem Bau der Rolle llm_stack daher ein Container manuell auf dem Server testen und das funktionierende Image pinnen — dieselbe Fehlerklasse wie beim Treiber (proprietäre vs. open Kernel-Module).

Kleines deutsches Eval-Set (2030 Fragen mit erwarteten Antworten aus dem Bestand) mit dem Kunden sammeln — das ist später das Abnahmekriterium.

2.6 Korpus eingrenzen (neu, wichtigster offener Punkt)

Die Share-Analyse (§2.1) hat 1,26 Mio. potenziell extrahierbare Dokumente ergeben. „Alles indizieren" ist weder technisch sinnvoll noch inhaltlich wünschenswert. Vorschlag für das Kundengespräch:

  1. Ordner statt Alter als Filter. Aus D-toplevel-folders.csv gemeinsam mit dem Kunden die Ordner markieren, die tatsächlich Wissensbasis sind (Doku, Normen, Datenblätter, Handbücher, Projektdoku) — Rest bleibt außen vor. Reiner Aktualitätsfilter wäre falsch: Datenblätter und Normen sind über Jahre gültig.
  2. Ausschlusslisten für Duplikate/Altversionen (33k Treffer), Archiv- und Backup-Ordner, nicht extrahierbare Formate (CAD, Bilder, Medien).
  3. Zielgröße nennen. Als Orientierung: eine gut funktionierende Wissensbasis liegt eher im Bereich 10.000100.000 Dokumente. Das ist kein hartes Limit, aber der Bereich, in dem Retrieval-Qualität und Indexierungsdauer beherrschbar bleiben.
  4. Iterativ starten. Phase 5 zuerst mit einem gut abgegrenzten Share/Ordner, Qualität am Eval-Set (§2.5) messen, dann erweitern. Das erspart einen tagelangen Fehlversuch über den Gesamtbestand.

Erwartungsmanagement gegenüber dem Kunden: Die ursprüngliche Anforderung lautete sinngemäß „unsere Dokumente auslesen". Realistisch ist „ein kuratierter Teil unserer Dokumente, dafür mit guten Antworten". Das früh sagen — nicht erst, wenn der Vollindex schlechte Treffer liefert.

2.7 Freigaben-Inventar (Stand 2026-09-03)

scripts/list-shares.ps1 auf Z-FILESERVER: 30 Freigaben, alle unterhalb D:, kein DFS. Vorschlag als Gesprächsgrundlage — die Zuordnung der Kürzel muss der Kunde bestätigen, ebenso die endgültige Auswahl:

Freigabe Pfad Vorschlag Begründung
QM D:\Abteilungen\QM rein Qualitätsmanagement — Normen, Prüfvorschriften: Kern der Wissensbasis
Arbeitssicherheit D:\Arbeitssicherheit rein Vorschriften, Betriebsanweisungen
Competence Center D:\Abteilungen\Competence Center rein Name deutet auf kuratiertes Wissen
EDV D:\Abteilungen\EDV rein IT-Doku
Produktion D:\Produktion prüfen vermutlich groß; ggf. nur Unterordner mit Doku
Projekte D:\Projekte prüfen vermutlich der größte Block; nur mit Unterordner-Filter sinnvoll
Lagerlogistik, Marketing, Kalkulationen, Controlling, Immobilie div. prüfen fachlich abhängig, eher zweite Welle
AA, AZ, BU, EE, EF, EK, ME, MF, MM, PL, SG, VT D:\Abteilungen\* klären Abteilungskürzel — Bedeutung und Inhalt vom Kunden bestätigen lassen
Zeichnungen D:\Abteilungen\Zeichnungen raus CAD/Zeichnungen — nicht extrahierbar (s. cad/image in §2.1)
Datenbank D:\Datenbank raus Datenbank-Dateien, kein Fließtext
Tempwork D:\Tempwork raus temporär, per Definition kein Wissensbestand
Benutzer D:\Benutzer raus persönliche Ablagen — Datenschutz, kein geteiltes Wissen
Personal D:\Abteilungen\Personal raus HR — explizit ausgeschlossen (§0: „alle sehen alles" gilt nur ohne Personaldaten)
GF D:\Abteilungen\GF raus Geschäftsführung — vertraulich
BR D:\Abteilungen\BR raus (klären) falls Betriebsrat: besonders schutzwürdig, auf keinen Fall indizieren

⚠️ Wichtig: Weil alle Nutzer alles sehen (§0), ist jede indizierte Freigabe für alle 25 Nutzer lesbar — unabhängig von den NTFS-Rechten auf dem Fileserver. Die Ausschlüsse oben sind deshalb keine Kosmetik, sondern die einzige Zugriffskontrolle. list-shares.ps1 gibt die NTFS-Gruppen je Freigabe mit aus: Alles, was heute nur einem eingeschränkten Personenkreis offensteht, gehört nicht in den Index.

3. Phasen ab Server-Lieferung

Phase Inhalt Ergebnis/Abnahme
1. Basis (Woche 1) Rack/Strom (600-W-GPU!), iLO, Firmware, RAID, Ubuntu 24.04 LTS, Eintrag in Ansible-Basis-Setup (Security, Pakete, Nutzer) just run phy_srv_gpu01 läuft grün
2. GPU-Stack (Woche 12) Rolle nvidia_gpu: Treiber, Container Toolkit, DCGM; Burn-in unter Dauerlast (SM120-Risiken, Deep Dive §1.6); MIG erst mal aus nvidia-smi ok, 48 h-Lasttest ohne Reset
3. Inference (Woche 2) vLLM-Container (NVIDIA-Build) mit gewähltem Modell, feste VRAM-Quote, Embedding-Server daneben; Benchmark mit Eval-Set deutsche Antworten ok, Ziel-Parallelität erreicht
4. UI + Auth (Woche 23) Open WebUI + pgvector, LDAP-Login, Reverse Proxy + TLS, vorkonfigurierter „Phytron-Assistent" Login mit AD-Konto, Chat läuft
5. Wissensbasis (Woche 35) CIFS-Mounts (ro), Extraktion inkl. OCR-Engine (Tika/Docling), oikb-Sync erst auf einen Teilbestand, Qualität prüfen, dann Vollindex (Dauer aus §2.1 abschätzen) Fragen aus dem Eval-Set werden mit korrekten Quellen beantwortet
6. Pilot → Rollout (Woche 57) 35 Pilotnutzer (gemischt), Feedback, dann alle 25; Onboarding-Einseiter (was kann es, was nicht — CAD/Scans!) Abnahme durch Kunden
7. Betrieb Monitoring (GPU/DCGM, Dienste), Backup (Konfig + DBs — Modelle nicht), Update-Runbook manuals/, Doku im README Runbooks vorhanden
später Jira & weitere Workloads; erst dann MIG-Layout festlegen (bis 4 Instanzen) statt jetzt raten

4. Risiken

Risiko Umgang
Storage zu klein für Index erledigt — 876 GB nutzbar, reicht (§2.3)
Korpus 12× über der Planungsschwelle (§2.1) Eingrenzung auf kuratierten Teilbestand (§2.6); ohne Kundenentscheid keine Phase 5
~166.000 Scan-PDFs → OCR-Aufwand & -Qualität eigener Arbeitsblock, GPU-Konkurrenz zu vLLM einplanen; Erwartungen dämpfen
SM120/Treiber-Kinderkrankheiten erledigt — Treiber 595 open läuft (proprietäre Module scheitern an RmInitAdapter)
Kein TLS zu Beginn (§2.2) AD-Passwörter im Klartext im LAN; internes CA-Zertifikat nachrüsten, Reverse Proxy vorbereiten
Software-Stand veraltet bis Lieferung Versionen erst bei Installation pinnen; Wiedereinstiegs-Checkliste
Erst-Indexierung dauert Tage Teilbestand zuerst; Sync nachts; Dauer vorab abschätzen
RAM-Konkurrenz Extraktion/OCR vs. vLLM vLLM hat feste VRAM-Quote; Indexer-Jobs drosseln (nice/cgroups); 128 GB reichen für OWUI-Stack
Datenschutz/Betriebsrat bei Chat-Logs Früh klären (§2.2), Logging-Policy dokumentieren
Kein HA — ein Server Erwartung managen: Wartungsfenster = Dienst weg; Backup-Restore-Runbook

5. Wiedereinstiegs-Checkliste (wenn der Server da ist)

  1. Dieses Dokument + Deep Dive lesen; offene Punkte aus §2.2 abhaken
  2. Ergebnis der Share-Analyse vorliegen? → §2.1
  3. Neu sichten & dann erst pinnen: vLLM-Version (RTX-PRO-6000-/SM120-Support), Open WebUI + oikb Release Notes, Modell-Shortlist §2.5 — NVIDIA-Treiber (595-open)
  4. Storage-Entscheidung §2.3 → unkritisch, nichts nachzubestellen
  5. Dann Phasenplan §3 von oben abarbeiten; jede Phase = Ansible-Commit + ggf. Runbook unter manuals/

6. Bewusst offen gelassen (kein Jetzt-Entscheid nötig)

  • Exaktes Modell & Quantisierung, vLLM-Flags, MIG-Layout, OCR-Engine-Wahl, Monitoring-Stack-Details, Reverse-Proxy-Produkt — alles bei Umsetzung mit aktuellem Stand entscheiden; Rahmen steht oben.