GNAI-007: ROCm-Probelauf hinzugefügt.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
Dokumentation für die Infrastruktur eines privaten Homelabs mit öffentlich erreichbaren Webdiensten, einem WireGuard-Zugang und einem dedizierten KI-Server. Dieses Repository hält Architekturentscheidungen, den belegten Betriebsstand und Verfahren für Einrichtung, Betrieb und Sicherheitsabnahme fest.
|
||||
|
||||
> **Projektstand: 20.09.2026.** Die Dokumentationsrevisionen sind zusammengeführt. Mehrere Sicherheitsmaßnahmen und technische Endabnahmen stehen noch aus. Auf dem KI-Server sind Host-Baseline, Podman, getrennte rootless Workload-Konten und der Gerätezugriff der KI-Konten auf beide AMD-GPUs eingerichtet; LLM- und Encoding-Anwendungen sind noch nicht installiert.
|
||||
> **Projektstand: 20.09.2026.** Die Dokumentationsrevisionen sind zusammengeführt. Mehrere Sicherheitsmaßnahmen und technische Endabnahmen stehen noch aus. Auf dem KI-Server sind Host-Baseline, Podman, getrennte rootless Workload-Konten und der Gerätezugriff der KI-Konten auf beide AMD-GPUs eingerichtet. Ein gepinnter `llama.cpp`-ROCm-Build erkennt beide Karten im rootless Testing-Container; dauerhafte LLM- und Encoding-Anwendungen sind noch nicht installiert.
|
||||
|
||||
## Überblick
|
||||
|
||||
@@ -26,7 +26,7 @@ Die drei vorgesehenen VPN-Netzwerkrollen sind **Familie** (gesamtes Heimnetz), *
|
||||
|
||||
| Bereich | Belegter Stand | Nächster Nachweis oder Schritt |
|
||||
| --- | --- | --- |
|
||||
| KI-Server | Debian-Basissystem, Deployment-Zugang, Podman 5.4.2, drei getrennte rootless Workload-Konten und geprüfter Zugriff beider KI-Konten auf `/dev/kfd` sowie zwei AMD-Render-Nodes | ROCm im rootless `llama.cpp`-Container prüfen und danach den Testing-Stack bereitstellen |
|
||||
| KI-Server | Debian-Basissystem, Deployment-Zugang, Podman 5.4.2, drei getrennte rootless Workload-Konten sowie zwei als `gfx1030` und als `llama.cpp`-ROCm-Geräte geprüfte RX 6900 XT | `llama.cpp` als Testing-Quadlet mit geprüftem Modellprofil bereitstellen |
|
||||
| VPN | wg-easy v15.4.0 auf CT 105 aktiv; ein externer Laptop-Teiltest liegt vor | Rollenrechte serverseitig umsetzen und mit erlaubten sowie gesperrten Zielen testen |
|
||||
| Reverse Proxy | NPM auf CT 103 dokumentiert; Fail2Ban laut Betreiber fest gepinnt und wieder in Betrieb | Effektive Jails, Sperren und Wiederanlauf prüfen |
|
||||
| Identität | Keycloak/OIDC laut Betreiber produktiv für Vaultwarden | Öffentlich erreichbare Keycloak-Administration sperren und den OIDC-Login erneut prüfen |
|
||||
@@ -41,11 +41,11 @@ Der [Dokumentationsindex](docs/GNAI-000-DOC_Index.md) enthält die datierten Que
|
||||
| [Plattform-Dokumentation](docs/platform/README.md) | Hostbasis, Zugriffsmodell, Reverse Proxy und VPN |
|
||||
| [KI-Dokumentation](docs/ai/README.md) | KI-Zielarchitektur und nicht finale Ansible-Deployment-Planung |
|
||||
| [Video-Encoding](docs/video-encoding/GNENC-000-DOC_Index.md) | getrennter Planungs- und späterer SOP-Bereich für den CPU-Encoding-Workload |
|
||||
| [Ansible-Control-Projekt](ansible/README.md) | lokale Einrichtung, Preflight, Deployment-Account, Host-Baseline, Podman, Workload-Konten und AMD-GPU-Zugriff |
|
||||
| [Ansible-Control-Projekt](ansible/README.md) | lokale Einrichtung, Preflight, Deployment-Account, Host-Baseline, Podman, Workload-Konten, AMD-GPU-Zugriff und rootless ROCm-Probe |
|
||||
|
||||
## Arbeiten mit dem Repository
|
||||
|
||||
Dieses Repository enthält Dokumentation und ein Ansible-Control-Projekt. Es prüft Inventar, SSH-Zugang, Hostidentität, Betriebssystem und die dokumentierten GPUs. Gemeinsame Rollen verwalten Plattform, Podman und getrennte Workload-Identitäten. KI- und Encoding-Fachdokumentation bleiben in getrennten Bereichen; Images und Container sind noch nicht bereitgestellt. Vor einer Infrastrukturänderung den Ist-Stand am betroffenen Host prüfen, die passende Fachanleitung lesen und die dort genannten Abnahmeschritte dokumentieren.
|
||||
Dieses Repository enthält Dokumentation und ein Ansible-Control-Projekt. Es prüft Inventar, SSH-Zugang, Hostidentität, Betriebssystem und die dokumentierten GPUs. Gemeinsame Rollen verwalten Plattform, Podman und getrennte Workload-Identitäten. KI- und Encoding-Fachdokumentation bleiben in getrennten Bereichen. Im Testing-Store liegt nur das gepinnte ROCm-Probeimage; dauerhafte Anwendungscontainer sind noch nicht bereitgestellt. Vor einer Infrastrukturänderung den Ist-Stand am betroffenen Host prüfen, die passende Fachanleitung lesen und die dort genannten Abnahmeschritte dokumentieren.
|
||||
|
||||
WireGuard-Profile enthalten private Schlüssel. Sie gehören nicht in Git, Ausgaben oder freigegebene Dokumente. Das lokale Verzeichnis `docs/platform/GNAI-006-profiles/` schließt Profil-Dateien über eine eigene `.gitignore` aus; es ist kein Verteiler- oder Backup-Ort für Zugangsdaten.
|
||||
|
||||
|
||||
+44
-4
@@ -184,7 +184,47 @@ On the current host, the verified devices are `/dev/kfd`,
|
||||
remains outside that group. The final convergence run reported
|
||||
`ok=55 changed=0 unreachable=0 failed=0`.
|
||||
|
||||
This proves host-level device permissions only. No ROCm userspace image has
|
||||
been pulled and no GPU workload has run yet. The next workload check must pass
|
||||
these devices into a rootless container with `GroupAdd=keep-groups` and prove
|
||||
that `llama.cpp` detects both cards as `gfx1030`.
|
||||
This proves host-level device permissions. The separate container probe below
|
||||
verifies the next layer without creating a permanent service.
|
||||
|
||||
## Rootless ROCm container probe
|
||||
|
||||
The dedicated verification playbook uses `gnai-testing` and an immutable amd64
|
||||
manifest of the official `llama.cpp` ROCm image:
|
||||
|
||||
```text
|
||||
version: b11058
|
||||
revision: f072b103714dfa1eee531f80b24512faf38e3dd2
|
||||
digest: sha256:b429b8be10d3d0353a09c98f4ab840fe516f779858a28f9fd4e5bdf10bc63cb4
|
||||
```
|
||||
|
||||
It passes `/dev/kfd` and both discovered render nodes with
|
||||
`--group-add=keep-groups`. `rocminfo` must report exactly two `gfx1030` agents,
|
||||
and `llama-server --list-devices` must expose exactly two ROCm devices. No
|
||||
architecture override is set.
|
||||
|
||||
Run the probe from the `ansible/` directory:
|
||||
|
||||
```bash
|
||||
../.venv/bin/ansible-playbook \
|
||||
--inventory inventories/host/hosts.yml \
|
||||
playbooks/verify-rocm-container.yml \
|
||||
--syntax-check
|
||||
|
||||
../.venv/bin/ansible-playbook \
|
||||
--inventory inventories/host/hosts.yml \
|
||||
playbooks/verify-rocm-container.yml \
|
||||
--check \
|
||||
--private-key ~/.ssh/id_ed25519_ghostnet_ai_ansible_deploy
|
||||
|
||||
../.venv/bin/ansible-playbook \
|
||||
--inventory inventories/host/hosts.yml \
|
||||
playbooks/verify-rocm-container.yml \
|
||||
--private-key ~/.ssh/id_ed25519_ghostnet_ai_ansible_deploy
|
||||
```
|
||||
|
||||
The verified live run on 2026-09-20 reported
|
||||
`ok=33 changed=0 unreachable=0 failed=0`. The ephemeral probe containers are
|
||||
removed; the pinned image remains in the separate Testing image store for the
|
||||
next deployment step. This proves ROCm discovery and the `llama.cpp` backend,
|
||||
but not model loading, multi-GPU splitting or inference.
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Verify rootless ROCm access for the AI Testing account
|
||||
hosts: llm_servers
|
||||
become: true
|
||||
gather_facts: true
|
||||
gather_subset:
|
||||
- min
|
||||
|
||||
roles:
|
||||
- role: amd_gpu_access
|
||||
- role: rocm_container_probe
|
||||
@@ -0,0 +1,17 @@
|
||||
# Rootless ROCm container probe
|
||||
|
||||
This verification role pulls one immutable amd64 manifest of the official
|
||||
`llama.cpp` `server-rocm` image into the `gnai-testing` rootless Podman store.
|
||||
It verifies the OCI image revision and build version, then runs
|
||||
`rocminfo` and `llama-server --list-devices` in ephemeral containers.
|
||||
|
||||
The probe uses the same security-relevant options planned for the permanent
|
||||
Quadlet: `/dev/kfd`, only the discovered AMD render nodes and
|
||||
`GroupAdd=keep-groups`. It sets no graphics-architecture override, publishes no
|
||||
port, mounts no model and removes the probe container after execution. The
|
||||
pinned image remains in the Testing store for the subsequent `llama.cpp`
|
||||
deployment.
|
||||
|
||||
Success proves that ROCm sees two `gfx1030` agents and that `llama.cpp` exposes
|
||||
both as usable ROCm devices to the rootless Testing container. It does not yet
|
||||
prove model loading, multi-GPU splitting or inference.
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
rocm_probe_account:
|
||||
name: gnai-testing
|
||||
uid: 981
|
||||
home: /var/lib/ghostnet-ai/testing
|
||||
|
||||
rocm_probe_image: >-
|
||||
ghcr.io/ggml-org/llama.cpp@sha256:b429b8be10d3d0353a09c98f4ab840fe516f779858a28f9fd4e5bdf10bc63cb4
|
||||
rocm_probe_expected_image_revision: f072b103714dfa1eee531f80b24512faf38e3dd2
|
||||
rocm_probe_expected_image_version: b11058
|
||||
rocm_probe_expected_architecture: gfx1030
|
||||
rocm_probe_expected_device_count: 2
|
||||
@@ -0,0 +1,204 @@
|
||||
---
|
||||
- name: Verify ROCm probe declarations and discovered devices
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- rocm_probe_account.name | length > 0
|
||||
- rocm_probe_account.uid | int > 0
|
||||
- rocm_probe_account.home is match("^/")
|
||||
- rocm_probe_image is match("^ghcr\.io/.+@sha256:[0-9a-f]{64}$")
|
||||
- rocm_probe_expected_image_revision is match("^[0-9a-f]{40}$")
|
||||
- rocm_probe_expected_image_version | length > 0
|
||||
- rocm_probe_expected_architecture is match("^gfx[0-9]+$")
|
||||
- rocm_probe_expected_device_count | int > 0
|
||||
- amd_gpu_render_devices | length == rocm_probe_expected_device_count | int
|
||||
fail_msg: ROCm probe inputs or AMD render-device discovery are invalid.
|
||||
|
||||
- name: Read rootless Podman OCI runtime
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- /usr/sbin/runuser
|
||||
- --user
|
||||
- "{{ rocm_probe_account.name }}"
|
||||
- --
|
||||
- /usr/bin/env
|
||||
- "HOME={{ rocm_probe_account.home }}"
|
||||
- "XDG_RUNTIME_DIR=/run/user/{{ rocm_probe_account.uid }}"
|
||||
- /usr/bin/podman
|
||||
- info
|
||||
- --format=json
|
||||
chdir: "{{ rocm_probe_account.home }}"
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
register: rocm_probe_podman_info_command
|
||||
|
||||
- name: Parse rootless Podman OCI runtime
|
||||
ansible.builtin.set_fact:
|
||||
rocm_probe_podman_info: "{{ rocm_probe_podman_info_command.stdout | from_json }}"
|
||||
|
||||
- name: Require crun for rootless keep-groups support
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- rocm_probe_podman_info.host.ociRuntime.name == "crun"
|
||||
- rocm_probe_podman_info.host.security.rootless
|
||||
fail_msg: The ROCm probe requires rootless Podman with the crun OCI runtime.
|
||||
|
||||
- name: Check whether the pinned ROCm image is already present
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- /usr/sbin/runuser
|
||||
- --user
|
||||
- "{{ rocm_probe_account.name }}"
|
||||
- --
|
||||
- /usr/bin/env
|
||||
- "HOME={{ rocm_probe_account.home }}"
|
||||
- "XDG_RUNTIME_DIR=/run/user/{{ rocm_probe_account.uid }}"
|
||||
- /usr/bin/podman
|
||||
- image
|
||||
- exists
|
||||
- "{{ rocm_probe_image }}"
|
||||
chdir: "{{ rocm_probe_account.home }}"
|
||||
changed_when: false
|
||||
failed_when: rocm_probe_image_exists.rc not in [0, 1]
|
||||
check_mode: false
|
||||
register: rocm_probe_image_exists
|
||||
|
||||
- name: Pull the pinned ROCm image into the Testing store
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- /usr/sbin/runuser
|
||||
- --user
|
||||
- "{{ rocm_probe_account.name }}"
|
||||
- --
|
||||
- /usr/bin/env
|
||||
- "HOME={{ rocm_probe_account.home }}"
|
||||
- "XDG_RUNTIME_DIR=/run/user/{{ rocm_probe_account.uid }}"
|
||||
- /usr/bin/podman
|
||||
- pull
|
||||
- "{{ rocm_probe_image }}"
|
||||
chdir: "{{ rocm_probe_account.home }}"
|
||||
changed_when: true
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- rocm_probe_image_exists.rc == 1
|
||||
|
||||
- name: Inspect the pinned ROCm image
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- /usr/sbin/runuser
|
||||
- --user
|
||||
- "{{ rocm_probe_account.name }}"
|
||||
- --
|
||||
- /usr/bin/env
|
||||
- "HOME={{ rocm_probe_account.home }}"
|
||||
- "XDG_RUNTIME_DIR=/run/user/{{ rocm_probe_account.uid }}"
|
||||
- /usr/bin/podman
|
||||
- image
|
||||
- inspect
|
||||
- --format=json
|
||||
- "{{ rocm_probe_image }}"
|
||||
chdir: "{{ rocm_probe_account.home }}"
|
||||
changed_when: false
|
||||
register: rocm_probe_image_inspect_command
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Parse the pinned ROCm image metadata
|
||||
ansible.builtin.set_fact:
|
||||
rocm_probe_image_metadata: >-
|
||||
{{ (rocm_probe_image_inspect_command.stdout | from_json) | first }}
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Verify the pinned ROCm image metadata
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- >-
|
||||
rocm_probe_image_metadata.Labels['org.opencontainers.image.revision'] ==
|
||||
rocm_probe_expected_image_revision
|
||||
- >-
|
||||
rocm_probe_image_metadata.Labels['org.opencontainers.image.version'] ==
|
||||
rocm_probe_expected_image_version
|
||||
fail_msg: The pulled ROCm image metadata does not match the pinned build.
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Detect both AMD GPU architectures through ROCm in a rootless container
|
||||
ansible.builtin.command:
|
||||
argv: >-
|
||||
{{
|
||||
[
|
||||
'/usr/sbin/runuser',
|
||||
'--user', rocm_probe_account.name,
|
||||
'--',
|
||||
'/usr/bin/env',
|
||||
'HOME=' + rocm_probe_account.home,
|
||||
'XDG_RUNTIME_DIR=/run/user/' + (rocm_probe_account.uid | string),
|
||||
'/usr/bin/podman',
|
||||
'run', '--rm', '--pull=never',
|
||||
'--group-add=keep-groups'
|
||||
]
|
||||
+ ((['/dev/kfd'] + amd_gpu_render_devices)
|
||||
| map('regex_replace', '^', '--device=') | list)
|
||||
+ [
|
||||
'--entrypoint=/usr/bin/rocminfo',
|
||||
rocm_probe_image
|
||||
]
|
||||
}}
|
||||
chdir: "{{ rocm_probe_account.home }}"
|
||||
changed_when: false
|
||||
register: rocm_probe_rocminfo_output
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Verify ROCm reported both expected GPU architectures
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- >-
|
||||
(rocm_probe_rocminfo_output.stdout + rocm_probe_rocminfo_output.stderr)
|
||||
| regex_findall("(?m)^\\s*Name:\\s+" ~ rocm_probe_expected_architecture ~ "\\s*$")
|
||||
| length == rocm_probe_expected_device_count | int
|
||||
fail_msg: >-
|
||||
rocminfo did not report the expected architecture for both AMD GPUs.
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Detect both AMD GPUs through llama.cpp in a rootless container
|
||||
ansible.builtin.command:
|
||||
argv: >-
|
||||
{{
|
||||
[
|
||||
'/usr/sbin/runuser',
|
||||
'--user', rocm_probe_account.name,
|
||||
'--',
|
||||
'/usr/bin/env',
|
||||
'HOME=' + rocm_probe_account.home,
|
||||
'XDG_RUNTIME_DIR=/run/user/' + (rocm_probe_account.uid | string),
|
||||
'/usr/bin/podman',
|
||||
'run', '--rm', '--pull=never',
|
||||
'--group-add=keep-groups'
|
||||
]
|
||||
+ ((['/dev/kfd'] + amd_gpu_render_devices)
|
||||
| map('regex_replace', '^', '--device=') | list)
|
||||
+ [rocm_probe_image, '--list-devices']
|
||||
}}
|
||||
chdir: "{{ rocm_probe_account.home }}"
|
||||
changed_when: false
|
||||
register: rocm_probe_device_output
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Verify llama.cpp reported both expected ROCm devices
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- >-
|
||||
(rocm_probe_device_output.stdout + rocm_probe_device_output.stderr)
|
||||
| regex_findall("(?m)^\s*ROCm[0-9]+:")
|
||||
| unique | length == rocm_probe_expected_device_count | int
|
||||
fail_msg: >-
|
||||
The rootless llama.cpp ROCm image did not report both expected GPUs.
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Report verified rootless ROCm devices
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
account: "{{ rocm_probe_account.name }}"
|
||||
image: "{{ rocm_probe_image }}"
|
||||
image_version: "{{ rocm_probe_expected_image_version }}"
|
||||
image_revision: "{{ rocm_probe_expected_image_revision }}"
|
||||
architecture: "{{ rocm_probe_expected_architecture }}"
|
||||
devices: "{{ amd_gpu_render_devices }}"
|
||||
when: not ansible_check_mode
|
||||
@@ -47,7 +47,7 @@ Der KI-Server heißt laut lesendem SSH-Abgleich vom 18.09.2026 `ghostnet-ki`; da
|
||||
|
||||
Die getrennten Schlüsselzugänge für `ghost` und `ghost-agent` wurden am 19.09.2026 erfolgreich getestet. Der persönliche Login wurde vom Betreiber interaktiv bestätigt; der Agentenlogin wurde technisch gegen Benutzername und Hostname geprüft.
|
||||
|
||||
Der KI-Server wurde als frisches Debian-Basissystem begonnen. Inzwischen sind die dokumentierten Ansible-Zugänge, die minimale Host-Baseline und Podman eingerichtet. Die LLM-Anwendungen sind weiterhin nicht installiert; GNAI-003 und GNAI-004 beschreiben für sie ein Zielbild.
|
||||
Der KI-Server wurde als frisches Debian-Basissystem begonnen. Inzwischen sind die dokumentierten Ansible-Zugänge, die minimale Host-Baseline und Podman eingerichtet. Ein gepinntes ROCm-Probeimage liegt im rootless Testing-Store und hat beide GPUs erkannt; dauerhafte LLM-Anwendungen sind weiterhin nicht installiert. GNAI-003 und GNAI-004 beschreiben für sie ein Zielbild.
|
||||
|
||||
Der [Ansible-Deployment-Entwurf](ai/GNAI-007-PLAN_Ansible-Deployment.md) persistiert den seit dem 19.09.2026 fortgeschriebenen Planungs- und Implementierungsstand. Er ist ausdrücklich keine verbindliche Spezifikation und kein Nachweis einer vollständig eingerichteten Deploymentkette. Die dort genannten Runner-, Freigabe- und Secret-Verfahren sind bis zu ihrer Prüfung und formalen Übernahme vorläufig.
|
||||
|
||||
@@ -61,7 +61,9 @@ Die Rolle `podman_runtime` wurde am 20.09.2026 angewendet. Sie installierte Podm
|
||||
|
||||
Die Rolle `workload_accounts` richtete am 20.09.2026 die gesperrten Konten `gnai-production` (UID/GID 980), `gnai-testing` (981) und `gn-encoding` (982) mit festen, getrennten SubID-Bereichen ein. Konfiguration bleibt rootverwaltet; Daten, rootless Podman-Stores und persistente systemd-User-Manager sind pro Workload getrennt. Der korrigierte Gesamtlauf meldete `ok=36 changed=0 unreachable=0 failed=0` und bestätigte drei unterschiedliche rootless Graph Roots. Images und Container wurden nicht angelegt.
|
||||
|
||||
Die Rolle `amd_gpu_access` bestätigte am 20.09.2026 zwei Sapphire-Navi-21-Geräte `1002:73bf` mit dem Kernel-Treiber `amdgpu`, `/dev/kfd` sowie die zugehörigen Render-Nodes `/dev/dri/renderD128` und `/dev/dri/renderD129`. Alle drei Geräte verwenden die Gruppe `render`. `gnai-production` und `gnai-testing` besitzen nachweislich Lese-/Schreibzugriff; `gn-encoding` erhielt keine GPU-Gruppe. Nach Beseitigung einer konkurrierenden Gruppenverwaltung endete der Gesamtlauf mit `ok=55 changed=0 unreachable=0 failed=0`. ROCm im Container und tatsächliche Inferenz sind damit noch nicht nachgewiesen.
|
||||
Die Rolle `amd_gpu_access` bestätigte am 20.09.2026 zwei Sapphire-Navi-21-Geräte `1002:73bf` mit dem Kernel-Treiber `amdgpu`, `/dev/kfd` sowie die zugehörigen Render-Nodes `/dev/dri/renderD128` und `/dev/dri/renderD129`. Alle drei Geräte verwenden die Gruppe `render`. `gnai-production` und `gnai-testing` besitzen nachweislich Lese-/Schreibzugriff; `gn-encoding` erhielt keine GPU-Gruppe. Nach Beseitigung einer konkurrierenden Gruppenverwaltung endete der Gesamtlauf mit `ok=55 changed=0 unreachable=0 failed=0`. Dieser Rollenlauf allein wies ROCm im Container oder tatsächliche Inferenz noch nicht nach.
|
||||
|
||||
Das getrennte Playbook `verify-rocm-container.yml` lud am 20.09.2026 für `gnai-testing` den offiziellen `llama.cpp`-ROCm-Build `b11058` als unveränderliches amd64-Manifest `sha256:b429b8be10d3d0353a09c98f4ab840fe516f779858a28f9fd4e5bdf10bc63cb4`. Mit `/dev/kfd`, beiden Render-Nodes und `keep-groups` meldete `rocminfo` genau zwei `gfx1030`-Agents; `llama-server --list-devices` meldete `ROCm0` und `ROCm1` als Radeon RX 6900 XT. Der abschließende Lauf endete mit `ok=33 changed=0 unreachable=0 failed=0`. Die Probecontainer wurden entfernt; dauerhafter Container-, Modell- und Inferenzbetrieb sind damit noch nicht abgenommen.
|
||||
|
||||
## 3. Sicherheitsbefunde mit Priorität
|
||||
|
||||
@@ -116,4 +118,14 @@ deckte auf, dass `workload_accounts` ergänzende Gruppen wieder entfernte. Nach
|
||||
Der Abschlusslauf war mit `changed=0` idempotent; Images und Container blieben
|
||||
weiterhin leer.
|
||||
|
||||
Der anschließende rootless ROCm-Probelauf verwendete das Image ausschließlich
|
||||
über seinen amd64-Manifest-Digest. Die OCI-Labels bestätigten Build `b11058`
|
||||
und Revision `f072b103714dfa1eee531f80b24512faf38e3dd2`. Zwei kurzlebige
|
||||
Container prüften mit denselben minimalen Geräteoptionen zunächst die
|
||||
Architektur über `rocminfo` und anschließend die Geräteerkennung von
|
||||
`llama-server`. Beide RX 6900 XT wurden als `gfx1030` und als getrennte
|
||||
`ROCm0`-/`ROCm1`-Geräte erkannt. Der finale Wiederholungslauf meldete
|
||||
`changed=0`; das Image bleibt im Testing-Store, laufende Container, Modelle
|
||||
und Inferenz wurden nicht eingerichtet.
|
||||
|
||||
Die WireGuard-Evidenz bleibt der Teiltest vom 12.09.2026: CachyOS-Laptop von WAN, Handshake, Ping auf Gateway/Proxmox und direkter IPv4-Internetpfad bestanden; KI-Server war ausgeschaltet. Neue Rollen, weitere Clientvarianten, Gateway-GUI-Zugriff, WAN-/IPv6-Isolation, Neustart und Restore sind noch nicht abgenommen. GNAI-006 ist erst nach Klärung der offenen Werte, Umsetzung und dokumentierter Abnahme technisch abgeschlossen.
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
| 2026-09-20 | 0.9 | spektr / Codex | getrennte rootless Konten für AI Production, AI Testing und CPU-Encoding eingerichtet; Parallelitäts- und Repository-Grenzen ergänzt |
|
||||
| 2026-09-20 | 0.10 | spektr / Codex | ROCm als Backend für zwei RX 6900 XT, initialen `llama.cpp`-Modellstand und Layer-Split mit gleicher GPU-Gewichtung festgehalten |
|
||||
| 2026-09-20 | 0.11 | spektr / Codex | AMD-Gerätezugriff für beide rootless KI-Konten implementiert, angewendet und idempotent geprüft |
|
||||
| 2026-09-20 | 0.12 | spektr / Codex | gepinnten rootless ROCm-Probelauf für Testing implementiert; zwei `gfx1030`-Agents und zwei `llama.cpp`-ROCm-Geräte nachgewiesen |
|
||||
|
||||
---
|
||||
|
||||
@@ -122,7 +123,7 @@ Planungsrichtung und noch nicht bestätigten Implementierungsdetails.
|
||||
|
||||
| Thema | Aktueller Planungsstand | Verbindlichkeit / Nachweis |
|
||||
| --- | --- | --- |
|
||||
| Konfigurationsmanagement | Ansible beschreibt Basissystem, Laufzeitumgebung, Dienste und Konfiguration | Control-Projekt, Preflight, `host_baseline`, `podman_runtime` und `workload_accounts` vorhanden und angewendet; GPU- und Anwendungsrollen fehlen noch |
|
||||
| Konfigurationsmanagement | Ansible beschreibt Basissystem, Laufzeitumgebung, Dienste und Konfiguration | Control-Projekt, Preflight, `host_baseline`, `podman_runtime`, `workload_accounts`, `amd_gpu_access` und der ROCm-Container-Probelauf vorhanden und angewendet; Anwendungsrollen fehlen noch |
|
||||
| Quell- und Freigabeverfahren | Änderungen über Gitea-Branches und Pull Requests; kein regulärer Direkt-Push auf `main` | vorgesehen; Branch-Schutz noch nicht geprüft oder eingerichtet |
|
||||
| CI | Pull Requests erhalten Lint-, YAML- und Ansible-Syntaxprüfungen ohne produktive Zugangsdaten | vorgesehen; Workflow noch nicht vorhanden |
|
||||
| Produktionsausführung | Gitea Actions startet Ansible über eine dedizierte Production-Berechtigungsstufe | bevorzugte Lösung; Gitea-Version, Runner-Trennung und Actions-Funktion noch zu prüfen |
|
||||
@@ -391,8 +392,11 @@ Als Ausgangspunkt dient eine bereits auf einer RX 7900 XTX verwendete
|
||||
Podman-Compose-Konfiguration. Die Serverumsetzung wird daraus mit folgenden
|
||||
Abweichungen als rootless Quadlet erzeugt:
|
||||
|
||||
- das Image `ghcr.io/ggml-org/llama.cpp:server-rocm` wird auf eine geprüfte
|
||||
Version und den zugehörigen Digest festgelegt;
|
||||
- das Image `ghcr.io/ggml-org/llama.cpp:server-rocm` ist für den ersten
|
||||
Testing-Stand als Build `b11058`, Revision
|
||||
`f072b103714dfa1eee531f80b24512faf38e3dd2` und amd64-Manifest
|
||||
`sha256:b429b8be10d3d0353a09c98f4ab840fe516f779858a28f9fd4e5bdf10bc63cb4`
|
||||
festgelegt;
|
||||
- `/dev/kfd` und die tatsächlich benötigten `/dev/dri`-Geräte werden explizit
|
||||
eingebunden; `GroupAdd=keep-groups` erhält die nötigen ergänzenden
|
||||
Geräte-Gruppen im rootless Container;
|
||||
@@ -442,12 +446,13 @@ angebundenen Slot läuft. `row` wird wegen seiner Ablösung im aktuellen
|
||||
mehr Kommunikation zwischen den Karten und ist mit dem geplanten
|
||||
quantisierten V-KV-Cache derzeit nicht kompatibel.
|
||||
|
||||
Vor dem dauerhaften Start muss ein begrenzter Test `gfx1030`, beide GPUs,
|
||||
Device-Reihenfolge, verfügbaren VRAM und die tatsächliche 1:1-Verteilung in
|
||||
den `llama.cpp`-Startlogs bestätigen. Zusätzlich werden Prompt-Verarbeitung,
|
||||
Token-Generierung, VRAM-Nutzung und Stabilität bei 51.200 Token Kontext
|
||||
gemessen. Der 1:1-Wert ist erst nach diesem Test ein abgenommener
|
||||
Betriebsparameter.
|
||||
Der rootless Container-Probelauf hat inzwischen zwei `gfx1030`-Agents sowie
|
||||
`ROCm0` und `ROCm1` mit jeweils rund 16 GiB VRAM bestätigt. Vor dem dauerhaften
|
||||
Start muss ein begrenzter Modelltest noch die Device-Reihenfolge und die
|
||||
tatsächliche 1:1-Verteilung in den `llama.cpp`-Startlogs bestätigen. Zusätzlich
|
||||
werden Prompt-Verarbeitung, Token-Generierung, VRAM-Nutzung und Stabilität bei
|
||||
51.200 Token Kontext gemessen. Der 1:1-Wert ist erst nach diesem Test ein
|
||||
abgenommener Betriebsparameter.
|
||||
|
||||
---
|
||||
|
||||
@@ -627,8 +632,9 @@ nicht als Nachweis einer erfolgreichen Einrichtung.
|
||||
- Podman- und Quadlet-Grundruntime sowie getrennte rootless Workload-Konten
|
||||
eingerichtet und geprüft;
|
||||
- rootless Host-Gerätezugriff auf beide RX 6900 XT eingerichtet und geprüft;
|
||||
- ROCm-Funktion im rootless Container prüfen;
|
||||
- `llama.cpp` und lokaler Funktionstest;
|
||||
- ROCm-Funktion und `llama.cpp`-Geräteerkennung im rootless Testing-Container
|
||||
mit gepinntem Image geprüft;
|
||||
- `llama.cpp` mit Modell und lokalem Inferenztest;
|
||||
- Wiederanlauf nach geplantem Reboot prüfen.
|
||||
|
||||
### Phase E – Anwendungen und Veröffentlichung
|
||||
@@ -676,9 +682,9 @@ Vor der technischen Spezifikation sind mindestens folgende Punkte zu klären:
|
||||
Wiederanlauf von Production sicher, wenn Runner oder Testing ausfallen?
|
||||
15. Welche internen Hostnamen und Ports erhält Testing, und welche LAN-/VPN-
|
||||
Rollen dürfen darauf zugreifen?
|
||||
16. Funktioniert der benötigte AMD-GPU-Zugriff zuverlässig aus den getrennten
|
||||
rootless Konten, und welche Gruppen-, Device- und Containeroptionen sind
|
||||
dafür minimal erforderlich?
|
||||
16. Muss der für Testing nachgewiesene AMD-GPU-Zugriff vor der ersten
|
||||
Production-Freigabe mit demselben gepinnten Image separat unter
|
||||
`gnai-production` abgenommen werden?
|
||||
17. Wie wird ein Testing-Deployment eines Pull-Request-Commits in der
|
||||
eingesetzten Gitea-Version autorisiert, ohne Production-Secrets oder
|
||||
Production-Runner für veränderbaren PR-Code verfügbar zu machen?
|
||||
@@ -844,26 +850,48 @@ bleibt ohne GPU-Gruppe. Der korrigierte Gesamtlauf endete mit
|
||||
`ok=55 changed=0 unreachable=0 failed=0`. Weder ein ROCm-Image noch ein
|
||||
Container oder eine Inferenz wurden dabei ausgeführt.
|
||||
|
||||
Danach wurde `verify-rocm-container.yml` mit der eigenständigen Rolle
|
||||
`rocm_container_probe` ergänzt. Das Playbook wiederholt zunächst den
|
||||
Host-Gerätenachweis und arbeitet anschließend ausschließlich im rootless
|
||||
Podman-Store von `gnai-testing`. Es verwendet das offizielle
|
||||
`llama.cpp`-ROCm-Image als unveränderliches amd64-Manifest
|
||||
`sha256:b429b8be10d3d0353a09c98f4ab840fe516f779858a28f9fd4e5bdf10bc63cb4`
|
||||
und prüft dessen OCI-Labels auf Build `b11058` und Revision
|
||||
`f072b103714dfa1eee531f80b24512faf38e3dd2`.
|
||||
|
||||
Die ephemeren Probecontainer erhielten nur `/dev/kfd`, die beiden zuvor
|
||||
ermittelten Render-Nodes und `keep-groups`; ein
|
||||
`HSA_OVERRIDE_GFX_VERSION` wurde nicht gesetzt. `rocminfo` meldete genau zwei
|
||||
GPU-Agents mit `gfx1030`. `llama-server --list-devices` meldete getrennt
|
||||
`ROCm0` und `ROCm1`, beide als AMD Radeon RX 6900 XT mit jeweils rund 16 GiB
|
||||
VRAM. Der Abschlusslauf endete mit
|
||||
`ok=33 changed=0 unreachable=0 failed=0`. Die Probecontainer wurden durch
|
||||
`--rm` entfernt; das gepinnte Image bleibt für den folgenden Testing-Aufbau im
|
||||
Store. Modellladen, Layer-Verteilung und Inferenz wurden noch nicht geprüft.
|
||||
|
||||
---
|
||||
|
||||
## 15. Abschlussgrenze dieses Entwurfs
|
||||
|
||||
Mit Version 0.11 sind der aktuelle Planungsstand, der ausdrücklich begrenzte
|
||||
Mit Version 0.12 sind der aktuelle Planungsstand, der ausdrücklich begrenzte
|
||||
Ansible-Preflight, der verifizierte Deployment-Account und die angewendete
|
||||
minimale Host-Baseline, die Podman-/Quadlet-Grundruntime und die getrennten
|
||||
Workload-Konten sowie deren begrenzter AMD-Gerätezugriff persistiert.
|
||||
Workload-Konten, deren begrenzter AMD-Gerätezugriff sowie der rootless
|
||||
ROCm-/`llama.cpp`-Gerätenachweis für Testing persistiert.
|
||||
Insbesondere wurden noch nicht:
|
||||
|
||||
- ein Gitea Runner angelegt,
|
||||
- Gitea Actions oder Schutzregeln konfiguriert,
|
||||
- eine ROCm-Container- oder Anwendungsrolle, ein Production-Inventar oder ein
|
||||
- eine dauerhafte `llama.cpp`-Anwendungsrolle, ein Production-Inventar oder ein
|
||||
Vault erstellt,
|
||||
- eine Production- oder Testing-Umgebung eingerichtet oder voneinander
|
||||
abgenommen,
|
||||
- ROCm-Userspace, GPU-Container oder Anwendungen auf dem KI-Server installiert,
|
||||
- ein dauerhafter GPU-Container, ein Modell oder eine Anwendung auf dem
|
||||
KI-Server eingerichtet,
|
||||
- Backups oder Rollbacks praktisch getestet oder
|
||||
- die geplante Deploymentkette technisch abgenommen.
|
||||
|
||||
Der nächste technische Schritt ist ein begrenzter rootless ROCm-Container-Test
|
||||
für beide KI-Konten, der beide Karten als `gfx1030` erkennen muss. Darauf bauen
|
||||
die `llama.cpp`-Rolle, das initiale Testing-Modellprofil und später LiteLLM auf.
|
||||
Der nächste technische Schritt ist die `llama.cpp`-Rolle für Testing. Sie soll
|
||||
das gepinnte Image als rootless Quadlet betreiben, das initiale Modell mit
|
||||
geprüfter Checksumme einbinden und den vorgesehenen Layer-Split sowie eine
|
||||
reale Inferenz abnehmen. Darauf baut anschließend LiteLLM auf.
|
||||
|
||||
Reference in New Issue
Block a user