first commit

This commit is contained in:
2026-07-10 09:57:37 +02:00
commit 652fba50c1
34 changed files with 1191 additions and 0 deletions
View File
View File
View File
View File
BIN
View File
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
Author: Petar Cubela
Company: Softbox GmbH
Date: 2024-12-04
Bla bla legal advise bla bla trademark, intellectual property and such bla bla
+3
View File
@@ -0,0 +1,3 @@
# Buero Templates for used software deployments
In this repository I collect all ansible playbooks used during my work.
+13
View File
@@ -0,0 +1,13 @@
## todo
### Modifications
- [ ] Build ansible-role-lamp
- [ ] Build seperate ansible-role-owncloud depending on ansible-role-lamp
- [ ] Build seperate ansible-role-nextcloud depending on ansible-role-lamp
## LAMP Stack
- [ ] Build with option to choose between apache and nginx
- [ ] Build with option to choose different databases
- [ ] Build with option to choose different php versions
+8
View File
@@ -0,0 +1,8 @@
[defaults]
nocows = 1
host_key_checking = false
inventory = ./hosts.ini
ansible_python_interpreter = /usr/bin/python3
[ssh_connections]
pipelining = true
+64
View File
@@ -0,0 +1,64 @@
---
# generic settings
main_username: sbxadmin
main_groupname: "{{ main_username }}"
main_uid: "1000"
main_gid: "{{ main_uid }}"
# weareinteractive.environment
environment_config: { "PUID": "{{ main_gid }}", "PGID": "{{ main_gid }}" }
global_env_vars:
- "PUID={{ main_uid }}"
- "PGID={{ main_gid }}"
- "TZ={{ ntp_timezone }}"
# geerlingguy.ntp
ntp_timezone: "Europe/Berlin"
# geerlingguy.nfs
#nfs_exports: [ "/home/public *(rw,sync,no_root_squash)" ]
# geerlingguy.security
security_ssh_port: 22
security_ssh_password_authentication: "yes"
security_ssh_permit_root_login: "no"
security_ssh_usedns: "no"
security_ssh_permit_empty_password: "no"
security_ssh_challenge_response_auth: "no"
security_ssh_gss_api_authentication: "no"
security_ssh_x11_forwarding: "no"
security_ssh_allowed_users:
- "{{ main_username }}"
security_ssh_allowed_groups: []
security_sudoers_passwordless:
- "{{ main_username }}"
security_autoupdate_enabled: false
security_autoupdate_blacklist: []
security_autoupdate_reboot: false
security_autoupdate_reboot_time: "03:00"
security_autoupdate_mail_to: "service@softbox.de"
security_autoupdate_mail_on_error: false
security_fail2ban_enabled: true
security_fail2ban_custom_configuration_template: "jail.local.j2"
###
#packages
package_list:
- bash-completion
- htop
- apt-transport-https
- network-manager
- vim
- curl
- xclip
- net-tools
- rsync
- smartmontools
- parted
- mlocate
- cpp
- gcc
- make
- psmisc
#- linux-headers-$(uname -r)
- open-vm-tools
+4
View File
@@ -0,0 +1,4 @@
hostname: cloud
#.phytron.de
php_version: 8.2
domain_base: "phytron.de"
+43
View File
@@ -0,0 +1,43 @@
---
# generic settings
main_username: sbxadmin
main_groupname: "{{ main_username }}"
main_uid: "1000"
main_gid: "{{ main_uid }}"
# weareinteractive.environment
environment_config: { "PUID": "{{ main_gid }}", "PGID": "{{ main_gid }}" }
global_env_vars:
- "PUID={{ main_uid }}"
- "PGID={{ main_gid }}"
- "TZ={{ ntp_timezone }}"
# geerlingguy.ntp
ntp_timezone: "Europe/Berlin"
# geerlingguy.nfs
#nfs_exports: [ "/home/public *(rw,sync,no_root_squash)" ]
# geerlingguy.security
security_ssh_port: 22
security_ssh_password_authentication: "no"
security_ssh_permit_root_login: "no"
security_ssh_usedns: "no"
security_ssh_permit_empty_password: "no"
security_ssh_challenge_response_auth: "no"
security_ssh_gss_api_authentication: "no"
security_ssh_x11_forwarding: "no"
security_ssh_allowed_users:
- "{{ main_username }}"
security_ssh_allowed_groups: []
security_sudoers_passwordless:
- "{{ main_username }}"
security_autoupdate_enabled: true
security_autoupdate_blacklist: []
security_autoupdate_reboot: reboot
security_autoupdate_reboot_time: "03:00"
security_autoupdate_mail_to: "service@softbox.de"
security_autoupdate_mail_on_error: true
security_fail2ban_enabled: true
security_fail2ban_custom_configuration_template: "jail.local.j2"
+9
View File
@@ -0,0 +1,9 @@
#[snipeit]
#10.0.101.15 ansible_user=root ansible_port=22
#
[nextcloud]
192.168.66.66 ansible_user=sbxadmin ansible_port=22
[sftp]
192.168.66.68 ansible_user=sbxadmin ansible_port=22
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env -S just --justfile
# Ansible playbook against specific host
run HOST *TAGS:
ansible-playbook -b run.yml --limit {{HOST}} {{TAGS}}
# docker compose against remote host via Ansible
compose HOST *V:
ansible-playbook run.yml --limit {{HOST}} --tags compose {{V}}
# optionally use --force to force reinstall all requirements
reqs *FORCE:
ansible-galaxy install -r requirements.yml {{FORCE}}
# just vault (encrypt/decrypt/edit)
vault ACTION:
EDITOR=nvim ansible-vault {{ACTION}} group_vars/secrets.yml
+9
View File
@@ -0,0 +1,9 @@
---
- name: Shutdown k3s_cluster
hosts: k3s_cluster
gather_facts: true
tasks:
- name: Shutdown the nodes (and wait one 1 min)
become: true
community.general.shutdown:
delay: 60
+29
View File
@@ -0,0 +1,29 @@
---
- hosts:
- all
become: true
tasks:
- name: Perform a dist-upgrade.
ansible.builtin.apt:
upgrade: dist
update_cache: yes
- name: Install essential packages
package:
name: "{{ package_list }}"
state: present
- name: Check if a reboot is required.
ansible.builtin.stat:
path: /var/run/reboot-required
get_checksum: no
register: reboot_required_file
- name: Reboot the server (if required).
ansible.builtin.reboot:
when: reboot_required_file.stat.exists == true
- name: Remove dependencies that are no longer required.
ansible.builtin.apt:
autoremove: yes
+8
View File
@@ -0,0 +1,8 @@
---
roles:
#- name: geerlingguy.pip
- name: geerlingguy.docker
- name: geerlingguy.nfs
- name: geerlingguy.security
- name: geerlingguy.ntp
- name: ironicbadger.docker_compose_generator
@@ -0,0 +1,5 @@
site_conf: cloud.conf
php_version: "8.4"
mysql_db_name: nextcloud
mysql_db_user: nextcloud
web_root: "/var/www/nextcloud"
@@ -0,0 +1,5 @@
---
- name: restart apache
service:
name: apache2
state: restarted
+35
View File
@@ -0,0 +1,35 @@
- name: Set hostname
ansible.builtin.hostname:
name: "{{ hostname }}"
- name: "Enable recommended Apache Modules."
apache2_module: "name={{ item }} state=present"
with_items:
- dir
- env
- headers
- mime
- rewrite
- setenvif
notify: restart apache
- name: Add Apache virtualhost for Nextcloud
template:
src: "templates/{{ site_conf }}.j2"
dest: "/etc/apache2/sites-available/{{ site_conf }}"
owner: root
group: root
mode: 0644
notify: restart apache
- name: Enable the Nextcloud site.
command: >
a2ensite {{ site_conf }}
creates="/etc/apache2/sites-enabled/{{ site_conf }}"
notify: restart apache
- name: Disable the default site.
command: >
a2dissite 000-default
removes=/etc/apache2/sites-enabled/000-default.conf
notify: restart apache
@@ -0,0 +1,72 @@
---
- name: Get software for apt repository management.
apt:
state: present
name:
- python3-apt
- python3-pycurl
- python3-pymysql
- gnupg2
#- name: Add ondrej repository for later versions of PHP.
# apt_repository:
# repo: "ppa:ondrej/php"
# update_cache: yes
#sudo dpkg -l | grep php | tee packages.txt
#sudo apt install apt-transport-https lsb-release ca-certificates wget -y
#sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
#sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
#sudo apt update
- name: "Install Apache, MySQL, PHP, and other dependencies."
apt:
state: present
name:
- acl
- git
- curl
- wget
- unzip
- openssl
- redis-server
- mariadb-server
- libpcre3-dev
- apache2
- "libapache2-mod-php"
- "php{{ php_version }}"
- "php{{ php_version }}-imagick"
- "php{{ php_version }}-common"
- "php{{ php_version }}-curl"
- "php{{ php_version }}-gd"
- "php{{ php_version }}-imap"
- "php{{ php_version }}-intl"
#- "php{{ php_version }}-json"
- "php{{ php_version }}-mbstring"
- "php{{ php_version }}-gmp"
- "php{{ php_version }}-bcmath"
- "php{{ php_version }}-mysql"
- "php{{ php_version }}-ssh2"
- "php{{ php_version }}-xml"
- "php{{ php_version }}-zip"
- "php{{ php_version }}-apcu"
- "php{{ php_version }}-redis"
- "php{{ php_version }}-ldap"
#- "php{{ php_version }}-smbclient"
- php-phpseclib
- bzip2
- rsync
- jq
- inetutils-ping
- ldap-utils
- smbclient
- cron
#- name: Disable the firewall (since this is behind a firewall)
# service: name=ufw state=stopped
- name: "Start Apache, MySQL, and PHP."
service: "name={{ item }} state=started enabled=yes"
with_items:
- apache2
- mysql
+24
View File
@@ -0,0 +1,24 @@
---
- name: Install LAMP stack dependencies
include_tasks:
file: dependencies.yml
- name: Configure Apache.
include_tasks:
file: apache.yml
- name: Configure PHP.
include_tasks:
file: php.yml
- name: Configure MySQL.
include_tasks:
file: mysql.yml
- name: Create occ helper script.
include_tasks:
file: occ.yml
- name: Download Nextcloud.
include_tasks:
file: nextcloud.yml
+16
View File
@@ -0,0 +1,16 @@
- name: Create a MySQL database.
community.mysql.mysql_db:
name: "{{ mysql_db_name }}"
state: present
login_unix_socket: /run/mysqld/mysqld.sock
- name: Create a MySQL db user.
community.mysql.mysql_user:
name: "{{ mysql_db_user }}"
password: "{{ mysql_passwd }}"
login_user: "root"
login_password: "{{ mysql_passwd }}"
priv: "{{ mysql_db_user }}.*:ALL"
host: localhost
state: present
login_unix_socket: /run/mysqld/mysqld.sock
@@ -0,0 +1,13 @@
---
- name: Download Nextcloud source.
ansible.builtin.get_url:
url: https://download.nextcloud.com/server/releases/latest.tar.bz2
dest: "/tmp/nextcloud-complete-latest.tar.bz2"
owner: www-data
- name: Extract the archive.
ansible.builtin.unarchive:
src: "/tmp/nextcloud-complete-latest.tar.bz2"
dest: "/var/www/"
owner: www-data
remote_src: yes
+7
View File
@@ -0,0 +1,7 @@
- name: Create a helper script for running occ commands.
template:
src: "templates/occ.j2"
dest: "/usr/local/bin/occ"
owner: root
group: root
mode: 0755
+16
View File
@@ -0,0 +1,16 @@
---
- name: Adjust OpCache memory setting.
lineinfile:
dest: "/etc/php/{{ php_version }}/apache2/conf.d/10-opcache.ini"
regexp: "^opcache.memory_consumption"
line: "opcache.memory_consumption = 96"
state: present
notify: restart apache
#- name: Adjust smbclient setting.
# template:
# src: "templates/smbclient.ini.j2"
# dest: "/etc/php/7.4/mods-available/smbclient.ini"
# owner: root
# group: root
# notify: restart apache
@@ -0,0 +1,17 @@
<VirtualHost *:80>
ServerName {{ hostname }}.{{ domain_base }}
DirectoryIndex index.php index.html
DocumentRoot {{ web_root }}
<Directory {{ web_root }}>
Options FollowSymLinks MultiViews
AllowOverride All
Require all granted
<IfModule mod_dav.c>
Dav off
</IfModule>
#SetEnv HOME {{ web_root }}
#SetEnv HTTP_HOME {{ web_root }}
</Directory>
</VirtualHost>
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
cd /var/www/nextcloud || exit
sudo -E -u www-data /usr/bin/php /var/www/nextcloud/occ "$@"
+52
View File
@@ -0,0 +1,52 @@
---
#- hosts: owncloud
# become: yes
# vars_files:
# - "vars/vault.yml"
#
# pre_tasks:
# - name: Update apt cache.
# apt:
# update_cache: true
# cache_valid_time: 3600
# when: ansible_os_family == 'Debian'
#
# roles:
# - role: geerlingguy.security
# #- role: geerlingguy.ntp ## NEEDED?
# - role: owncloud
- hosts: nextcloud
become: yes
vars_files:
- "vars/vault.yml"
pre_tasks:
- name: Update apt cache.
apt:
update_cache: true
cache_valid_time: 3600
when: ansible_os_family == 'Debian'
roles:
# - role: geerlingguy.security
- role: nextcloud
- role: smtp_nextcloud
tags: mail
- hosts: sftp
become: yes
vars_files:
- "vars/vault.yml"
pre_tasks:
- name: Update apt cache.
apt:
update_cache: true
cache_valid_time: 3600
when: ansible_os_family == 'Debian'
roles:
- role: geerlingguy.security
tags: base
+14
View File
@@ -0,0 +1,14 @@
$ANSIBLE_VAULT;1.1;AES256
31353435633062366461353231666566366662373733656337356339626234313966366139613161
3533646266393033316330323737303638303162356161610a393337313837653835396162633030
30313066326337393831643833663237643966383163363866386133373264373933633133653462
6636376563336433640a356231363764363834626431616435633436306662313932313164623733
62383062653166613661303939346135643661646630386532306161393365393133626164303337
31623962623931353365346365623333386638313266356131326565613730303338643863396237
39353261616339356563393236633232646361326234333533643338656331623732636432383434
63653963336333366462366562633631336636643935646632323031666366633136383732643733
63366433363136666131386434333431333062363238633064646336626463623730616238646136
31333839623538306161393862306231656466613231326165666562616432363136396332646533
30663130336438623463336333343830656138316236353963373833386434393337356262313934
63323030323837373066323337363633636236353931643636643337393161303965613438363638
3532
@@ -0,0 +1,62 @@
# Add new Users to SFTP Server
## Introduction
We configured a SFTP server with a shared chroot jail and such that the server can only be authenticated via public key exchange.
The shared SFTP root folder is at `/sftp`:
```bash
root@z-sftp-01:~# ls -al /sftp/
total 16
drwxr-xr-x 4 root root 4096 Jan 30 15:16 .
drwxr-xr-x 19 root root 4096 Feb 4 00:00 ..
drwxrwx--- 2 root sftpusers 4096 Jan 30 15:47 data
drwxrwx--- 2 root sftpusers 4096 Jan 30 15:23 uploads
```
The server can only be reached via sftp by users which are members of the `sftpusers` group; while these users are not able to login via ssh. Only users which are in `admins` group can access the server via ssh and this also only via public key authentication.
## New User
### User Creation
We create the user on the server:
```bash
useradd -m -s /sbin/nologin <username>
```
The option `-m` explicitly creates a home folder (under `/home`) for the user which is not created when using the option `-s` and giving the user the `/sbin/nologin` shell.
And add the user to the correct group:
```bash
usermod -aG sftpusers <username>
```
### SSH authentication
Create a ssh key pair for the user with the command,
```bash
ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/<sbx-sftp-name> -C <user-mail>
```
which can be done in an arbitrary Unix shell supporting `ssh-keygen`.
In order for the user to be able to authenticate via public key exchange we have to create a `/home/<username>/.ssh/authorized_keys` file with proper permissions:
```bash
mkdir /home/<username>/.ssh
touch /home/<username>/.ssh/authorized_keys
chown -R <username>:<username> /home/<username>/.ssh
chmod 700 /home/<username>/.ssh
chmod 600 /home/<username>/.ssh/authorized_keys
```
Take the content of the public key file an insert into the proper authorized_key file
```bash
cat ~/.ssh/<sbx-sftp-name>.pub | tee -a ~/.ssh/authorized_keys
```
@@ -0,0 +1,90 @@
# Hardware Assessment — GPU Server für LLM-Workloads
Date: 2026-07-06
Status: Draft for internal review
Budget: ~50.000 €
## TL;DR
Die Beobachtung vom Bestandsserver (CPU < 10 %, RAM < 150 GB, GPUs zeitweise
voll ausgelastet) ist typisch: **LLM-Inference ist fast reine GPU-Last.**
Downscaling von CPU und RAM ist richtig. Bei der GPU empfehle ich statt einer
halben H100-NVL-Konfiguration die **NVIDIA RTX PRO 6000 Blackwell Server
Edition (96 GB)** — mehr VRAM als eine H100 NVL, in Single-GPU-Inference-
Benchmarks gleichauf oder schneller, für etwa **ein Drittel des Preises**
(~910 k€ statt ~31 k€). Gesamtsystem landet grob bei **2025 k€ inkl.
Support** — deutlich unter Budget.
## 1. Einordnung des Bestandsservers
Die Referenz-Konfiguration (DL380a Gen11, 2× Xeon 6526Y, 512 GB RAM,
2× H100 NVL) ist für den Inference-Use-Case überdimensioniert:
- **CPU < 10 %**: erwartbar — bei GPU-Inference macht die CPU nur
Tokenizing, Scheduling und I/O. 2× 16 Kerne sind unnötig.
- **RAM < 100150 GB**: davon ist erfahrungsgemäß ein großer Teil
Page-Cache. Echter Bedarf: Modell-Staging + Services, deutlich unter 128 GB.
- **2× H100 NVL**: NVLink-Pärchen lohnt sich nur, wenn ein Modell über beide
GPUs gespannt wird (Tensor-Parallel). Für Modelle ≤ 96 GB unnötig.
## 2. GPU-Empfehlung
| | RTX PRO 6000 Blackwell SE | H100 NVL | L40S |
|---|---|---|---|
| VRAM | **96 GB GDDR7** | 94 GB HBM3 | 48 GB GDDR6 |
| Speicherbandbreite | 1.792 GB/s | 3.900 GB/s | 864 GB/s |
| FP8/FP4 | ✅ / ✅ (Blackwell) | ✅ / ❌ | ❌ / ❌ |
| NVLink | ❌ (hier irrelevant, 1 GPU) | ✅ | ❌ |
| Straßenpreis (ca.) | **~910 k€** | ~31 k€ | ~8 k€ |
- Benchmarks 2026 zeigen die RTX PRO 6000 bei Single-GPU-LLM-Inference
**gleichauf bis vor der H100** bei ~28 % niedrigeren Kosten pro Token
([cloudrift.ai](https://www.cloudrift.ai/blog/benchmarking-rtx6000-vs-datacenter-gpus),
[openmetal.io](https://openmetal.io/resources/blog/comparing-the-nvidia-rtx-pro-6000-vs-h100-for-ai-inference/)).
- Gegenüber der in den Notizen angesetzten 48-GB-Karte (L40S-Klasse):
doppelter VRAM und > 2× Bandbreite für ähnliches Geld — 96 GB erlauben
70B-Modelle in FP8 bzw. viel KV-Cache für parallele Nutzer
([gpuperhour.com](https://gpuperhour.com/compare/l40s-vs-rtx-pro-6000-blackwell)).
- H100 NVL nur dann, wenn später auf 2 GPUs mit Tensor-Parallelität erweitert
werden soll — dafür gibt es hier kein Anzeichen.
⚠️ Mit dem Distributor klären, welche HPE-Plattform (DL380 Gen11/Gen12 bzw.
DL380a) für die RTX PRO 6000 Blackwell SE qualifiziert ist.
## 3. Empfohlene Konfiguration (angelehnt an das Referenz-Angebot)
| Komponente | Referenz-Server | Empfehlung neu | Begründung |
|---|---|---|---|
| Chassis | DL380a Gen11 | DL380 Gen11/Gen12 mit GPU-Kit (oder DL380a) | 1 GPU braucht kein 4-GPU-Chassis |
| CPU | 2× Xeon 6526Y (32C) | **1× Xeon 16C** (z. B. 6526Y o. kleiner) | CPU-Last < 10 % beobachtet |
| RAM | 512 GB (8× 64 GB) | **128 GB (8× 16 GB)** | Alle 8 Kanäle belegt (Bandbreite), Upgrade-Pfad auf 256 GB frei |
| Boot-SSD | 2× 960 GB NVMe | 2× 960 GB NVMe (RAID 1) | unverändert |
| Daten-SSD | — | **+ 2× 3,84 TB NVMe (RAID 1)** | Modelle + Vektor-Index der Datei-Suche |
| NIC | 2× 25 GbE + 4× 1 GbE | 1× 25/10 GbE SFP28 + 1 GbE (Mgmt) | Indizierung zieht die SMB-Shares übers Netz — 1 GbE wäre der Flaschenhals |
| GPU | 2× H100 NVL 94 GB | **1× RTX PRO 6000 Blackwell SE 96 GB** | s. o. |
| PSU | 4× 18002200 W | 2× 1800 W (redundant) | 1 GPU à 600 W |
| iLO Adv + Support | 5 J. | 5 J. Tech Care Essential | unverändert |
**Grobe Kostenschätzung:** Server-Basis + CPU + RAM + Storage ≈ 1012 k€,
GPU ≈ 910 k€, Support ≈ 46 k€ → **~2328 k€**. Es bleibt Budget für
Einrichtung/Software-Dienstleistung (RAG-Pipeline!) und ggf. eine zweite GPU
später — das Chassis dafür gleich mit einplanen (Riser/Netzteile).
## 4. Passt eine GPU für "viele Nutzer"?
Ja, für den beschriebenen Fall (Nicht-Power-User, Chat + Datei-Suche):
- Nicht-Power-User erzeugen wenig gleichzeitige Last; realistisch sind
520 parallele Anfragen selbst bei 100+ angebundenen Usern.
- vLLM mit einem 2032B-Modell in FP8 auf 96 GB bedient das komfortabel;
ein 70B-Modell geht ebenfalls, mit weniger Parallelitäts-Headroom.
- Wachstumspfad: zweite RTX PRO 6000 nachrüsten (zwei unabhängige
vLLM-Instanzen bzw. Modell-Replikation — kein NVLink nötig).
## Quellen
- [RTX PRO 6000 vs H100/H200/L40S LLM Inference Benchmarks (cloudrift.ai)](https://www.cloudrift.ai/blog/benchmarking-rtx6000-vs-datacenter-gpus)
- [RTX PRO 6000 Pricing July 2026 (Thunder Compute)](https://www.thundercompute.com/blog/nvidia-rtx-pro-6000-pricing)
- [L40S vs RTX PRO 6000 (gpuperhour)](https://gpuperhour.com/compare/l40s-vs-rtx-pro-6000-blackwell)
- [RTX PRO 6000 vs H100 for AI Inference (OpenMetal)](https://openmetal.io/resources/blog/comparing-the-nvidia-rtx-pro-6000-vs-h100-for-ai-inference/)
- [RTX PRO 6000 Benchmarks: 30B AWQ, 70B FP8, Cost per Mtok (Spheron)](https://www.spheron.network/blog/rent-nvidia-rtx-pro-6000/)
@@ -0,0 +1,119 @@
# Software Assessment — GPU Server für LLM-Workloads
Date: 2026-07-06
Status: Draft for internal review
## TL;DR
**LM Studio ist als Server-Dienst für viele Benutzer nicht geeignet.** Es ist ein
Desktop-Tool für Einzelnutzer. Empfehlung: **vLLM** als Inference-Server +
**Open WebUI** als Benutzeroberfläche (Multi-User, LDAP). Für die Datei-Suche
über SMB-Shares wird zusätzlich eine RAG-/Enterprise-Search-Komponente
benötigt — das ist der eigentlich anspruchsvolle Teil des Projekts, nicht das
LLM-Hosting.
## 1. Ist LM Studio als Server-Dienst geeignet?
Kurz: **Nein**, nicht für den Multi-User-Betrieb.
Was LM Studio inzwischen kann:
- Headless-Betrieb ohne GUI über den `llmster`-Daemon (offiziell dokumentiert:
[lmstudio.ai/docs/app/api/headless](https://lmstudio.ai/docs/app/api/headless))
- OpenAI-kompatible lokale API
- Seit 2025 auch für kommerzielle Nutzung kostenlos
Warum es trotzdem ungeeignet ist:
| Anforderung | LM Studio |
|---|---|
| Multi-User / Benutzerverwaltung | ❌ Keine — die API ist für einen lokalen Einzelnutzer gedacht, ohne Benutzerkonten |
| LDAP/AD-Anbindung | ❌ Nicht vorhanden |
| Gleichzeitige Anfragen vieler Nutzer | ❌ llama.cpp-Backend, kein Continuous Batching wie vLLM — Durchsatz bricht bei Parallelität ein |
| Modell-Verwaltung im Betrieb | ⚠️ Modell-Laden ist exklusiv; Wechsel unterbricht den Dienst |
| RAG / Suche über Netzlaufwerke | ❌ Nur lokale Datei-Anhänge im Chat, keine Index-Pipeline |
Fazit: LM Studio bleibt sinnvoll als **lokales Tool für Power-User am
Arbeitsplatz**, aber der Server braucht einen echten Inference-Stack.
## 2. Empfohlener Software-Stack
```
[User-Browser] ──► Open WebUI (Auth via LDAP/AD, Chat-UI, RAG)
│ OpenAI-kompatible API
vLLM (Inference-Server, Continuous Batching)
1× GPU (96 GB VRAM)
[SMB-Shares] ──► Index-Pipeline (Embedding + Vektor-DB) ──► RAG-Abfragen
```
### Inference: vLLM
- De-facto-Standard für Multi-User-LLM-Serving: Continuous Batching,
PagedAttention, hoher Durchsatz bei vielen gleichzeitigen Nutzern
- OpenAI-kompatible API → jedes Frontend (auch LM Studio-Clients der
Power-User) kann sich verbinden
- Läuft als Docker-Container, gut automatisierbar
### Frontend: Open WebUI
- Multi-User mit Rollen/Gruppen, **native LDAP-Anbindung** (deckt die
Anforderung "Alle User angebunden (LDAP?)" aus den Notizen ab)
- Chat-UI im ChatGPT-Stil — geeignet für Nicht-Power-User
- Eingebaute RAG-Funktion ("Knowledge Bases"): Dokumente hochladen und
durchsuchen
### Datei-Suche über SMB-Shares — der kritische Punkt
"Suchmaschine für eigene Daten" heißt: die Shares müssen **indiziert** werden
(Embedding-Modell + Vektor-Datenbank), nicht nur per Chat angehängt. Optionen:
1. **Open WebUI Knowledge Bases** — seit v0.9.6 mit offiziellem Sync-Tool
`oikb`: gemountete Verzeichnisse (→ SMB-Shares) werden inkrementell in
Knowledge Bases gespiegelt. Details: `20260707-deep-dive.md` §4.3.
2. **Onyx (ehem. Danswer)** — dediziertes Enterprise-Search-Produkt,
Konnektoren für Datei-Quellen, eigene Benutzer-/Rechteverwaltung,
nutzt das lokale LLM via OpenAI-API. Passender für den Vollausbau.
3. Eigene Pipeline (gemountete Shares + Embedding-Job + Qdrant/pgvector) —
maximale Kontrolle, mehr Aufwand.
⚠️ **Offener Punkt, vor Angebot klären:** Müssen Suchergebnisse die
NTFS-/Share-Berechtigungen respektieren (User A darf Dokumente von Abteilung B
nicht sehen)? **Permission-Trimming ist in keiner der Standard-Lösungen
trivial** und bestimmt maßgeblich Aufwand und Produktwahl. Wenn ja, ist Onyx
oder eine kommerzielle Lösung fast zwingend; wenn die Shares ohnehin für alle
lesbar sind, reicht der einfache Stack.
### Modelle (bei 96 GB VRAM)
- Start: ein 2032B-Instruct-Modell (z. B. Qwen3-32B oder gpt-oss-20b) in
FP8 — schnell, viel KV-Cache-Headroom für viele parallele Nutzer, gutes
Deutsch
- Option: 70B-Klasse in FP8 oder gpt-oss-120b (MXFP4, ~63 GB) passt auf die
eine Karte, wenn mehr Qualität gewünscht ist — auf Kosten des Durchsatzes
- Zusätzlich ein Embedding-Modell für die Suche (z. B. multilingual-e5 oder
bge-m3, klein, läuft nebenher auf derselben GPU)
### Betrieb
- Ubuntu Server 24.04 LTS, NVIDIA-Treiber + Container Toolkit
- Alles als Docker Compose (vLLM, Open WebUI, Vektor-DB) → reproduzierbar,
einfache Updates
- Backup nur für Konfiguration + Vektor-DB nötig; Modelle sind wiederbeschaffbar
## 3. Offene Fragen an den Kunden
1. Wie viele Benutzer insgesamt / gleichzeitig? (bestimmt Modellgröße)
2. Datenvolumen und Dateitypen auf den Shares? (Office, PDF, Scans/OCR?)
3. Müssen Berechtigungen der Shares in der Suche durchgesetzt werden? (s. o.)
4. Nur Chat + Suche, oder auch API-Zugriff für Anwendungen/Skripte?
## Quellen
- [LM Studio Docs — Headless/llmster](https://lmstudio.ai/docs/app/api/headless)
- [Top 20 Tools to Run LLMs Locally in 2026 (iunera)](https://www.iunera.com/kraken/enterprise-ai/top-20-tools-to-run-llms-locally-in-2026-ollama-anythingllm-open-webui-lm-studio-vllm-and-every-real-alternative-compared/)
- [Open WebUI Overview (glukhov.org)](https://www.glukhov.org/llm-hosting/llm-frontends/open-webui-overview-quickstart-and-alternatives/)
- [LM Studio Complete Guide 2026 (codersera)](https://codersera.com/blog/lm-studio-complete-guide-2026/)
- [Open WebUI + LM Studio Integration (markaicode)](https://markaicode.com/integrate/open-webui-with-lm-studio/)
@@ -0,0 +1,427 @@
# Deep Dive — GPU-Auswahl, Inference-Backend & Anbindung der SMB-Wissensbasis
Date: 2026-07-07
Status: Entscheidungsgrundlage für Kundengespräch
Basiert auf: `20260706-hardware-assessment.md`, `20260706-software-assessment.md`
---
## 0. Executive Summary
| Entscheidung | Empfehlung | Konfidenz |
|---|---|---|
| GPU | **RTX PRO 6000 Blackwell Server Edition (96 GB)** statt H100 NVL | Hoch — durch mehrere unabhängige Benchmarks gedeckt |
| LM Studio als Server | **Nein** — Desktop-Tool, kein Mehrbenutzer-Server | Hoch |
| Inference-Backend | **vLLM** (ggf. Ollama zusätzlich für Power-User-Experimente) | Hoch |
| Frontend | **Open WebUI** (LDAP/AD, Gruppen, Knowledge Bases) | Hoch |
| SMB-Anbindung | **Phase 1: Open WebUI Knowledge + offizielles Sync-Tool `oikb`**; Phase 2: Onyx nur falls Skalierung/Berechtigungen es erzwingen | Mittel — hängt von offenen Fragen ab (§6) |
---
## 1. GPU: RTX PRO 6000 Blackwell SE vs. H100 NVL
Der Kunde hat die H100 genannt. Das ist verständlich („die KI-GPU"), aber die
H100 ist eine **Hopper-Karte von 2022/23** und für verteiltes Training bzw.
Multi-GPU-Inference gebaut. Die RTX PRO 6000 Blackwell Server Edition (2025)
ist **zwei Architektur-Generationen neuer** und von NVIDIA explizit als
Enterprise-Inference-Karte positioniert.
### 1.1 Daten im Vergleich
| | RTX PRO 6000 Blackwell SE | H100 NVL |
|---|---|---|
| Architektur | Blackwell (2025) | Hopper (2022/23) |
| VRAM | **96 GB GDDR7, ECC** | 94 GB HBM3, ECC |
| Speicherbandbreite | 1,79 TB/s | **3,9 TB/s** |
| FP8 / FP4 (NVFP4) | ✅ / **✅** | ✅ / ❌ |
| MIG (GPU-Partitionierung) | ✅ bis 4 Instanzen ([NVIDIA](https://www.nvidia.com/en-us/data-center/rtx-pro-6000-blackwell-server-edition/)) | ✅ bis 7 Instanzen |
| vGPU-Support | ✅ (vGPU 19.0, [NVIDIA Blog](https://developer.nvidia.com/blog/nvidia-vgpu-19-0-enables-graphics-and-ai-virtualization-on-nvidia-blackwell-gpus/)) | ✅ |
| NVLink | ❌ (nur PCIe Gen5) | ✅ (Paarweise) |
| Leistungsaufnahme | 600 W (passiv, Server-Kühlung) | ~400 W |
| Formfaktor | PCIe FHFL Dual-Slot, OEM-qualifiziert (u. a. [Lenovo](https://lenovopress.lenovo.com/lp2263-thinksystem-nvidia-rtx-pro-6000-blackwell-server-edition-pcie-gen5-gpu), HPE) | PCIe Dual-Slot |
| Straßenpreis | **~910 k€** | ~31 k€ (lt. Referenz-Angebot) |
### 1.2 Benchmark-Evidenz (der Kern der Argumentation)
Mehrere **unabhängige** Quellen, alle mit vLLM als Serving-Stack:
1. **Single-GPU-Durchsatz:** RTX PRO 6000 schlägt sogar die H100 SXM
(3.140 vs. 2.987 tok/s) bei **28 % niedrigeren Kosten pro Token**
([cloudrift.ai](https://www.cloudrift.ai/blog/benchmarking-rtx6000-vs-datacenter-gpus)).
2. **Unter Parallellast** (unser Szenario!): stärkste Skalierung aller
getesteten Karten; auf Qwen-32B vor A100 **und** H100
([databasemart vLLM-Benchmark](https://www.databasemart.com/blog/vllm-gpu-benchmark-pro6000)).
3. **Bei 100 gleichzeitigen Requests**: bis zu **1,63× höherer Durchsatz als
die H100** ([Akamai-Benchmark](https://www.akamai.com/blog/cloud/benchmarking-nvidia-rtx-pro-6000-blackwell-akamai-cloud)).
4. Kostenanalyse pro Million Token: [Spheron](https://www.spheron.network/blog/rent-nvidia-rtx-pro-6000/),
unabhängige Tests: [HOSTKEY](https://huggingface.co/blog/HOSTKEY/nvidia-rtx-6000-blackwell-server-edition-tests-ben),
Vergleich: [OpenMetal](https://openmetal.io/resources/blog/comparing-the-nvidia-rtx-pro-6000-vs-h100-for-ai-inference/).
Warum schlägt GDDR7 hier HBM3? Die H100 spielt ihre Bandbreite erst bei
Multi-GPU-Tensor-Parallelität über NVLink aus. Bei **einer** Karte limitiert
meist Compute/KV-Cache-Management — und da ist Blackwell schlicht neuer
(mehr FP8/FP4-Durchsatz, größere L2-Caches, besserer Scheduler).
### 1.3 Wann wäre die H100 trotzdem richtig? (Ehrlichkeit fürs Gespräch)
- **Multi-GPU-Modelle**: Modelle > 96 GB über 2+ GPUs gespannt → NVLink
gewinnt deutlich (8× H100 SXM ≈ 3× Durchsatz von 8× RTX PRO 6000).
- **Training/Fine-Tuning im Dauerbetrieb** über mehrere Karten.
- **Extreme Kontextlängen + sehr hohe Batchgrößen** (Bandbreiten-limitiert).
**Keiner dieser Punkte trifft hier zu**: 1 GPU, reine Inference, ≤ 20
gleichzeitige Anfragen, Modelle ≤ 96 GB. Selbst der Wachstumspfad (zweite
RTX PRO 6000, zwei unabhängige vLLM-Replikate) braucht kein NVLink.
### 1.4 Argumentationslinie für den Kunden (Kurzform)
1. „Die H100 ist eine 2022er-Architektur am Ende ihres Zyklus; die RTX PRO
6000 ist NVIDIAs aktuelle Enterprise-Inference-Karte (Blackwell, 2025)."
2. „Für genau unser Szenario — eine Karte, viele gleichzeitige Chat-Anfragen —
ist sie in unabhängigen Benchmarks **gleich schnell bis 1,6× schneller**."
3. „Mehr Speicher (96 vs. 94 GB), ECC, MIG, vGPU — alle Enterprise-Merkmale
vorhanden, OEM-qualifiziert (HPE/Lenovo/Dell)."
4. „**Ein Drittel des Preises.** Die Differenz (~21 k€) finanziert die
eigentliche Wertschöpfung — die Such-Pipeline — oder eine zweite GPU."
5. Einziger technischer Trade-off: kein NVLink und höhere Leistungsaufnahme
(600 W) — beides für diesen Use Case irrelevant bzw. vom Chassis abgedeckt.
⚠️ Vor Angebot prüfen: HPE-Qualifizierung der Karte für das konkrete Chassis
(DL380 Gen12 / DL380a) und vBIOS-Stand für MIG.
### 1.5 Alternativen — vollständig geprüft (Stand Juli 2026)
Re-Evaluation gegen das gesamte Feld, nicht nur gegen die H100:
| Kandidat | VRAM | Preis (ca.) | Bewertung für unseren Fall |
|---|---|---|---|
| **RTX PRO 6000 Blackwell SE** | 96 GB | **~910 k€** | ✅ Empfehlung — s. §1.2, aber Risiken in §1.6 beachten |
| H100 NVL | 94 GB | ~2630 k€ | Ausgereifteste Software-Basis (Hopper/SM90), sonst in allen Benchmarks unterlegen; 3× Preis. **Der risikoärmste, teuerste Weg.** |
| H200 NVL | 141 GB | ~3042 k€ ([IntuitionLabs](https://intuitionlabs.ai/articles/nvidia-ai-gpu-pricing-guide), [JarvisLabs](https://jarvislabs.ai/blog/h200-price)) | 45 GB mehr VRAM als nötig; Preis wie H100+1520 %. Nur sinnvoll bei Modellen > 96 GB — nicht unser Fall. |
| L40S | 48 GB | ~8 k€ | Halber Speicher, weniger als halber Durchsatz (864 GB/s, Ada 2022, kein FP4), kaum billiger. Von der RTX PRO 6000 obsolet gemacht. |
| 2× RTX PRO 5000 Blackwell | 2×48 GB | ~9 k€ | Gleicher Gesamt-VRAM, aber Tensor-Parallel über PCIe (Overhead), doppelte Komplexität, gleiche SM120-Risiken. Kein Vorteil. |
| RTX 5090 (Consumer) | 32 GB | ~2,5 k€ | Kein ECC, keine OEM-/Server-Qualifizierung, EULA-Grauzone im Rechenzentrum, 32 GB zu klein. Nein. |
| AMD MI300X | 192 GB | ~1518 k€ ([gpucost](https://gpucost.org/gpu/mi300x)) | Auf dem Papier attraktiv (192 GB!), ROCm/vLLM inzwischen First-Class ([AMD](https://rocm.blogs.amd.com/software-tools-optimization/vllm-omni/README.html)). Aber: **OAM-Modul, keine PCIe-Einzelkarte** — existiert praktisch nur in 8-GPU-Plattformen, nicht im ProLiant-2U. Dazu ROCm-Betriebsrisiko ohne AMD-Erfahrung im Team. Scheidet formfaktorbedingt aus. |
Fazit der Re-Evaluation: Die Empfehlung **hält**. Die einzige echte
Alternative ist die H100 NVL als „konservative Versicherung" zum 3-fachen
Preis — alle anderen Kandidaten scheitern an Formfaktor, Speicher oder
Preis-Leistung.
### 1.6 Risiken der RTX PRO 6000 SE — ehrlich benannt (wichtig!)
Die Karte ist neue Architektur (Blackwell/SM120), und 2025 bis Anfang 2026
gab es dokumentierte Kinderkrankheiten:
- **Kernel-Kompatibilität**: SM120 ist nicht abwärtskompatibel zu
Hopper-Kerneln; exotische Modellarchitekturen liefen anfangs nicht
(z. B. [DeepSeek-Serie](https://github.com/vllm-project/vllm/issues/26211),
[NVFP4-Kernel](https://github.com/vllm-project/vllm/issues/23497)).
Mainstream-Modelle (Llama, Qwen, Mistral, gpt-oss) sind davon nicht
betroffen.
- **Reset-Bug bei Virtualisierung** (VM-Passthrough): GPU nach VM-Shutdown
in unrecoverable state; ab Treiber 580+ weitgehend behoben. → **Bare-Metal
betreiben** (ohnehin empfohlen).
- Vereinzelte Berichte über GPU-Resets unter Dauerlast und ein
[offenes vLLM-Issue (03/2026)](https://github.com/vllm-project/vllm/issues/36327) —
letzteres betrifft `--tensor-parallel-size 4`, also **Multi-GPU, nicht
unsere Single-GPU-Konfiguration**.
**Warum das Risiko tragbar ist (Stand Juli 2026):**
1. NVIDIA führt die Karte offiziell in den
[vLLM-Release-Notes](https://docs.nvidia.com/deeplearning/frameworks/vllm-release-notes/rel-25-09.html)
(funktionaler Support, CUDA 13.0) und stellt einen eigenen
[vLLM-Container für RTX](https://build.nvidia.com/rtx/vllm) bereit.
2. Systemhäuser liefern inzwischen **vLLM-vorvalidierte Server mit genau
dieser Karte** aus ([VRLA Tech](https://vrlatech.com/running-vllm-on-your-own-hardware-the-production-guide-for-2026/)).
3. HPE-qualifizierte Karte + Support-Vertrag = Hardware-Risiko abgedeckt.
**Absicherung im Projekt:** aktueller Treiber (≥ 580/581), NVIDIA-vLLM-
Container statt Eigenbau, Bare-Metal, Mainstream-Modell, und die Pilotphase
(§4.7) als **Burn-in-Test** nutzen — 2 Wochen Dauerlast vor Produktivsetzung.
Falls der Kunde maximale Risikoaversion über Preis stellt: H100 NVL als
dokumentierte Alternative anbieten und die Differenz transparent machen
(~20 k€ „Versicherungsprämie" für ausgereiftere Software-Basis).
---
## 2. Warum LM Studio (llmster) kein Server ist — Argumentation
LM Studio ist bei den Mitarbeitern bekannt und beliebt — das Argument muss
also respektvoll sein: **das Tool ist gut, aber es löst eine andere Aufgabe.**
| Server-Anforderung | LM Studio / llmster | Server-Stack (vLLM + Open WebUI) |
|---|---|---|
| Benutzerkonten & Login | ❌ keine Benutzerverwaltung | ✅ LDAP/AD, Rollen, Gruppen |
| Wer darf was (Modelle, Daten)? | ❌ ein API-Key für alle | ✅ RBAC pro Gruppe/Ressource |
| 1020 gleichzeitige Anfragen | ❌ llama.cpp-Engine, Anfragen stauen sich | ✅ Continuous Batching |
| Zentrale Wissensbasis (SMB) | ❌ nur lokale Datei-Anhänge pro Chat | ✅ zentrale, gepflegte Indizes |
| Audit/Protokollierung | ❌ | ✅ |
| Betrieb (Updates, Monitoring, HA) | ⚠️ Desktop-App-Zyklus | ✅ Container, Standard-Ops |
Kernsatz fürs Gespräch: *„llmster macht aus LM Studio einen Dienst ohne
Bildschirm — aber nicht ohne die Einzelnutzer-Architektur. Es fehlt alles,
was aus einem laufenden Modell einen Firmendienst macht: Anmeldung,
Berechtigungen, Parallelität, zentrale Datenanbindung."*
Wichtig: Die Mitarbeiter **verlieren nichts** — Open WebUI fühlt sich wie
ChatGPT an (einfacher als LM Studio), und Power-User können LM Studio lokal
weiterverwenden oder per API-Key direkt gegen den Server arbeiten.
---
## 3. Inference-Backend: vLLM vs. Ollama
Beide sprechen die OpenAI-API und funktionieren mit Open WebUI. Der
Unterschied liegt in Architektur und Zielgruppe.
### 3.1 Ist vLLM wirklich effizienter? Ja — deutlich, sobald parallel
Aktuelle Benchmarks (2025/26):
- Bei **50 gleichzeitigen Nutzern**: vLLM ~920 tok/s gesamt, Ollama
plateauiert bei ~155 tok/s; je nach Test **2029× mehr Durchsatz** und
819× niedrigere P95-Latenz ([runaihome](https://runaihome.com/blog/vllm-vs-ollama-when-each-wins-2026/),
[tech-insider](https://tech-insider.org/vllm-vs-ollama-2026/)).
- Peer-reviewte Studie: Ollama erreicht **Engpass bei ~10 gleichzeitigen
Nutzern**, 1330 % Timeouts unter Last; vLLM 100 % Erfolgsquote
([MDPI Applied Sciences](https://doi.org/10.3390/app16115435)).
- Bei **einem einzelnen Nutzer** ist Ollama minimal schneller beim ersten
Token (~45 vs. ~82 ms TTFT) — irrelevant für einen Firmenserver
([Red Hat Benchmark](https://developers.redhat.com/articles/2025/08/08/ollama-vs-vllm-deep-dive-performance-benchmarking),
[SitePoint](https://www.sitepoint.com/ollama-vs-vllm-performance-benchmark-2026/)).
### 3.2 Der Modellwechsel-Trade-off, korrekt dargestellt
| | Ollama | vLLM |
|---|---|---|
| Modellwechsel | ✅ automatisch, lädt/entlädt on-the-fly | ⚠️ 1 Modell pro Instanz, Wechsel = Neustart (12 min) |
| Mehrere Modelle parallel | ⚠️ ja, aber teilen sich GPU unkontrolliert | ✅ mehrere Instanzen mit fester VRAM-Zuteilung |
| Durchsatz unter Last | ❌ s. o. | ✅ |
Die Flexibilität von Ollama ist im Firmenbetrieb **weniger wert, als sie
klingt**: Nicht-Power-User wollen kein Modell wählen — sie wollen, dass es
funktioniert. Ein ungeplanter Modellwechsel entlädt zudem das Modell der
anderen 15 aktiven Nutzer (Kaltstart-Latenz für alle).
**Empfehlung — kein Entweder-oder:**
```
GPU (96 GB, via MIG oder VRAM-Quoten aufteilbar)
├── vLLM #1: Haupt-Chatmodell (fest, z. B. Qwen3-32B FP8) ~40 GB
├── vLLM #2: Embedding-Modell für die Suche ~4 GB
└── optional Ollama: Spielwiese für Power-User Rest
```
Open WebUI kann mehrere Backends gleichzeitig einbinden — die Normalnutzer
sehen nur „Firmen-Assistent", Power-User sehen zusätzlich die
Ollama-Modelle. Damit ist die Kundenfrage („Flexibilität vs. Effizienz")
keine Entscheidung mehr, sondern eine Konfiguration.
### 3.3 Lastabschätzung (100 Mitarbeiter)
Erfahrungswerte für interne Chat-Assistenten: ~3060 % registrieren sich,
davon ~1020 % gleichzeitig aktiv in Spitzen → **515 parallele Anfragen**.
Das bedient eine RTX PRO 6000 mit einem 32B-FP8-Modell unter vLLM komfortabel
(vgl. Benchmarks oben: brauchbare Latenz noch bei 50100 parallelen Requests
mit kleineren Modellen).
---
## 4. Anbindung der Wissensbasis (SMB-Shares) — der Deep Dive
### 4.1 Was technisch passieren muss (unabhängig vom Produkt)
Ein LLM kann nicht „auf den Share schauen". Die Pipeline ist immer:
```
SMB-Share ──mount──► Server (read-only, Service-Account)
Extraktion (PDF, Office, E-Mail…; OCR für Scans)
Chunking + Embedding (Embedding-Modell auf der GPU)
Vektor-Datenbank (Index) ← periodischer Sync (cron)
Retrieval zur Laufzeit: Frage → relevante Chunks → LLM antwortet mit Quellen
```
Die Produktfrage ist nur: **wer betreibt diese Pipeline und wie gut?**
### 4.2 Option A — LM Studio: scheidet aus
Kein zentraler Index möglich. Jeder Nutzer müsste Dateien manuell in seinen
Chat ziehen (RAG pro Sitzung, wenige Dateien). Für „Suchmaschine über die
Firmendaten" schlicht das falsche Werkzeug — unabhängig von der Serverfrage.
### 4.3 Option B — Open WebUI Knowledge + offizielles Sync-Tool `oikb` ⭐
Seit **v0.9.6** hat Open WebUI eine offizielle Lösung genau für unseren Fall
([Docs](https://docs.openwebui.com/features/knowledge-base-sync/),
[GitHub open-webui/oikb](https://github.com/open-webui/oikb)):
- **`oikb`** (CLI, [PyPI](https://pypi.org/project/oikb/)) synchronisiert ein
Verzeichnis — also einen **auf dem Server gemounteten SMB-Share** — in eine
Knowledge Base: inkrementell per SHA-256-Diff, nur neue/geänderte Dateien
werden neu embedded, Löschungen werden nachgezogen, Ordnerstruktur wird
gespiegelt. Ein unveränderter 10.000-Dateien-Bestand re-synct in Sekunden.
- Läuft als **Cron/systemd-Timer pro Share** → vollautomatisch, kein
Nutzer-Zutun.
- **Berechtigungen**: Knowledge Bases sind per Gruppe zugreifbar; Open WebUI
synchronisiert **Gruppen direkt aus LDAP/AD**
([LDAP-Doku](https://docs.openwebui.com/features/authentication-access/auth/ldap/)).
Damit lässt sich die Share-Struktur abbilden:
```
\\fs01\konstruktion ──oikb──► KB "Konstruktion" ──► AD-Gruppe Konstruktion
\\fs01\vertrieb ──oikb──► KB "Vertrieb" ──► AD-Gruppe Vertrieb
\\fs01\allgemein ──oikb──► KB "Allgemein" ──► alle
```
- **Nutzererlebnis Normies**: Vorkonfigurierte „Modelle" in Open WebUI
(z. B. „Konstruktions-Assistent" = Chatmodell + KB Konstruktion fest
verdrahtet). Der Nutzer wählt den Assistenten und fragt auf Deutsch —
kein RAG-Wissen nötig, Antworten mit Quellenangabe (Datei + Passage).
- **Power-User**: können eigene Knowledge Bases anlegen, per `#` gezielt
Kollektionen in den Chat holen, oder per API-Key direkt gegen vLLM arbeiten
(IDE-Integration, Skripte).
**Grenzen (ehrlich einplanen):**
1. **Berechtigungsgranularität = Share/Ordner-Ebene**, nicht NTFS-Datei-ACL.
Wer Zugriff auf die KB „Konstruktion" hat, kann alles darin erfragen.
2. **Skala**: praktikabel bis in den Bereich von einigen zehntausend
Dokumenten pro Kollektion; bei sehr großen Shares selektiv syncen
(Unterordner, Dateitypen-Filter). Für den DB-Unterbau bei Wachstum
**pgvector statt Default** einplanen ([Scaling-Doku](https://docs.openwebui.com/getting-started/advanced-topics/scaling/)).
3. **Extraktionsqualität** hängt von den Dateitypen ab: Office/PDF gut;
**gescannte PDFs brauchen OCR** (Tika/Docling als Extraktions-Engine
konfigurieren); CAD/proprietäre Formate bleiben außen vor.
### 4.4 Option C — Onyx (ehem. Danswer) als dedizierte Such-Anwendung
[Onyx](https://github.com/onyx-dot-app/onyx) ist ein spezialisiertes
Enterprise-Search-Produkt mit 50+ Konnektoren, darunter ein **File Connector
für lokale/Netzlaufwerke** ([Connector-Doku](https://docs.onyx.app/overview/core_features/connectors)) —
SMB-Anbindung also wie bei Option B über einen Mount, aber mit produktisierter
Crawling-/Index-Pipeline.
- **Stärken**: bessere Such-Ergonomie (hybride Suche, Reranking), skaliert
auf große Bestände, Konnektoren für spätere Quellen (SharePoint, Wiki,
E-Mail…), eigenes Berechtigungsmodell.
- **Schwächen für unseren Fall**:
- **Document-Level Permission Sync ist Enterprise Edition** (kostenpflichtig)
und primär für Cloud-Quellen (SharePoint, Google Drive) gebaut — für
SMB-NTFS-ACLs gibt es auch hier **keine fertige Lösung**.
- **Zweite Anwendung** mit eigener UI, eigener Nutzerverwaltung, eigenem
Betrieb (mehrere Container, Vespa-Index, Worker) — spürbar mehr
Betriebsaufwand als Option B.
- Zwei UIs für die Nutzer (Chat in Open WebUI, Suche in Onyx) oder man
ersetzt Open WebUI ganz durch Onyx' Chat — dann verliert man dessen
Flexibilität (Multi-Backend, Power-User-Features).
### 4.5 Option D — Eigenbau-Pipeline (Qdrant/pgvector + eigener Indexer)
Maximale Kontrolle (eigenes ACL-Modell, beliebige Formate/OCR, Anbindung an
Open WebUI über dessen Pipelines/Tools-API) — aber man betreibt und wartet
eine Individualsoftware. Nur gerechtfertigt, wenn **Datei-genaue
NTFS-Berechtigungen** harte Anforderung sind; dann als Projekt kalkulieren
(mehrere Wochen Entwicklung + laufende Pflege).
### 4.6 Entscheidungsmatrix
| Kriterium | B: Open WebUI + oikb | C: Onyx | D: Eigenbau |
|---|---|---|---|
| Aufwand Einführung | **niedrig** (Tage) | mittel (Wochen) | hoch |
| Betriebsaufwand | **niedrig** (1 Stack) | mittel (2 Stacks) | hoch |
| Berechtigungen | Share/Ordner-Ebene via AD-Gruppen | ähnlich; Datei-Ebene nur EE + nicht für SMB | frei gestaltbar |
| Suchqualität große Bestände | gut bis ~10⁴–10⁵ Docs | **sehr gut, skaliert** | je nach Bau |
| Normie-Tauglichkeit | **sehr gut** (ein UI, Assistenten) | gut | je nach Bau |
| Power-User | **sehr gut** (API, eigene KBs, Ollama) | mittel | gut |
| Kosten | Open Source | OSS; Permissions = EE-Lizenz | Entwicklungszeit |
### 4.7 Empfehlung: Phasenmodell
- **Phase 1 (Pilot, ~46 Wochen):** vLLM + Open WebUI + LDAP + `oikb` auf
12 ausgewählte Shares (read-only Service-Account). Misst reale Nutzung,
Suchqualität und die tatsächliche Parallellast — mit minimalem Invest.
- **Phase 2 (Entscheid nach Pilot):** Bleiben = Ausbau Option B (mehr Shares,
pgvector, OCR). Nur bei nachgewiesenem Bedarf (sehr große Bestände, harte
Berechtigungsanforderungen) → Onyx bzw. Eigenbau ergänzen. Die
Investition aus Phase 1 (Server, vLLM, LDAP, Mounts) bleibt vollständig
erhalten — Onyx würde denselben vLLM-Endpunkt nutzen.
Das Phasenmodell ist auch das Verkaufsargument: kein Big-Bang, Budget bleibt
unter Kontrolle, und die GPU-Ersparnis aus §1 finanziert die Pilotphase.
---
## 5. Gesamtbild (Zielarchitektur Phase 1)
```
┌────────────────────────────────────────────┐
Mitarbeiter ────────►│ Open WebUI (LDAP/AD-Login, Gruppen) │
(Browser) │ ├─ „Firmen-Assistent" + KB je Abteilung │
│ └─ Power-User: API-Keys, eigene KBs │
└───────┬────────────────────────┬───────────┘
Power-User ─────────────────►│ OpenAI-API │ Retrieval
(Skripte, IDE, LM Studio ▼ ▼
lokal als Client) vLLM #1 Chat 32B FP8 Vektor-DB (pgvector)
vLLM #2 Embeddings ▲
┌──────────────────────┐ │ oikb-Sync (cron)
│ RTX PRO 6000 96 GB │ SMB-Mounts (ro)
└──────────────────────┘ ▲
\\fs01\... Shares
```
## 6. Offene Fragen an den Kunden (vor Angebotslegung)
1. **Berechtigungen** (kritischster Punkt): Genügt Zugriffssteuerung auf
Share-/Ordner-Ebene via AD-Gruppen — oder müssen Datei-genaue NTFS-ACLs
durchgesetzt werden? (Letzteres = Eigenbau-Anteil, deutlich teurer.)
2. **Datenbestand**: Wie viele Shares, wie viel Volumen, welche Dateitypen?
Anteil gescannter Dokumente (OCR-Bedarf)? CAD-Daten relevant?
3. **Nutzerkreis**: Wie viele der ~100 Mitarbeiter sollen initial angebunden
werden? Gibt es Abteilungen mit Priorität?
4. **H100-Motivation**: Steht hinter dem H100-Wunsch eine konkrete Anforderung
(Training? Zukunftspläne?) oder Markenwahrnehmung? → bestimmt, wie viel
der Argumentation aus §1.4 nötig ist.
5. **Virtualisierung**: Soll die GPU ggf. in eine VM-Umgebung (vGPU/MIG,
Lizenzthema) oder Bare-Metal-Betrieb (empfohlen, einfacher)?
6. **Sprache**: Dokumente überwiegend Deutsch? (Modellwahl: Qwen3/Mistral/
Llama sind mehrsprachig solide; Embedding-Modell muss multilingual sein,
z. B. bge-m3.)
## 7. Quellen
**GPU:**
[NVIDIA RTX PRO 6000 Blackwell SE](https://www.nvidia.com/en-us/data-center/rtx-pro-6000-blackwell-server-edition/) ·
[cloudrift.ai Benchmark](https://www.cloudrift.ai/blog/benchmarking-rtx6000-vs-datacenter-gpus) ·
[Akamai Benchmark](https://www.akamai.com/blog/cloud/benchmarking-nvidia-rtx-pro-6000-blackwell-akamai-cloud) ·
[databasemart vLLM-Benchmark](https://www.databasemart.com/blog/vllm-gpu-benchmark-pro6000) ·
[HOSTKEY Tests](https://huggingface.co/blog/HOSTKEY/nvidia-rtx-6000-blackwell-server-edition-tests-ben) ·
[OpenMetal RTX PRO 6000 vs H100](https://openmetal.io/resources/blog/comparing-the-nvidia-rtx-pro-6000-vs-h100-for-ai-inference/) ·
[Spheron Cost/Mtok](https://www.spheron.network/blog/rent-nvidia-rtx-pro-6000/) ·
[Lenovo Product Guide](https://lenovopress.lenovo.com/lp2263-thinksystem-nvidia-rtx-pro-6000-blackwell-server-edition-pcie-gen5-gpu) ·
[NVIDIA vGPU 19.0](https://developer.nvidia.com/blog/nvidia-vgpu-19-0-enables-graphics-and-ai-virtualization-on-nvidia-blackwell-gpus/) ·
[MIG auf RTX PRO 6000 (Medium)](https://medium.com/@sangjinn/maximize-your-gpu-efficiency-configuring-4-nvidia-mig-instances-on-the-rtx-pro-6000-blackwell-1c9b3714af61)
**vLLM vs Ollama:**
[Red Hat Benchmark](https://developers.redhat.com/articles/2025/08/08/ollama-vs-vllm-deep-dive-performance-benchmarking) ·
[MDPI-Studie](https://doi.org/10.3390/app16115435) ·
[runaihome Konkurrenz-Zahlen](https://runaihome.com/blog/vllm-vs-ollama-when-each-wins-2026/) ·
[tech-insider](https://tech-insider.org/vllm-vs-ollama-2026/) ·
[SitePoint](https://www.sitepoint.com/ollama-vs-vllm-performance-benchmark-2026/)
**Open WebUI / RAG:**
[Knowledge-Doku](https://docs.openwebui.com/features/workspace/knowledge/) ·
[Knowledge Base Sync / oikb](https://docs.openwebui.com/features/knowledge-base-sync/) ·
[oikb GitHub](https://github.com/open-webui/oikb) ·
[LDAP-Doku](https://docs.openwebui.com/features/authentication-access/auth/ldap/) ·
[Scaling-Doku](https://docs.openwebui.com/getting-started/advanced-topics/scaling/)
**Onyx:**
[Onyx GitHub](https://github.com/onyx-dot-app/onyx) ·
[Connector-Übersicht](https://docs.onyx.app/overview/core_features/connectors)