KI-Box auf dem BC-250

Eine Sony-PS5-APU als lokaler KI-Server: 16 GB GDDR6, 40 Recheneinheiten, Ollama über Vulkan — Aufbau, Einrichtung und Messwerte zum Nachbauen.

ASRock BC-250Fedora ServerOllama · Vulkanqwen3:14b · 36 T/skein BIOS-Flash

Erfahrungsbericht und Anleitung · Stand 03.11.2026 · Nachbau auf eigene Verantwortung

   ████    ████         ████   █████   ███        █   █  █████         ████    ███   █   █
   █   █  █                 █  █      █  ██       █  █     █           █   █  █   █   █ █ 
   ████   █      █████   ███   ████   █ █ █       ███      █    █████  ████   █   █    █  
   █   █  █             █          █  ██  █       █  █     █           █   █  █   █   █ █ 
   ████    ████         █████  ████    ███        █   █  █████         ████    ███   █   █

                PS5-APU  ·  16 GB GDDR6  ·  40 CUs  ·  Ollama über Vulkan

Stand 03.11.2026. Nachbau-Anleitung für eine lokale LLM-Kiste auf dem ASRock BC-250 (AMD „Cyan Skillfish“, Sony-PS5-APU) mit Fedora Server und Ollama über Vulkan. Alle Zahlen sind an unserem Board gemessen, die Quellen stehen am Ende. Anwendungsfall bei uns: nächtlicher Sicherheits-Digest (Wazuh-Events per LLM einstufen) und eine private Chat-KI.

0. Kurzfassung

Was Ergebnis bei uns
Board ASRock BC-250, BIOS P3.00 (Stock, unverändert), 6C/12T, 16 GB GDDR6
Nutzbarer GPU-Speicher 13,5 GiB (Split 512 MB + GTT 13,3 GB, ohne BIOS-Flash)
qwen3:14b Q4 (9,3 GB) 27,8 T/s mit 24 CUs → 36,1 T/s mit 40 CUs
Prompt-Verarbeitung (2.426 Token) 197 → 253 T/s
Leistungsaufnahme ~50 W idle / ~120 W Last (Netzteil-seitig, Community-Messung)
Kosten Board 260 € gebraucht (eBay, DE) + Netzteil ~45 € + NVMe + Lüfter + Druckgehäuse

Was das Board nicht ist: kein Ersatz für eine 24-GB-Karte. 357 GB/s Speicherbandbreite (gemessen in der Community) gegen 1.008 GB/s einer 4090 — Tokens/s sind bandbreitenbegrenzt, 27b-Dense-Modelle passen nicht in 13 GiB. Für 14b-Klasse und MoE-Modelle ist es sehr gut.

Der Weg in zehn Schritten

 [1] Netzteil        [2] Funktionstest      [3] Fedora Server     [4] Split + GTT
   verdrahten  ───▶   Live-USB, lspci  ───▶  NVMe, LV wachsen ───▶  memcfg 512 MB
   12,0 V messen      BIOS: IOMMU aus        dnf upgrade            ttm.pages_limit
        │                                                                 │
        ▼                                                                 ▼
 [10] Betrieb        [9] Messen             [8] 40 CUs            [5-7] Governor,
   Cron/WoL, Digest ◀── T/s, Temps,     ◀──  umr + Boot-     ◀──   Sensoren, Ollama
   Monitoring           Stresstest           Dienst                  (Vulkan, Unit)

1. Hardware

1.1 Board

1.2 Stromversorgung

   8-Pin-PCIe-Stecker, Blick auf die Kabelseite, Rastnase OBEN
   ┌─────┬─────┬─────┬─────┐
   │ GND │ GND │ GND │ GND │   ◀── Reihe mit Rastnase: 4× Masse  → V−
   ├─────┼─────┼─────┼─────┤
   │ 12V │ 12V │ 12V │ GND │   ◀── untere Reihe: 3× +12 V → V+ , 1× Masse → V−
   └─────┴─────┴─────┴─────┘
           ▲ die beiden abnehmbaren "+2"-Pins sind BEIDE Masse

   LRS-350-12 Klemmleiste:   L   N   ⏚  │  V−  V−  V+  V+
                            (230 V)      │  5 Adern  3 Adern

1.3 Kühlung

            ↓↓↓  P12 Pro bläst von oben AUF den Kühlkörper  ↓↓↓
          ┌──────────────────────────────────────────┐
          │ ░░░░░░░░░░░░░░ Lüfter 120 mm ░░░░░░░░░░░░ │
          └──────────────────────────────────────────┘
      ←── ║║║║║║║║║║║║║║ Kühlrippen ║║║║║║║║║║║║║║ ──→   Abluft seitlich
          ╔══════════════════════════════════════════╗
          ║   APU  ·  GDDR6  ·  BC-250-Platine        ║
          ╚══════════════════════════════════════════╝
Behelfslüfter (USB, ungeregelt) ARCTIC P12 Pro an CPU_FAN1
Leerlauf GPU / CPU 47–55 °C / 50–55 °C 45 °C / 51 °C
Last GPU / CPU 71 °C / 83–85 °C 63 °C / 77 °C
GPU-Takt am Ende der Last ~1.420 MHz (gedrosselt) 1.850 MHz
Lüfter – 1.145 → 2.013 U/min, vom Board geregelt

Mit dem geregelten Lüfter ist die Drosselung weg; offen bleibt der Wert im geschlossenen Gehäuse.

1.4 Gehäuse

1.5 Platte

1.6 Stückliste (Amazon.de-Nummern geprüft am 27.10.2026)

Teil Produkt ASIN / Quelle
Board ASRock BC-250, gebraucht (unbenutzter Restbestand, Stock-BIOS) eBay, DE-Händler, 260 €
Netzteil Mean Well LRS-350-12 (siehe Lehre in Abschnitt 8: nächstes Mal lüfterlos) B07F2939RR
Lüfter ARCTIC P12 Pro PST LN, 120 mm, 4-Pin PWM B0FVXTP7P6
Netzeingang Kaltgerätebuchse C14 mit Schalter und Sicherungshalter B0H7X6NK2Z
Stromkabel Board PCIe-8-Pin-Verlängerung (wird am Netzteil-Ende abgeschnitten und verdrahtet) B07RW7FQZN
Aderendhülsen Sortiment mit Crimpzange B09P8B19VB
Kaltgerätekabel C13, 1,8 m B07Y1V1HB2
Schrauben Gehäuse Blechschrauben-Sortiment für den 3D-Druck B0CG673MS3
Schrauben Board PC-Schraubenset #6-32 / M3 B0DFMG3F8K
Magnete Deckel Neodym 8×1 mm (für den Gehäusedeckel) B0BBMY4QNX
NVMe 2280, 250 GB reichen (bei uns Samsung 980 Pro 1 TB aus dem Bestand) z. B. B09F4CT8LV
Werkzeug langer PH2-Schraubendreher (Netzteil-Klemmen hinter dem Board) B000ZEFON4
Optional CH341A-Programmer mit SOIC8-Clip, nur für BIOS-Backup/-Flash. Für den LLM-Betrieb NICHT nötig (Split per memcfg). Achtung: schwarze CH341A-Platinen legen 5 V an den 3,3-V-Flash B0H9SKVSBW
Aus der Werkstatt Sicherung 5×20 mm 4 A träge, 2× M4×8 für das Netzteil, Kabelbinder –

Gehäuse: MakerWorld-Modell (Abschnitt 1.4) auf einem eigenen oder befreundeten 3D-Drucker. Keine Affiliate-Links.

2. Funktionstest vor allem anderen (Rückgabefrist!)

  1. Lüfter auf den Kühlkörper (irgendein 12-V-Lüfter), CPU_FAN1, Monitor an DP, Tastatur, Live-USB (Fedora Workstation Live, Release, keine Beta).
  2. Einschalten, Entf → BIOS: Version ablesen (P3.00), unter Advanced IOMMU → Disabled (Doku: MUST be Disabled), SVM egal (aus lassen). Ein „Chipset“-Menü gibt es im Stock-BIOS nicht — das ist normal.
  3. F11 → vom Stick booten. Im Live-Terminal:
lspci -nn | grep -iE 'vga|display'          # erwartet: Cyan Skillfish [BC-250] [1002:13fe]
free -g                                     # ~7 GiB bei Stock-Split 8/8
cat /sys/class/drm/card*/device/mem_info_vram_total   # 8589934592 bei 8/8
journalctl -k | grep -iE 'amdgpu.*(SMU|VRAM|Display Core)'

Erwartet: SMU is initialized successfully, Display Core … initialized, 8192M of VRAM. Zwei WARNING … dal_irq_service beim Display-Init und eine ACPI-FADT-Warnung sind bekannt und harmlos.

3. Installation

sudo lvextend -l +100%FREE /dev/fedora_localhost-live/root
sudo xfs_growfs /
sudo dnf -y upgrade --refresh
sudo dnf -y install git gcc gcc-c++ make vulkan-tools mesa-vulkan-drivers lm_sensors nvme-cli pciutils zstd umr

4. Speicher-Split und GTT (der entscheidende Teil)

   16 GB GDDR6, EIN Speicher für CPU und GPU (unified)

   Stock (UMA 8192):   ├──────── 8 GB VRAM fest ────────┼──── 8 GB RAM ────┤
                                 GPU sieht 8 GB            OS hat 7,5 GB

   memcfg UMA 512      ├─┬────────────── GTT 13,3 GB ──────────────┬────────┤
   + ttm.pages_limit:   │512 MB      GPU darf bis hierher belegen   │ OS-Rest │
                        VRAM        (Ollama meldet 13,5 GiB)        ~1,5 GB

4.1 Split OHNE BIOS-Flash: bc250_memcfg

Das Stock-BIOS versteckt die UMA-Einstellung (8/8 oder 4/12 fest). Früher wurde dafür ein modifiziertes BIOS geflasht; das ist obsolet: bc250_memcfg (fanoush) schreibt den Wert ins batteriegepufferte CMOS, kein Flash, Rückweg = CMOS-Clear (Jumper/Batterie) oder UMA_SIZE 8192. Quelle geprüft: 259 Zeilen C, nur I/O-Ports 0x72/0x73, Offsets 0x90–0xAB.

git clone https://github.com/fanoush/bc250_memcfg && cd bc250_memcfg && make
sudo ./bc250memcfg                # nur lesen: UMA_SIZE=8192 bei Stock
sudo ./bc250memcfg UMA_SIZE 512   # "512 MB" = dynamisch, GPU nutzt fast alles
sudo reboot

Nach dem Reboot: free -h ≈ 14 GiB, mem_info_vram_total = 536870912.

4.2 GTT-Deckel heben (sonst sieht die GPU nur ~7,5 GB)

sudo grubby --update-kernel=ALL --args="ttm.pages_limit=3407872 ttm.page_pool_size=3407872"
sudo reboot
sudo dmesg | grep "GTT memory"    # erwartet: 13312M of GTT memory ready

(3407872 Seiten × 4 KiB = 13 GiB.) Falle aus der Community: systemd-tmpfiles kann /sys/module/ttm/... überschreiben — darum Kernel-Argument, nicht sysfs.

5. Betriebssystem-Tuning

5.1 Sensoren (nct6683, nur lesen)

echo nct6683 | sudo tee /etc/modules-load.d/99-sensors.conf
echo "options nct6683 force=true" | sudo tee /etc/modprobe.d/options-sensors.conf
sudo modprobe nct6683 && sensors

Liefert Thermistoren, AMD-TSI-Temperatur und die Lüfter-Tachos (fan1–5).

5.2 IOMMU

Im BIOS Disabled (Abschnitt 2). Beleg im Kernel: dmesg | grep -c AMD-Vi = 0.

5.3 GPU-Governor (Pflicht)

Ohne Governor steht die GPU fest auf 1.500 MHz. Empfohlen (Community seit 03/2026): cyan-skillfish-governor-smu — regelt über die SMU-Firmware, kein Kernel-Patch. Quelle geprüft (Rust, unsafe_code = deny, SMU-Mailbox über PCI-Config des Host-Bridge, kein Netz).

sudo dnf copr enable filippor/bazzite
sudo dnf install cyan-skillfish-governor-smu
sudo systemctl enable --now cyan-skillfish-governor-smu
cat /sys/class/drm/card1/device/pp_dpm_sclk    # idle: 1000Mhz *

Config: /etc/cyan-skillfish-governor-smu/config.toml (Spannungskurve; nur nach Messung anfassen, siehe 8).

5.4 Wake-on-LAN

NIC kann Magic Packet; im OS einschalten und im BIOS speichern (bei uns griff WoL erst nach einem BIOS-Speichervorgang):

sudo nmcli con modify "<Verbindungsname>" 802-3-ethernet.wake-on-lan magic
sudo ethtool enp4s0 | grep Wake-on     # erwartet: g

Bei uns weckt die Firewall (OPNsense, Plugin os-wol) die Kiste per Cron morgens, nachts ist sie stromlos.

6. Ollama über Vulkan

Nicht curl | sh, sondern Tarball mit Prüfsumme:

V=v0.40.13; B=https://github.com/ollama/ollama/releases/download/$V
curl -sSL -o ollama-linux-amd64.tar.zst $B/ollama-linux-amd64.tar.zst
curl -sSL -o sha256sum.txt $B/sha256sum.txt
grep ollama-linux-amd64.tar.zst sha256sum.txt   # Hash vergleichen mit: sha256sum ollama-linux-amd64.tar.zst
sudo tar --zstd -xf ollama-linux-amd64.tar.zst -C /usr/local
sudo useradd -r -s /sbin/nologin -U -m -d /usr/share/ollama ollama
sudo usermod -a -G render,video ollama

Unit /etc/systemd/system/ollama.service — die drei Zeilen, die den Unterschied machen, sind kommentiert:

[Unit]
Description=Ollama Service
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/local/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=3
Environment="PATH=/usr/local/bin:/usr/bin:/bin"
Environment="OLLAMA_HOST=0.0.0.0:11434"
# ohne das wird die iGPU verworfen ("dropping integrated GPU")
Environment="OLLAMA_IGPU_ENABLE=1"
# Prompt-Cache AUS: auf dem BC-250 ist RAM = GPU-Speicher (GTT); der
# 8-GiB-Default von llama-server fuellt den RAM und der Runner stirbt per OOM-Kill
Environment="LLAMA_ARG_CACHE_RAM=0"
# Flash Attention + KV-Cache q8_0: gleiche Generierung, weniger Speicher je Kontext
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"
# Vulkan braucht CAP_PERFMON fuer die VRAM-Abfrage (Ollama-Doku)
AmbientCapabilities=CAP_PERFMON
CapabilityBoundingSet=CAP_PERFMON

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload && sudo systemctl enable --now ollama
sudo firewall-cmd --permanent --add-port=11434/tcp && sudo firewall-cmd --reload
journalctl -u ollama | grep "inference compute"
# erwartet: library=Vulkan … description="AMD BC-250 (RADV GFX1013)" … total="13.5 GiB"
ollama pull qwen3:14b
ollama run qwen3:14b --verbose "Antworte in einem Satz: Was ist ein SIEM?"

Falle OOM (bei uns nach 28 Digest-Karten): journalctl -u ollama zeigt Failed with result 'oom-kill', dmesg den llama-server. Ursache ist der Prompt-Cache (srv load_model: use --cache-ram 0 to disable the prompt cache). Fix ist die Zeile LLAMA_ARG_CACHE_RAM=0 oben.

7. 40 Compute Units freischalten (ohne Flash, ohne Kernel-Patch)

Das Board hat 40 CUs, der Treiber aktiviert 24. Zwei Wege: gepatchtes amdgpu-Modul (duggasco, muss nach jedem Kernel-Update neu gebaut werden) oder zur Laufzeit per umr (WinnieLV/bc250-cu-live-manager) — wir nehmen Letzteres: rückbaubar durch Reboot, kein Eingriff in den Kernel.

   Shader-Engines des Cyan Skillfish — je Reihe 5 WGPs à 2 CUs

              WGP0  WGP1  WGP2  WGP3  WGP4
   SE0.SH0  [ ██ ] [ ██ ] [ ██ ] [ ░░ ] [ ░░ ]
   SE0.SH1  [ ██ ] [ ██ ] [ ██ ] [ ░░ ] [ ░░ ]      ██ = ab Werk aktiv (24 CUs)
   SE1.SH0  [ ██ ] [ ██ ] [ ██ ] [ ░░ ] [ ░░ ]      ░░ = per umr zugeschaltet (+16)
   SE1.SH1  [ ██ ] [ ██ ] [ ██ ] [ ░░ ] [ ░░ ]
                                                     Maske je Reihe: 0x07 → 0x1f
sudo dnf install umr        # AMDs Register-Tool, in Fedora enthalten
sudo install -D -m 0755 bc250-cu-live-manager.sh /opt/bc250-cu-live-manager/bc250-cu-live-manager.sh
cd /opt/bc250-cu-live-manager
sudo ./bc250-cu-live-manager.sh status          # CUs active & routed : 24/40
sudo ./bc250-cu-live-manager.sh enable all --yes
sudo ./bc250-cu-live-manager.sh status          # 40/40
# bootfest (systemd-Oneshot, Config /etc/bc250-cu-live-manager.conf):
sudo ./bc250-cu-live-manager.sh write-service-table --yes
sudo ./bc250-cu-live-manager.sh install-service --yes
# Rueckweg: sudo ./bc250-cu-live-manager.sh uninstall-service --yes  (oder stock-dispatch)

Hinweise:

Messung bei uns (qwen3:14b Q4, Ollama, gleiche Prompts):

24 CU 40 CU
Generierung 27,8 T/s 36,1 T/s
Prompt 2.426 Token 197 T/s 253 T/s
80 Digest-Anfragen (je ~1.000 Token Prompt, 1 Zeile Antwort) 610 s 550 s

7.2 Vergleich mit einer PS5 (gleicher Chip, gleiches Modell)

Ein Kollege fährt dasselbe Modell auf einer PS5 mit llama.cpp (b11327, Flash Attention, KV-Cache q8_0, 36 CUs, 2,23 GHz). Nachgemessen bei uns mit Qwen3.5-9B Q4_K_M, Ollama, 40 CUs, noch mit Behelfslüfter:

Qwen3.5-9B Q4_K_M PS5 (llama.cpp) BC-250 (Ollama)
Generierung, kurzer Prompt 45–50 T/s 50,0 T/s
Generierung, ~4,8k-Token-Prompt ~40–50 T/s 47,5 T/s
Prompt-Verarbeitung, sauberer Kontext 340–370 T/s 507 T/s

Tokens/s hängen fast nur an der Modellgröße (Bandbreite): das 14B-Modell liegt bei 36 T/s, das 9B bei 50. Die PS5 ist dem Board also nicht voraus.

7.1 Die zwei abgeschalteten CPU-Kerne (nicht umgesetzt)

Gehen per SMU-Nachricht ohne BIOS-Flash (rw-r-r-0644/bc250-core-unlock, auch als cpu-unlock im cu-live-manager): Kernmaske 0x77 → 0xFF. Flüchtig bis zum Kaltstart, dauerhaft nur per BIOS-DXE-Mod (Boot-Block-Flash, höchstes Risiko). Die Kerne können aus gutem Grund deaktiviert sein (mehrere Stunden stress-ng, dmesg auf MCEs). Bekannter Nebeneffekt: pp_dpm_sclk zeigt danach falsche Werte. Für GPU-Inferenz bringen sie nichts — bei uns bewusst nicht aktiviert.

8. Was bei uns noch offen ist (in dieser Reihenfolge)

  1. Thermik im geschlossenen Gehäuse messen (offen: Drosselung ist mit dem P12 Pro weg).
  2. Spannungskurve im Governor (Doku: 1.500 MHz @ ~900 mV) — nur mit Messung.
  3. llama.cpp direkt gegen Ollama benchen (Community: bis ~2× bei Vulkan).
  4. Nicht geplant: Speichertimings/-takt (stille Fehler), mitigations=off.
  5. Lehre für den nächsten Bau: ein anderes Netzteil. Das LRS-350 ist technisch in Ordnung, aber sein Lüfter läuft unter Last durch und ist laut. Nächstes Mal lüfterlos (Mean Well UHP-350-12) oder ein semi-passives SFX-Netzteil mit nativem PCIe-Stecker, und das Gehäuse gleich dafür zeichnen.

9. Quellen

Kontakt

Fragen, Korrekturen, eigene Messwerte?

Gerne als Technik-Gespräch unter Kollegen — melden Sie sich.

Kontakt aufnehmen