
Un PC gamer devenu serveur IA, qui joue toujours
Notre nœud de calcul était un PC gamer. Il fait désormais tourner des modèles d'IA jour et nuit, n'a pas d'écran, et nous jouons toujours dessus : depuis une console portable Android, partout dans la maison ou dehors, grâce à un serveur de streaming. L'astuce : donner un seul travail à chaque partie de la machine.
Un peu d'histoire
La diffusion de jeux à la maison a commencé avec GameStream de NVIDIA en 2013, conçu pour ses appareils Shield. Moonlight, un client libre, a retrouvé le protocole par rétro-ingénierie et l'a porté sur tous les téléphones et ordinateurs ; Sunshine a ensuite réimplémenté le côté hôte en libre, et Apollo l'a étendu. Une tour dans un coin peut désormais jouer sur une console portable partout dans la maison.
Un travail par puce
- Les cartes NVIDIA : les modèles, ou le jeu pendant que vous jouez (voir Libérer vos cartes graphiques pour l'IA).
- Le GPU intégré : le bureau, et l'encodage du flux vidéo. Son moteur vidéo est distinct des cartes NVIDIA : le streaming ne prend rien à l'IA.
- Un écran virtuel : le serveur de streaming a besoin d'un écran à capturer. Nous lui en donnons un qui n'existe pas physiquement.
1. Un écran qui n'existe pas
On peut dire au noyau qu'un écran est branché sur une sortie, et quel est cet écran, grâce à un fichier EDID (la carte d'identité qu'envoie un vrai écran). Deux paramètres du noyau, sur une sortie du GPU intégré :
video=HDMI-A-1:e drm.edid_firmware=HDMI-A-1:edid/virtual-1080p120.bin
Placez le fichier EDID dans /usr/lib/firmware/edid/. Générez-le en 1920×1080 à 120 Hz avec blanking réduit, et faites de ce mode le mode préféré, sinon le bureau ne le choisira pas par défaut. Il existe des générateurs d'EDID open source ; vérifiez le résultat avant de redémarrer.
- La sortie se désigne par son connecteur (
HDMI-A-1,DP-3…), pas par sa carte : les numéros de carte peuvent changer d'un démarrage à l'autre, le nom du connecteur non. - L'EDID n'est lu qu'au démarrage : tout changement demande un redémarrage.
- Une sortie forcée n'a ni HDR ni taux de rafraîchissement variable.
- Avec le pilote propriétaire NVIDIA chargé,
drm.edid_firmwareseul est ignoré sans prévenir : il faut aussivideo=…:e.
2. Le serveur de streaming
Sunshine est le serveur open source de streaming de jeux ; Apollo en est un fork avec des extras. Trois réglages font la différence sur une machine comme celle-ci :
capture = kms # capture l'affichage directement, latence minimale, tout bureau
encoder = vaapi # encode sur le GPU intégré
adapter_name = /dev/dri/renderD128 # le nœud de rendu du GPU intégré, vérifiez le vôtre
La capture kms demande une capacité supplémentaire (cap_sys_admin) que les paquets posent en général. Le numéro du nœud de rendu change d'une machine à l'autre : trouvez celui du GPU intégré avec ls -l /dev/dri/by-path/.
3. La console
Sur une console portable Android (la nôtre est une AYN Odin 2 Portal), installez Moonlight, ou Artemis, un fork fait pour s'appairer avec Apollo. Appairez avec le code PIN affiché dans la page web du serveur, choisissez le jeu, jouez. Hors de chez vous, passez par votre réseau privé (Tailscale, WireGuard) : n'ouvrez jamais les ports de streaming sur Internet.
Pièges que nous avons payés
Un GPU intégré de la génération Ryzen 7000 décode l'AV1 mais ne sait pas l'encoder. Utilisez le HEVC : l'image est excellente et la console le décode en matériel.
L'interface web du serveur n'enregistrait pas toujours nos modifications. Éditez le fichier de configuration service arrêté, puis lisez le journal pour voir ce qui a vraiment été chargé.
Le réglage output_name est un index dans la liste des écrans du serveur, pas un nom de connecteur. Une mauvaise valeur fait échouer tous les encodeurs à la suite, et le client ne reçoit qu'une erreur.
Oubliez les vieux tutos d'« écran factice » avec xrandr : ils ne marchent que sous X11, pas dans une session Wayland.
Sources
Utile ? Dites-nous ce qu'il faut mesurer ensuite.