Skip to main content
Jonathan Andrei
Retour aux billets
Projet lauréat · OpenAI Open Model Hackathon
Sept. 20256 min de lecture

Pourquoi j'ai transformé une Steam Deck en console d'impression 3D

Lauréat du OpenAI Open Model Hackathon, parmi 8 652 participants : des modèles gpt-oss qui tournent hors ligne sur une Steam Deck, contrôle vocal via Vosk, visualisation STL en OpenGL, et OctoPi pour l'impression. De « imprime-moi un crochet pour mon bureau » à un crochet sur le plateau.

Steam Deckgpt-ossVoice3D PrintingAward
Mise à jour : Steam Print a remporté le OpenAI Open Model Hackathon, un défi de 30 000 $ réunissant 8 652 participants (soutenu par OpenAI, NVIDIA et d'autres), pour une création avec gpt-oss, les modèles de raisonnement à poids ouverts d'OpenAI. Voici le projet.

La Steam Deck est la console la plus sous-utilisée dans le tiroir d'un développeur. C'est une machine Linux à écran tactile avec une batterie utile et un GPU compétent. Le OpenAI Open Model Hackathon demandait : qu'est-ce que vous construiriez avec gpt-oss en local ? Ma réponse : « un truc auquel on parle et qui imprime des objets physiques ».

Steam Print en cours d'exécution sur la Steam Deck, montrant l'interface voix-à-impression
Steam Print sur la Deck. Un boîtier Linux portable, un micro, gpt-oss et une imprimante 3D à l'autre bout du réseau.

Pourquoi je l'ai construit

L'impression 3D, c'est puissant, mais ça suppose presque toujours un PC de bureau performant et un slicer lourd comme Cura ouvert en arrière-plan. Je voulais que la boucle soit portable. M'asseoir sur le divan, parler à la Deck, voir une pièce sortir de l'imprimante dans la pièce d'à côté. La Deck a déjà le GPU et l'écran tactile. Il lui manquait un chemin vocal hors ligne, un LLM local et un transfert propre vers l'imprimante.

La boucle voix-à-impression

Vosk fait l'ASR hors ligne. La transcription arrive sur un backend Flask qui passe par gpt-oss:20b pour les intentions rapides et gpt-oss:120b pour les tâches « génère-moi une pièce ». La sortie est un STL (visualisé en PySide6 + OpenGL avec Trimesh) puis remis à une instance OctoPi sur le réseau local pour le slicing, le téléversement et un flux caméra de l'impression.

Ce que ça fait

  • Charge et affiche des fichiers STL sur la Steam Deck avec un visualiseur OpenGL optimisé tactile.
  • Reçoit des commandes vocales hors ligne via Vosk et sounddevice, sans Internet requis pour le chemin micro.
  • Envoie les prompts vocaux à un backend Flask qui exécute gpt-oss:20b ou gpt-oss:120b, lequel génère de la géométrie STL dynamiquement.
  • Slice et téléverse le modèle vers OctoPi sur un Raspberry Pi, puis affiche un flux caméra en direct de l'impression.
  • Exécute le tout comme un flux portable, quasi mains libres, sans aucun slicer de bureau ouvert.
Le visualiseur STL PySide6 + OpenGL dans Steam Print
Le visualiseur STL. PySide6 pour l'habillage, OpenGL pour la géométrie, Trimesh pour les calculs de maillage.

Comment je l'ai construit

Le frontend est en PySide6 avec OpenGL et Trimesh pour la 3D, plus sounddevice et Vosk pour la voix hors ligne. Le backend est un serveur Flask qui reçoit les prompts vocaux de la Deck, les dispatche vers gpt-oss:20b pour les intentions rapides ou gpt-oss:120b pour la génération, et renvoie des octets STL. L'impression passe par l'API OctoPi sur un Raspberry Pi avec module caméra. Chaque tâche longue (requêtes serveur, slicing, impression, boucle micro) tourne sur son propre QThread pour garder l'interface tactile réactive.

Pourquoi deux tailles de modèle

gpt-oss:20b sert de dispatcheur. « tourne de 90 degrés », « lance l'impression », « montre la caméra » : ce genre de classification doit sembler instantané sur l'APU de la Deck. gpt-oss:120b ne se réveille que pour la génération paramétrique, où je lui passe un scaffold de prompt avec des contraintes (unités en mm, épaisseur de paroi imprimable, pas de surplombs au-delà de 45 degrés) et il renvoie une description que le backend convertit en STL. Séparer la charge comme ça a gardé les parties interactives vives sans sacrifier la qualité de génération sur les tâches plus dures.

Pourquoi l'offline comptait pour le jury

Le hackathon portait spécifiquement sur les modèles ouverts qui tournent en local. Un appel GPT-4 connecté aurait été plus rapide. Il aurait aussi raté le point. La contrainte a forcé des choix qui se sont avérés utiles : gpt-oss:20b est assez rapide sur l'APU de la Deck pour la classification d'intentions, et 120b est assez bon pour la génération paramétrique de pièces si on lui donne le bon scaffold de prompt.

Ce qui a été difficile

La concurrence a été le premier mur. Trois threads (Vosk qui écoute, l'aller-retour Flask, le slicing OctoPi) qui piétinent la même boucle d'événements Qt, ça plante l'app rapidement. Pousser chaque appel bloquant dans un worker QThread avec des signaux vers le thread GUI est la seule chose qui a arrêté les crashs. Le deuxième mur, c'était le rendu : même de petits STL ralentissaient le visualiseur, jusqu'à ce que je décime les maillages lourds au chargement et que je mette les buffers OpenGL en cache. Le troisième, c'était de m'assurer que Vosk se comporte bien sur l'Arch Linux de la Deck sans réseau, ce qui voulait surtout dire fixer les fichiers de modèle et le backend sounddevice explicitement.

Flux caméra OctoPi en direct de l'imprimante 3D au travail, vu depuis la Steam Deck
Le flux caméra OctoPi renvoyé dans la Deck. La boucle se referme ici : la voix entre, le plastique sort.

Ce que j'ai appris

  • QThread plus signaux, c'est la seule façon saine de garder une interface PySide6 vivante quand voix, réseau et slicing tournent en même temps.
  • gpt-oss:120b peut faire de la 3D paramétrique utile si on cadre le prompt avec les unités, l'épaisseur de paroi et les contraintes de surplomb dès le départ.
  • Décimer les STL au chargement vaut plus que n'importe quel truc GPU sur l'APU de la Deck.
  • Une séparation modulaire frontend-backend (la Deck parle, le serveur réfléchit, le Pi imprime) rend chaque morceau testable séparément.

La suite

  • Contrôles de slicing (hauteur de couche, remplissage, supports) exposés directement dans l'interface Deck, au lieu de passer par les valeurs par défaut d'OctoPi.
  • Chargement multi-format : OBJ, 3MF, PLY en plus du STL.
  • Optimisation d'impression assistée par IA qui choisit l'orientation, les supports et les paramètres avant le slicing.
  • Récupération cloud depuis des dépôts publics de modèles, pour que la Deck tire un modèle de base que le LLM peut ensuite éditer à la voix.
  • Surveillance multi-appareils pour que plusieurs Decks puissent mettre en file des tâches sur la même ferme OctoPi.
Projet associé

Steam Print: Optimized 3D Printing from Steam Deck

Voir le projet