Files
infrastructure/docs/platform/llm-server/encoding/GNENC-001-PLAN_Architecture.md
T
spektr 26fb86781f Encoding: Profile, Queue-, Aufbewahrungs- und Dashboard-Entscheidungen dokumentiert.
Drei HandBrake-Presets (SVT-AV1 10-bit, MKV, Audio-Passthrough) versioniert
unter llm-server/encoding/profiles/; Profilwahl ueber gleichnamige Ordner
unter input/. Gemeinsamer NFS-Mount mit input/- und output/-Unterverzeichnissen.
Input-Loeschung nach Encoding und Validierung, Output bis Abholung, work/ pro
Lauf. Dashboard-Endpunkte fuer Fortschritt und Ressourcen als Statusanzeige.
Eigene Programme liegen kuenftig unter llm-server/encoding/scripts/.
GNENC-000/001 aktualisiert.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-10-19 15:22:31 +02:00

9.8 KiB
Raw Blame History

Arbeitsentwurf

Dokumenten-ID: GNENC-001-PLAN Titel: CPU-basiertes Video-Encoding auf dem KI-Server Stand: 2026-10-05 Status: Nicht finaler Arbeitsentwurf zur Persistierung der Planungsentscheidung

1. Zweck und Abgrenzung

Der physische Server ghostnet-ki soll neben den KI-Workloads einen getrennten Workload zum Encoding von Videodateien ausführen. Der Encoding-Workload gehört nicht zum LLM-Stack. Seine fachliche Architektur, Bedienung und späteren SOPs werden deshalb in diesem eigenen Dokumentationsbereich geführt.

Ansible, Podman, Betriebssystem und hostweite Ressourcenregeln bleiben gemeinsame Plattformbestandteile. Sie werden weiterhin ausschließlich im Infrastructure-Repository verwaltet, damit nicht mehrere Repositories unabhängig konkurrierende Sollzustände auf denselben Host anwenden.

2. Bestätigte Entscheidungen

Thema Entscheidung Nachweisgrenze
Repository Host- und Deployment-Ansible bleibt im bestehenden Infrastructure-Repository angenommen
Dokumentation Encoding liegt unter docs/platform/llm-server/encoding/ und verwendet die Kennung GNENC umgesetzt
Ausführungsidentität eigenes gesperrtes Konto gn-encoding, UID/GID 982 eingerichtet und mit rootless Podman geprüft
Containertrennung eigener rootless Podman-Store und eigener rootverwalteter Quadlet-Pfad eingerichtet; Grundzustand per Ansible verwaltet und verifiziert; noch keine Workload definiert
Rechenressource Encoding ist nach Betreiberfestlegung rein CPU-basiert und erhält keinen GPU-Zugriff Planungsentscheidung; reale Last noch nicht gemessen
Parallelität darf parallel zu AI Production oder AI Testing laufen Planungsentscheidung
Zeitsteuerung nächtlich 00:00–06:00 Uhr Europe/Berlin; am Fensterende geordneter Stopp, unfertige Jobs starten nächtlich erneut Betreiberentscheidung 19.10.2026
Anwendung HandBrake im Image linuxserver/handbrake:1.11.2-ls48 mit gepinntem amd64-Manifest-Digest sha256:fda92bd1b43a07a770b10ad793172b10451ba1690803112dbaf2b48a6148a3c7 Betreiberentscheidung 19.10.2026; Digest aufgelöst und per Pull im gn-encoding-Store bestätigt
Ein-/Ausgabe ein NFS-Export, gemountet auf /var/lib/ghostnet-encoding; input/ und output/ als Unterverzeichnisse Betreiberentscheidung 19.10.2026; Server-Adresse und Export-Pfad offen
Profile drei versionierte HandBrake-Presets (SVT-AV1 10-bit, MKV, Audio-Passthrough) unter llm-server/encoding/profiles/; Auswahl über gleichnamige Ordner unter input/ Betreiberentscheidung 19.10.2026; Presets versioniert
Warteschlange dateibasiert über input/<Profilname>/; genau ein gleichzeitiger Job; unfertige oder fehlerhafte Jobs werden nächtlich wiederholt; Teilresultate in work/ Betreiberentscheidung 19.10.2026
Aufbewahrung Input-Datei wird nach erfolgreichem Encoding und Validierung gelöscht; Output bleibt bis zur Abholung; work/ wird pro Lauf geleert Betreiberentscheidung 19.10.2026
Statusanzeige Dashboard-Endpunkte für Arbeitsfortschritt und System-Ressourcen des Encoding-Workloads Betreiberentscheidung 19.10.2026; technische Umsetzung offen

3. Zielbild

flowchart LR
    HOST[ghostnet-ki]
    PROD[gnai-production\nrootless Podman]
    TEST[gnai-testing\nrootless Podman]
    ENC[gn-encoding\nrootless Podman]
    GPU[beide GPUs]
    CPU[CPU / I-O Budget]
    TIMER[nächtliche systemd-Zeitsteuerung]

    HOST --> PROD
    HOST --> TEST
    HOST --> ENC
    PROD --> GPU
    TEST --> GPU
    ENC --> CPU
    TIMER --> ENC

AI Production und AI Testing bleiben untereinander exklusiv. Der Encoding-Workload ist von dieser KI-Umschaltung unabhängig und darf parallel zur jeweils aktiven KI-Umgebung laufen. Hostwartung kann weiterhin einen Stopp aller Workloads erfordern.

4. Ressourcen- und Zeitsteuerung

Die nächtliche Einplanung allein schützt Production nicht vollständig: Ein Encoding-Lauf kann länger dauern als sein Startfenster, und Inferenz benötigt trotz GPU-Schwerpunkt CPU für Tokenisierung, Netzwerk und Begleitdienste. Die spätere Encoding-Unit soll deshalb mindestens verwalten:

  • ein eindeutig definiertes Zeitfenster mit Zeitzone;
  • Verhalten bei verpasstem Start, Neustart und überlangem Lauf;
  • maximale CPU-Nutzung oder CPU-Gewichtung;
  • niedrigere Scheduling-Priorität gegenüber interaktiven Diensten;
  • I/O-Gewichtung und freien Speicher;
  • geordneten Abbruch beziehungsweise Abschluss am Ende des erlaubten Fensters;
  • Begrenzung auf genau einen gleichzeitigen Encoding-Job.

Konkrete Grenzwerte werden erst nach einem repräsentativen Encoding-Test unter gleichzeitiger Inferenzlast festgelegt. gn-encoding erhält keine Mitgliedschaft in GPU-Gruppen und keine /dev/kfd- oder /dev/dri-Weitergabe.

5. Repository-Grenzen

Am 19.10.2026 wurde das LLM-Server-Projekt fachlich in ein Hauptverzeichnis pro Aufgabe aufgeteilt; die Struktur folgt den Bereichen unter docs/platform/llm-server/:

llm-server/
├── host/ansible/                 # gemeinsame Plattform des physischen Servers
│   ├── playbooks/
│   │   ├── host.yml              # host_baseline, podman_runtime (shared), workload_accounts, amd_gpu_access
│   │   ├── preflight.yml
│   │   ├── bootstrap-deploy-account.yml
│   │   ├── verify-deploy-access.yml
│   │   └── verify-rocm-container.yml
│   └── roles/
│       ├── host_baseline/
│       ├── workload_accounts/
│       ├── amd_gpu_access/
│       └── rocm_container_probe/
├── llm/                          # LLM-Stack; entsteht mit dem AI-Vertical-Slice (GNAI-001 Meilenstein 2)
└── encoding/ansible/             # CPU-Encoding-Workload
    ├── playbooks/
    │   └── video-encoding.yml    # video_encoding
    └── roles/
        └── video_encoding/

host.yml verwaltet ausschließlich gemeinsame Plattformzustände; die gemeinsame Rolle workload_accounts legt dabei auch das Konto gn-encoding an. video-encoding.yml verwaltet den Encoding-spezifischen Zustand des Kontos gn-encoding — seine Pfade, Images, Quadlets, Timer und Health Checks — und setzt die Host-Baseline voraus. Ein künftiges ai.yml im llm/-Projekt darf nur KI-Zustände verändern. Ein späteres site.yml kann die unterstützte Gesamtkonfiguration in definierter Reihenfolge anwenden.

Eigene Programme (z. B. das Queue-/Warteschlangen-Skript) liegen versioniert unter llm-server/encoding/scripts/ (Betreiberentscheidung 19.10.2026). Ein separates Quellcode-Repository wird erst benötigt, wenn eine Oberfläche oder ein umfangreicher Dienst eigenständig entwickelt wird. Ein solches Repository erzeugt ein versioniertes Artefakt oder Image; ausschließlich das Infrastructure- Repository legt fest, welche Version auf dem Server läuft.

6. Aktueller Implementierungsstand

Die gemeinsame Rolle workload_accounts hat am 20.09.2026 eingerichtet:

Konto:       gn-encoding (UID/GID 982)
Konfiguration: /etc/ghostnet-encoding
Daten:         /var/lib/ghostnet-encoding
Eingang:       /var/lib/ghostnet-encoding/input
Ausgang:       /var/lib/ghostnet-encoding/output
Arbeitsdaten:  /var/lib/ghostnet-encoding/work
Quadlets:      /etc/containers/systemd/users/982
Podman-Store:  /var/lib/ghostnet-encoding/.local/share/containers/storage

Passwort und interaktive Shell sind gesperrt. Der systemd-User-Manager läuft dank Linger unabhängig von einer Anmeldung. Der Podman-Store wurde als rootless und getrennt von beiden KI-Stores geprüft. Es wurden noch keine Images oder Container angelegt.

Am 19.10.2026 wurde das Encoding-Ansible-Projekt unter llm-server/encoding/ansible/ eingerichtet. video-encoding.yml verwaltet und verifiziert seitdem den Encoding-Grundzustand: Konto-Identität und Passwort- sperre, subordinate ID-Bereiche, Verzeichnisstruktur, Quadlet-Verzeichnis, Linger und aktiver User-Manager, getrennter rootless Podman-Store sowie die CPU-Isolation (keine GPU-Gruppenmitgliedschaft, kein Lesezugriff auf /dev/kfd oder DRM-Render-Nodes). Solange die offenen Entscheidungen in Abschnitt 7 nicht getroffen sind, stellt die Rolle zusätzlich sicher, dass weder Quadlet-Dateien noch Container für gn-encoding existieren. Check-Mode und zwei aufeinanderfolgende Läufe meldeten jeweils ok=30 changed=0 failed=0. Das gepinnte HandBrake-Image linuxserver/handbrake:1.11.2-ls48 (sha256:fda92bd1…48a3c7) wurde anschließend in den rootless Store von gn-encoding gezogen; der Pull bestätigte den Manifest-Digest.

7. Offene Entscheidungen

Am 19.10.2026 wurden Encoder und Image (HandBrake, gepinnter Digest), das nächtliche Zeitfenster (00:00–06:00 Uhr Europe/Berlin), das Abbruchverhalten am Fensterende (geordneter Stopp, nächtlicher Retry), das Ein-/Ausgabeverfahren (gemeinsamer NFS-Mount mit input/- und output/-Unterverzeichnissen), die drei HandBrake-Presets mit profilbezogener Auswahl über Input-Ordner, die Aufbewahrung (Input-Löschung nach Encoding und Validierung, Output bis zur Abholung, work/ pro Lauf) und die Statusanzeige (Dashboard-Endpunkte für Arbeitsfortschritt und System-Ressourcen) festgelegt. Offen bleiben:

  1. Welche NFS-Server-Adresse, welcher Export-Pfad und welche Mount-Optionen gelten für den gemeinsamen Mount auf /var/lib/ghostnet-encoding?
  2. Wie wird ein fertiger Encode validiert, bevor die Input-Datei gelöscht wird (Vorschlag: HandBrakeCLI-Exit 0, nicht-leere Zieldatei, fehlerfreies ffprobe)?
  3. Wie werden die Dashboard-Endpunkte technisch umgesetzt (Metriken für Arbeitsfortschritt und System-Ressourcen, Transport, Authentifizierung)?
  4. Welche CPU-, Speicher- und I/O-Grenzen schützen die KI-Dienste? Konkrete Grenzwerte werden erst nach einem repräsentativen Encoding-Test unter gleichzeitiger Inferenzlast festgelegt (Abschnitt 4).

Diese Werte werden nicht vorab in Playbooks angenommen.