← Retour au portfolio English

Installation volumétrique auto-observante

Vue d'ensemble de l'architecture — sous-système documenté : aida-stream-llm-analysis

Objectif

Les spectateurs se tiennent autour d'une sphère d'un mètre. Un projecteur caché sous la table restitue en direct sur sa surface un nuage de points les représentant, reconstruit à partir de trois caméras de profondeur. Ce même nuage de points conditionne aussi un pipeline visuel génératif, de sorte que le mouvement des spectateurs façonne littéralement l'imagerie apparaissant sur la sphère. Une caméra séparée observe l'ensemble de l'installation depuis l'extérieur, et un modèle vision-langage décrit ce qu'il voit — en deux langues — projetant cette description sous forme de texte sur la sphère, tandis qu'une version condensée de celle-ci est réinjectée comme un prompt qui oriente l'évolution suivante de l'imagerie générée. L'installation s'observe elle-même, s'explique elle-même, et change à cause de ce qu'elle a dit — pendant que les personnes autour d'elle lui font subir la même chose depuis l'autre direction.

Capture volumétrique et projection sphérique

Capture volumétrique et projection sphérique Trois caméras de profondeur Orbbec alimentent Carto, un programme de reconstruction volumétrique basé sur Godot, qui pilote à la fois la projection sphérique vue par les spectateurs et conditionne un pipeline visuel génératif Stable Diffusion avec le nuage de points reconstruit. 3 caméras de profondeur Orbbec Capture volumétriquedes spectateurs Carto (moteur Godot) Reconstruit la scène en nuage de points Projection sphérique Sphère d'1m, projecteurcaché sous la table Pipeline visuel génératif Le nuage de pointsconditionne Stable Diffusion Les spectateurs autour de la sphère deviennent l'entrée en direct du modèle génératif
La capture de profondeur se divise vers l'affichage de la sphère et l'entrée du pipeline génératif

Trois caméras de profondeur Orbbec capturent les spectateurs autour de la table. Carto, un programme personnalisé de capture volumétrique et de reconstruction construit sur le moteur Godot, transforme cela en un nuage de points en direct. Ce nuage de points pilote deux choses à la fois : l'image projetée sur la sphère d'un mètre (via un projecteur caché sous la table de l'installation), et l'entrée de conditionnement d'un pipeline visuel génératif Stable Diffusion — de sorte que les personnes physiquement présentes constituent, en effet, l'entrée en direct du modèle.

La boucle d'auto-observation par LLM

Boucle de rétroaction d'auto-observation par LLM Une caméra fisheye AIDA observe l'ensemble de l'installation. Un modèle vision-langage dans LM Studio décrit la scène en anglais et en français. Cette description est à la fois projetée en texte sur la sphère et réduite en mots-clés, qui orientent le pipeline visuel génératif. Les nouveaux visuels apparaissent sur la sphère et sont observés à nouveau par la même caméra, bouclant la boucle. Caméra fisheye AIDA Observe l'ensemblede l'installation Modèle vision-langage LM Studio Décrit la scène, en anglais et en français Superposition de texte sur la sphère Par-dessus le nuage depoints et les visuels Extraction de mots-clés 1 à 3 mots-clés concrets,anglais seulement Pipeline visuel génératif Les mots-clés orientent l'imagerie évolutive ↻ de nouveaux visuels apparaissent sur la sphère et sont observés à nouveau par la même caméra — l'installation s'observant évoluer elle-même
Une boucle fermée : la propre sortie de l'installation devient sa prochaine entrée

Une caméra AIDA N200, montée pour voir l'ensemble de l'installation (pas seulement la sphère), diffuse via SRT. Un modèle vision-langage exécuté localement dans LM Studio décrit périodiquement ce qu'il voit, une fois en anglais et une fois en français, chacune envoyée comme son propre message OSC et projetée en texte par-dessus la sphère — superposée à la fois au nuage de points volumétrique et aux visuels générés. La description anglaise est en outre réduite à un à trois mots-clés concrets, qui sont réinjectés dans le pipeline visuel génératif comme un court prompt, infléchissant la façon dont l'imagerie évolue. Comme la caméra AIDA voit aussi ce que la sphère affiche actuellement, les nouveaux visuels qu'elle produit sont observés, décrits, et à nouveau distillés en mots-clés au cycle suivant — une boucle fermée où la propre sortie de l'installation devient sa propre entrée suivante, indépendamment de (mais en parallèle avec) l'influence volumétrique directe des spectateurs sur ce même pipeline génératif.

aida-stream-llm-analysis : fonctionnement interne du pipeline

Le sous-système d'observation et de rétroaction est un petit ensemble de scripts orchestrant un cycle périodique capture → analyse → résumé → diffusion, tous coordonnés via un fichier image partagé et des messages OSC.

Fonctionnement interne du pipeline aida-stream-llm-analysis capture_loop_srt.sh rafraîchit une image en arrière-plan. manage_lmstudio.sh assure que le modèle vision-langage est chargé en CPU seul. analyze_latest_frame.py exécute une passe anglaise puis française. summarize_keywords.py réduit le texte anglais en mots-clés. Les trois résultats sont envoyés comme messages OSC séparés. Un processus overnight_monitor.sh séparé journalise indépendamment l'état du GPU, des processus et du disque. capture_loop_srt.sh Rafraîchit un JPEGtoutes les ~10s via SRT manage_lmstudio.sh Assure le serveur actif, modèle chargé en CPU seul analyze_latest_frame.py Passe anglaise, puis passe française summarize_keywords.py Réduit le texte anglais en mots-clés Sortie OSC, 3 ports Descriptions et mots-clés vers les visuels overnight_monitor.sh tourne indépendamment, journalisant GPU, processus, et disque toutes les 60s pour un fonctionnement de nuit sans surveillance
Le cycle capture → analyse → résumé → diffusion, plus une surveillance de santé indépendante

Capture — capture_loop_srt.sh

S'exécute en continu en arrière-plan : se connecte au sous-flux SRT de la caméra AIDA (srt://<ip_camera>:<port>?streamid=<id>), capture exactement une image avec ffmpeg, l'écrit à un chemin fixe (/tmp/latest_frame.jpg), se déconnecte, et attend l'intervalle configuré (10 s par défaut) avant de recommencer. Chaque connexion est volontairement de courte durée — le côté analyse ne touche jamais la caméra directement, seulement le fichier que ce script maintient.

Analyse — analyze_latest_frame.py

Lit l'image actuellement présente à ce chemin, l'encode en base64 dans une requête chat-completions vers l'API locale compatible OpenAI de LM Studio, et envoie la réponse du modèle en un seul message OSC. Il n'a aucune dépendance caméra — tout ce qui concerne la caméra relève entièrement du script de capture. Détails de conception notables :

Extraction de mots-clés — summarize_keywords.py

Purement texte-entrée/texte-sortie, sans caméra ni image impliquée : prend une description (la sortie anglaise ci-dessus), demande au même modèle LM Studio de la réduire à un à trois mots-clés concrets d'objets réels — avec instruction explicite d'éviter le langage abstrait ou émotionnel — ajoute un suffixe fixe ("fisheye 250 degrees", nommant la géométrie de l'objectif de la caméra AIDA elle-même) et envoie le résultat combiné en OSC. Le suffixe est une chaîne fixe, pas une sortie du modèle, donc il est toujours exact quoi que retourne le modèle.

Orchestration — run_pipeline.sh

Relie tout ce qui précède en un cycle unique qui tourne en continu :

  1. Confirme que LM Studio est prêt (via manage_lmstudio.sh) avant de toucher la caméra de quelque façon que ce soit.
  2. Démarre la boucle de capture en arrière-plan, en suivant son PID pour un arrêt propre.
  3. Boucle indéfiniment : description anglaise → (pause) → description française → (pause) → résumé de mots-clés du texte anglais → (pause) → recommence. Avec le décalage par défaut de 5 s, un cycle complet dure 15 s plus le temps que prennent les deux appels LM Studio eux-mêmes.
  4. Sur Ctrl+C, tue le processus de capture en arrière-plan (et tout enfant ffmpeg qu'il a engendré) mais laisse volontairement LM Studio en cours d'exécution, puisque c'est un service local persistant plutôt que quelque chose appartenant à cette exécution du pipeline.

Les prompts anglais et français sont des « humeurs » réglables indépendamment pour la façon dont l'installation parle de ce qu'elle voit — le pipeline par défaut utilise un cadrage « humble, eutopique et existentialiste », tandis que la variante allégée d'analyse alternée ci-dessous en utilise un « dystopique et nihiliste », faisant de la posture interprétative de l'installation elle-même un paramètre artistique ajustable plutôt qu'un comportement fixe.

Gestion du processus LM Studio — manage_lmstudio.sh

Assure que le serveur d'inférence local est en cours d'exécution et que le modèle vision-langage cible est chargé, de façon idempotente (sûr à appeler à chaque exécution). Deux points à noter :

Variante opérationnelle — run_alternating_analysis.sh

Un mode plus léger : seulement l'alternance anglais/français, à 5 s d'intervalle, sans gestion de la boucle de capture ni étape de résumé de mots-clés — utile quand la boucle de capture tourne déjà indépendamment (par exemple en développement, ou pour une configuration de performance qui n'a pas besoin du pilotage visuel par mots-clés).

Fonctionnement sans surveillance — overnight_monitor.sh

S'exécute indépendamment du pipeline d'analyse, journalisant une ligne toutes les 60 s : utilisation, mémoire, température par GPU (signalant tout ce qui atteint ≥ 85 °C, en amont du seuil de limitation thermique de la carte), et consommation électrique ; si chaque processus clé (ossia-score, Godot_v4, le ffmpeg de capture, et un processus basé sur Node) est toujours vivant ; si l'API de LM Studio répond toujours ; et l'espace disque libre (signalant moins de 3 Go libres). Chaque ligne est étiquetée ALL-OK ou PROBLEM, de sorte que vérifier une exécution de nuit le lendemain matin se résume à un simple grep -c "ALL-OK" ou grep -v "ALL-OK".

Référence OSC

AdressePortEnvoyé parContenu
/camera/description9000analyze_latest_frame.py (anglais)Description de la scène en anglais
/camera/description9001analyze_latest_frame.py (français)Description de la scène en français
/camera/keywords9002summarize_keywords.py1 à 3 mots-clés + suffixe fixe, alimente le pipeline visuel génératif

Les trois sont envoyés au même hôte OSC (la machine exécutant le pipeline visuel génératif / le patch Ossia Score), simplement sur des ports différents et, pour les deux descriptions, la même adresse distinguée par le port.

Composants mentionnés mais non détaillés ici

Ce que cela démontre

Au-delà du résultat artistique, ce sous-système a demandé une orchestration multi-processus en temps réel sur une machine contrainte en GPU (en maintenant délibérément un LLM hors du GPU pour que le rendu et la génération ne soient pas privés de ressources), une gestion propre du cycle de vie des processus (capture en arrière-plan avec arrêt correct, une vérification idempotente de disponibilité du service sûre à relancer en plein spectacle), un pipeline d'inférence multilingue petit mais réel, et des outils de fonctionnement sans surveillance (journalisation structurée de l'état de santé) construits spécifiquement pour qu'une exécution de nuit puisse être vérifiée en quelques secondes plutôt qu'en lisant des journaux bruts.