Vue normale

Reçu avant avant-hier

Unvanquished 0.55, enfin là !

Après une longue attente la version 0.55 du jeu Unvanquished a été publiée le 20 octobre 2024. Deux mises à jour mineures se sont succédées le 3 novembre et le 15 décembre pour peaufiner cette version, juste à temps pour être déposée sous le sapin de Noël !

Unvanquished est un jeu vidéo libre et gratuit mêlant stratégie en temps réel et actions à la première personne dans un univers futuristique où deux factions (humains, aliens) combattent pour leur survie.

S’inscrivant dans la continuité de Tremulous (révélé en 2006) et basé sur ce dernier, Unvanquished développe cette expérience de jeu nerveuse et exigeante depuis 2013, en améliorant continuellement le moteur et explorant des variantes et ajustements de jouabilité.

Un Tyrant Laisse-moi goûter à cette version !

Sommaire

Cette version avait été promise dans le dernier article Des nouvelles de Unvanquished, et 10 mois après la version 0.54, voici la version 0.55.

Pendant cette année 2024, le jeu a fait l’objet d’un développement soutenu et vu l’arrivée de nouveaux contributeurs.

Gameplay

  • La portée du « rocket pod » a été réduite: 2000qu → 1300qu (62m → 40m).
  • Il n’est plus possible de désévoluer vers la même classe, ce qui permettait de recharger ses projectiles sans attendre.

Bots

  • Les bots aliens savent désormais éteindre les bases en feu.
  • Ils peuvent aussi utiliser le granger avancé pour atteindre des plate-formes élevées et y construire.
  • Les classes sachant marcher sur les murs le font de manière plus fiable, et le saut de mur du maraudeur est plus précis lorsqu’il escalade des murs.

D’autres améliorations sont plus subtiles, les bots peuvent naviguer dans les cartes de façon plus efficace depuis que la taille des tuiles du maillage de navigation est configurable. Les mappers (ceux qui créent ou modifient des cartes) peuvent aussi configurer d’autres aspects de la navigation.

Un déséquilibre qui rendait les bots aliens moins bons que les bots humains a été retravaillé.

La navigation dans la carte perseus a été améliorée. C’est un des patchs de la mise à jour mineure 0.55.1, c’était déjà prêt pour la 0.55 mais avait été oublié (oups !).

La 0.55.2 a donné aux bots la capacité de voler et la capacité de danser autour des ravins sans tomber.

Interface utilisateur

Il est désormais possible de se déplacer et d’utiliser certaines touches d’action alors que certains menus circulaires sont ouverts : évolution, construction, balises (beacons). Cela permet d’ouvrir le menu de construction en tant que granger avancé sans tomber. On peut aussi évoluer tout en courant ou en sautant, etc.

Les nouveaux menus Les nouveaux menus avec les options de réticules.

Traductions

La version 0.55 est la première version majeure d’Unvanquished à distribuer de nouveau des traductions ! Nous avions déjà distribué quelques traductions avec la version de correction 0.54.1, elles étaient en quelques sorte en prévisualisation. Cette version apporte les traductions pour le Français, l’Allemand, l’Italien, l’Espagnol, le Finlandais, deux variantes de Portugais, et trois variantes de Chinois.

Dans les premiers jours d’Unvanquished nous avions des traductions, mais il y a longtemps nous avons changé la technologie utilisée pour implémenter l’interface utilisateur et la prise en charge des traductions a dû être réimplémentée. Les voici de retour et nous sommes heureux de vous les distribuer de nouveau. Pour contribuer plus de traductions et les affiner, le mieux est de le faire sur Weblate.

Nouveaux visuels

De nouveaux modèles sont là : la « painsaw » d’Alex Tikkoiev et le Chaingun d’extreazz. Ils ont été intégrés au jeu par Ishq. Cela semble simple à faire mais nous n’avons pas de modeleur ni d’animateur actif et cela nous freine beaucoup, vous pouvez nous rejoindre.

Le chaingun Le nouveau chaingun d’extreazz.

La painsaw produit désormais des étincelles quand elle impacte des surfaces dures, agissant comme le Grand Communicateur de vos désirs de disperser des tripes extra-terrestres.

La painsaw La nouvelle painsaw d’Alex Tikkoiev.

Il y a dix ans nous avons reçu une fonctionnalité bien sympathique appelée particules douces (soft particles). Cela empêche certains effets comme le brouillard ou les nuages d’acides d’être affichés de manière disgracieuse lorsqu’ils touchent des murs. Initialement l’effet n’était configuré que pour une poignée de shaders. Rapidement des programmeurs paresseux se sont dits : « configurer les shaders est ennuyeux, et si nous activions la fonctionnalité pour toutes les particules ? ». Malheureusement, cela rend certaines particules invisibles, spécialement les effets d’impacts qui sont très proches de murs ou de sols. Apparemment personne n’a remarqué ça pendant 9 ans, jusqu’à ce que nous retournions à la configuration manuelle de shaders à cause de changements architecturaux liés à autosprite2. Après une revue méticuleuse de tous les systèmes de particules du jeu, nous avons corrigé, retiré ou amélioré certains effets graphiques. Par exemple le souffle du canon lucifer produit désormais une onde de choc, causant une distorsion visuelle. Un tel effet était déjà présent dans les données, mais il ne fonctionnait pas à cause d’un problème de tri des shaders. Le tir secondaire produit aussi un flash violacé à l’impact, effet qui était souvent invisible à cause des particules douces automatiques.

Un humain en cours de soin sur la médistation Le nouvel effet de soin de la médistation.

Reaper a repensé l’effet de soin de la medistation et l’a rendue plus transparente, pour que les joueurs en cours de soin puissent voir à travers.

Sweet a ajouté un nouvel effet visuel au champ de force de la carte plat23. Cela utilise l’effet de mirage de chaleur (heat haze) qui était initialement conçu pour les armes et les effets de feu, mais il se trouve que ça peut également produire des effets très sympathiques dans les cartes. Nous remercions Masmblr pour la manière dont il nous fait avancer en démontrant dans ses propres cartes communautaires comment il est possible d’exploiter de façon créative et nouvelle des fonctionnalités que nous proposons déjà !

Fichier d’entité

Le moteur prend désormais en charge les fichiers d’entité. Cela est particulièrement utile pour les cartes (niveaux de jeu) sans source (il y en a des centaines !). Un fichier d’entité permet certaines personnalisations de comment certaines entités fonctionnent (portes, ascenseurs, téléporteurs…). Il est possible d’extraire une description d’entités avec q3map2 et le fichier extrait peut être édité avec un éditeur de texte et lu par le moteur lorsqu’il charge une carte. Le fichier d’entité peut aussi être utilisé pour modifier comment la lumière d’une carte sera appliquée (il est possible d’y renseigner des variables qui configurent le moteur de rendu pour cette carte).

Le futur est lumineux

Comparaison de rendu de lumière Une vidéo démontrant la compatibilité des lumières de diverses cartes historiques (voir la vidéo complète).

Un effort aux long cours est fait pour que le moteur affiche de meilleures lumières en jeu. Les investigations ont commencé à livrer des résultats significatifs en 2020 avec l’affinage du procédé de compilation des lumières. Cet effort est multi-facettes et touche à de multiples aspects de la chaîne de production et de rendu. Ces dernières années, Illwieckz s’est assuré que différents types d’éclairage soient pris en charge. L’éclairage par vertex (vertex lighting) a été ajouté en plus de l’éclairage par grille (grid lighting) et de l’éclairage par texture (lightmap). Ainsi les cartes qui mélangent éclairage par vertex et éclairage par texture sont désormais correctement affichées. Illwieckz a aussi débuggué les styles de lumières, une sorte de lumière dynamique pré-calculée qui fusionne plusieurs textures de lumière (lightmap) au moment du rendu.

Comparaison de suréclairage Comparaison entre l'ancien suréclairage (à gauche) et le nouveau suréclairage (à droite). Comparer avec un curseur.

Après cela Illwieckz a réimplémenté le mécanisme de suréclairage (overbright) pour éviter la troncature des lumières (light clamping). Il se trouve que le moteur de rendu de Quake 3 souffrait d’une limitation qui atténuait les lumières autant qu’il les éclaircissait… Le nouveau code non-buggé est désormais activé par défaut. Cela a suscité des débats puisque comme le moteur id Tech 3 avait un suréclairage buggé depuis plus de 20 ans, utiliser un moteur de rendu non-buggé peut révéler des bugs que les créateurs de niveaux n’ont jamais vu avant, et il était même possible d’introduire des bugs dans certains logiciels de production sans que les gens ne s’en rendent compte ! Certaines personnes peuvent argumenter que l’affichage buggé est la façon dont le créateur du niveau s’attend à ce que son niveau soit vu… Cette histoire va si loin que cela mériterait un article dédié !

La prochaine étape sur ce chemin vers un meilleur éclairage sera de faire de la colorimétrie correctement et de faire de la fusion linéaire de lumière (quelque chose qu’id Tech 3 n’a jamais fait), mais cette tâche est pour le futur.

Corrections du moteur de rendu

Un battlesuit se regardant dans des miroirs Une vidéo montrant la récursion de miroirs et de portails et leur fusion (voir la vidéo complète).

  • Sprites : Les surfaces utilisant le mot clé de shader autosprite2 sont correctement affichées, c’est parfois utilisé pour afficher des effets de symétrie axiale, par exemple pour une flamme de bougie. Ce travail a été réalisé par Slipher.
  • Portails et miroirs : Reaper a terminé l’implémentation de la récursion de portail et de miroir, a implémenté la fusion de portails et la fusion alphaGen (une technique qui permet d’obscurcir un portail selon la distance à celui-ci), et a rendu possible d’avoir des portails mobiles. Il a corrigé la rotation de portail ainsi que des bugs de portails liés aux lumières, et s’est assuré que du creep extra-terrestre de taille 10 millions de fois la taille de l’univers observable n’apparaissent pas dans les portails…
  • Vidéo : Nous pouvons à nouveau jouer des vidéos sur les surfaces. Avec le temps le code s’était gâté (rotten code), était devenu cassé et avait même été enlevé tandis qu’il était cassé. Il fut ressuscité et a fait l’objet d’une profonde réécriture par Slipher, et la fonctionnalité fonctionne de nouveau — et même mieux qu’avant (avec moins de limites arbitraires) ! Cette nouvelle implémentation était déjà visible dans la version 0.54.1, la voici désormais dans une version majeure. Le seul format pris en charge est l’antique format RoQ utilisé par Quake 3 qui, par mesure de compatibilité avec les données de jeu existantes, est le codec que nous devons prendre en charge avant tout autre codec. Nous ne fermons pas la porte au fait de prendre en charge d’autres codecs, mais pour cela il faudrait que la fonctionnalité soit utilisée plus souvent pour justifier cet effort supplémentaire.
  • Brouillard : Reaper a corrigé l’effet de brouillard, qui était cassé dans la version 0.45. Oups !
  • Lumières : Les lumières dynamiques sont désormais moins pixelisées, quand bien même ce problème n’est pas encore complètement corrigé.
  • PBR : La prise en charge de textures prétendues « basées sur la physique » est désormais dans un état viable grâce à Ishq (plus d’artefacts noirs). C’est déjà utilisé avec un nouveau modèle de chaingun. Pour le rendre bon, nous avons besoin de le faire fonctionner avec les réflexions spéculaires (réflexions statiques).

Un dretch regardant Big Buck Bunny Une vidéo montrant la lecture de vidéo sur les surfaces du jeu (voir la vidéo complète).

En corrigeant le shader autosprite2, la fusion de portails et la lecture de vidéos, nous avons corrigé 3 régressions du moteur original de Quake 3 et qui étaient liées à la prise en charge de format de fichiers anciens et de techniques tout aussi anciennes. Parce que notre moteur de rendu n’est plus celui de Quake 3, corriger certaines de ces régressions requiert parfois d’écrire du code neuf plutôt que de corriger un code existant, et c’est exactement ce qui s’est produit pour les portails.

Performance améliorées

Un granger à Noël Unvanquished 0.55.2 a été publiée pour Noël !

Le moteur et le jeu sont plus rapides que jamais !

  • Simplification du ciel : Reaper a purifié par le feu le code de rendu du ciel qui était archaïque et… étrange. Ce code pouvait générer plus de 1000 triangles par trame rien que pour dessiner le ciel. Une skybox n’a pas besoin d’une géométrie aussi fine, elle est simplement modélisée comme l’intérieur d’un cube. En plus le code faisait des allers-retours mémoire entre la mémoire principale et la mémoire graphique… 🤦‍♂️️ Nous dessinons donc le ciel maintenant avec seulement 12 triangles. Inutile de dire que les performances sont significativement améliorées, et ça aurait toujours dû être comme ça.
  • Culling : Il s’agit du procédé qui élague les surfaces non-visibles pour éviter de les dessiner. Illwieckz a optimisé l’implémentation générique pour processeur central (CPU), Slipher a ciselé à la main un code SSE pour les processeurs x86, et Reaper a permis d’utiliser la carte graphique (GPU) quand le pilote et le matériel sont compatibles.
  • Réduction des délais IPC par du traitement par lots et de la mise en cache : Ces travaux accélèrent des choses comme les particules, les marques d’impact, et les ombres. Illwieckz a réduit le temps d’attente pour ces communications interprocessus en ajoutant des alternatives à nos interfaces de programmation (API) qui fonctionnent par lot. L’IPC est comme un service postal qui transporte les messages entre le processus du jeu Unvanquished et le moteur Dæmon. Pour un facteur, l’important n’est pas le nombre de pages que vous écrivez mais le nombre d’enveloppes à livrer. Vous pouvez donc alléger sa charge de travail en mettant toutes vos lettres dans une seule grande enveloppe. Pour un cas d’utilisation (déjà livrée dans la version 0.54.1), Slipher a implémenté une mise en cache côté code de jeu. Pour filer la métaphore, il n’est pas nécessaire de ré-envoyer le même courrier si le contenu est déjà connu. Sur du matériel actuel, ces optimisations peuvent augmenter le taux de trame (framerate) de plusieurs centaines de FPS quand il y a de nombreuses particules et autres choses de ce genre à l’écran (spam de grenade incendiaires, par exemple !).
  • Code de vertex flottant plus rapide : L’implémentation de vertex plein-flottant écrite par Slipher pour étendre la compatibilité à du matériel plus ancien ou de plus basse gamme qui ne prennent pas en charge les demi-flottants a aussi doublé le taux de rafraïchissement sur du matériel qui fonctionnait déjà ! La réécriture a aussi apporté de menues optimisations dans le code de modèles.
  • Placage de relief : Reaper a corrigé un bug dans le code des cartes de relief (relief mapping), ce qui a débloqué quelques centaines de FPS sur des cartes graphiques de génération actuelle.
  • Usage mémoire des images : Illwieckz a implémenté le mécanisme fitScreen pour les textures d’interfaces utilisateur : c’est une alternative à l’antique implémentation noPicMip de Quake 3 : noPicMip instruisait le moteur de ne jamais réduire la taille d’une image, fitScreen s’assure qu’elle soit réduite d’une façon qu’elle ne devienne jamais plus large que l’écran. Par exemple une capture d’écran d’une carte (niveau) utilisée dans la liste des cartes et au chargement d’une carte ne sera plus jamais chargée en pleine résolution dans la mémoire graphique si elle doit être affichée sur un écran 640×480 (pour donner un exemple extrême)… Combiné avec le mécanisme r_maxImageDimension que nous avons ajouté en version 0.52 pour les textures qui ne sont pas utilisées pour les interfaces utilisateurs comme alternative à r_picmip, ce nouveau mécanisme donne au jeu une empreinte mémoire en VRAM très très faible quand on utilise un écran avec une résolution toute petite.
  • Plus de pré-calcul : De nombreuses décisions étaient préalablement prises à chaque trame en rendant telle ou telle surface, Illwieckz s’est assuré que ces décisions soient désormais prises une fois pour toute lorsque le shader est parsé. Ce que nous appelons « shader » ici est un format de définition de matériaux utilisé par id Tech 3 et ses dérivés, ainsi que de nombreux outils d’édition de cartes. Ne pas confondre avec un « shader GLSL » qui est un programme exécuté sur la carte graphique.
  • SSAO : Le shader GLSL SSAO (Screen Space Ambient Occlusion) a été rendu un peu plus rapide par Reaper.

Le moteur et le jeu ont été profilés intensivement par Illwieckz en utilisant Orbit. Cet effort a permis d’identifier des goulots d’étranglement (bottleneck) et du code non-optimal. Au final cela nous a aidé à implémenter de nombreuses optimisations à de nombreux endroits dans le code.

Le chargement de carte a aussi été amélioré de plusieurs façons :

  • Le moteur ne calcule plus la somme de contrôle des images CRN au chargement.
  • Le moteur ne compile plus certains shaders GLSL qui sont détectés comme inutilisés.
  • De la même façon nous avons réduit le nombre de permutations de shader GLSL à compiler.
  • Les joueurs qui aiment jouer seul apprécieront notre génération « multithread » de maillage de navigation de bot (bot navigation mesh), grâce à Ishq et Slipher. Cela fait partie de la phase de chargement lorsque vous jouez une carte pour la première fois dans un jeu local. Cette génération n’utilisait avant qu’un seul fil d’exécution (thread), désormais toute la puissante de votre processeur est exploitée en mettant tous les cœurs à contribution. Les hébergeurs de serveurs peuvent également en profiter et peuvent configurer cette fonctionnalité avec la variable g_bot_navgenMaxThreads (utiliser moins de fils utilise moins de mémoire, ce qui peut être préféré sur certains serveurs).

Il y a aussi tout un ensemble de choses qui n’ont pas de lien avec le moteur de rendu qui rendent le jeu plus rapide :

  • Le préréglage « le plus bas » (lowest) pour les appareils de très bas de gamme a été optimisé encore plus.
  • Nous distribuons des modèles optionnels en faible qualité – pour le moment seulement pour les constructions, avec la seule différence que ces modèles ont moins d’articulations. Cela permet de traiter l’animation de ces modèles sur des GPUs plus bas de gamme (au lieu de basculer sur le code CPUs quand le GPU est trop bas de gamme).
  • Il a été découvert que certaines variables de configuration (cvar) étaient utilisées par le code de jeu pour envoyer des informations à l’interface du code du jeu dans le but de les afficher à l’écran. Cela signifie que le jeu s’envoyait une lettre à lui-même à travers le moteur à chaque trame… En fait cela demandait même deux lettres : une pour envoyer la donnée au moteur, une pour la récupérer depuis le moteur, tout ça pour une donnée déjà connue ! Cette horreur a été atomisée avec un préjudice extrême.
  • L’accès à une cvar de jeu par son nom depuis le jeu utilise désormais un cache local, réduisant encore le nombre de messages que le jeu et le moteur doivent échanger, accélérant de beaucoup l’interface utilisateur.

Ceux qui aiment faire tourner des benchmarks seront heureux d’apprendre que le taux de trame de la fonctionnalité timedemo n’est plus plafonné à 999 fps.

De plus, l’interface Curses peut désormais afficher les FPS.

Bien entendu que ça fait tourner Unvanquished !

Toujours du côté du moteur de rendu, l’exigence minimale est désormais OpenGL 2.1 sans extension spéciale. Cela signifie que le matériel le plus limité qui puisse faire tourner Unvanquished inclue les ATI R300, les Intel GMA 3 et 4 (sous Linux) et les Nvidia NV40. Parfois même un OpenGL 2.1 incomplet pourrait suffire !

Votre carte graphique est prise en charge. Si cela ne fonctionne pas alors qu’elle est censée prendre en charge OpenGL 2.1 (ou plus), c’est très probablement un bug de pilote.

Par exemple même le VC4 du Raspberry Pi 3B+ peut soutenir 60 fps avec la préconfiguration la plus basse (lowest) et une résolution faible. Cependant le pilote a encore besoin d’être amélioré pour être compatible avec tous les niveaux jouables.

La carte plat23 Un Raspberry Pi 3B+ dessinant la carte plat23 à 60 fps avec le préréglage « le plus bas »…

Jouer à Unvanquished sur un RPI3 n’est vraiment pas recommandé (la mémoire vive disponible sera aussi très limitante), mais si un RPI3 arrive à tenir le rang, c’est que le jeu tourne sur vraiment n’importe quoi, y compris sur un topinambour (parce que même une patate ça serait du luxe 🤭️).

Voici quelques optimisations qui ont été faites pour étendre la compatibilité du moteur :

  • L’extension GL_ARB_half_float_vertex n’est plus requise. Cela s’ajoute au fait que l’extension GL_ARB_framebuffer_object n’est plus non-plus requise depuis la version 0.54 pour être compatible avec plus de matériel. La réécriture faite par Slipher pour prendre en charge à la fois les vertex demi-flottants ou les vertex plein-flottants a même amélioré les performances du moteur (code plus concis, code plus performant, et qui permet plus de chose… tout ça à la fois) !
  • Les textures 3D ne sont plus requises. C’est quelque chose qui est obligatoire en OpenGL 2.1, mais le moteur peut faire sans lorsque l’implémentation est incomplète. De telles implémentations incomplètes peuvent être trouvées avec certaines puces graphiques embarquées conçues pour OpenGL ES, et Mesa se permet de fournir « autant qu’il peut » d’OpenGL pour faire fonctionner les compositeur de bureau. Le moteur Dæmon sait désormais se satisfaire lui-aussi d’une telle implémentation incomplète.
  • Une collection de codes de détection a été implémentée pour identifier des pilotes buggés ou lent, ainsi que des matériels lents. Quand c’est possible, un code moins buggé ou plus rapide est activé lors de l’exécution. Par exemple lors de ce cycle de développement nous avons mis le pied dans ce que les développeurs Intel caractérisent comme un défaut matériel de l’architecture Iris (l’actuelle…), et ont suggéré un contournement qui limite les défauts visuels la plupart du temps. Il y a quelques années nous avions identifié que le dernier pilote Nvidia pour toute une génération de carte donnée ment sur la présence d’une extension, et plante si on tente de s’en servir, et ne sera jamais mis à jour… donc depuis un moment déjà on le détecte pour corriger ses prétentions. Il y a aussi une génération de vieilles cartes ATI qui sont plus rapides en flottants qu’en demi-flottant (la prise en charge annoncée par le pilote est très probablement une émulation pour permettre de faire fonctionner d’autres logiciels qui n’ont pas d’implémentation alternative), donc on détecte et on utilise le code le plus adapté à cette architecture. Il y a d’autres types de contournements mais ces trois-là sont représentatifs. Nous avions déjà quelques-uns de ces contournements implémentés (comme celui pour certaines Nvidia), mais désormais nous avons un procédé standardisé pour implémenter de tels contournements et pour pouvoir les désactiver (pour que les fabricants de matériel et/ou développeurs de pilotes puissent reproduire les bugs, par exemple).

Bien sûr toutes les améliorations de la vitesse d’exécution ont étendu la compatibilité en transformant des équipements « capable de faire le rendu » en « quelque chose avec lequel on peut jouer ».

Nous avons aussi ajouté la possibilité de compiler et exécuter un moteur Dæmon natif sur FreeBSD. Les binaires NaCl exécutés dans le bac à sable tournent toujours dans le mode de compatibilité Linux, mais le moteur peut désormais être natif FreeBSD. Une telle astuce doit probablement être utilisable sur d’autres systèmes qui ont une compatibilité Linux intégrée (NetBSD par exemple, mais nous n’avons pas testé), en utilisant un binaire natif pour le moteur et la compatibilité Linux pour la machine virtuelle du code du jeu.

Un point que nous aimerions améliorer dans le futur au niveau du moteur est l’utilisation mémoire.

Nouveaux joujoux

Reflets sur des tuyaux dans la carte Chasm Remarquez les reflets sur les tuyaux !

Placage de reflet (très expérimental) : Tandis que notre moteur de rendu progresse, les reflets statiques qui étaient complètement cassés sont désormais en meilleur état. Une fois activés, vous pourrez apercevoir votre environnement dans les matériaux réfléchissants, comme des tuyaux métalliques, des plastiques brillants, et des surfaces excessivement polies… Puisque cela est statique, seule la géométrie stationnaire de la carte est pour le moment reflétée, bien que cela soit suffisamment subtil pour que les différences ne soient pas trop évidentes, surtout au beau milieu de l’action. En outre, les données de reflets sont enregistrées et chargées depuis le disque quand vous activez la mise en cache dans les options. Le code du moteur en charge de sélectionner les reflets pour chaque surface a aussi été amélioré, apportant des reflets plus corrects et de grandes améliorations de performance.

Système de matériaux (très expérimental) : Une autre étape vers la modernisation du moteur est l’ajout d’un système de matériaux. Lorsque le matériel et les pilotes sont compatibles, cela déplace de nombreuses tâches de rendu depuis le CPU vers le GPU, produisant ainsi un flux de travail centré sur le GPU. Bien que cela ajoute un peu plus de travail au GPU, cela élimine une forte pression mise sur le CPU, ainsi que de nombreux aller-retours entre le moteur et le pilote et entre le CPU et le GPU. Sur les cartes les plus exigeantes pour le CPU (en particulier celles avec un “vis” mauvais, le vis est une représentation de la carte générée par le compilateur de carte qui détermine quelle partie devrait être visible selon le point de vue) cela peut doubler le taux de trame comparé au moteur de base. Ce système est encore incomplet et de nombreuses améliorations sont à venir.

Reaper est celui qui se cache derrière la réalisation de ces chantiers impressionnants.

Pour pouvoir en profiter il vous sera nécessaire d’avoir OpenGL 4.6 et (en plus) l’extension GL_ARB_bindless_texture. Il reste cependant des problèmes avec certains matériels et pilotes : tout devrait fonctionner avec Nvidia, le système de matériaux et le « frustum culling » devraient fonctionner avec Mesa (radeonsi pour AMD, etc.) quand la dernière version de Mesa est utilisée (l’ « occlusion culling » ne fonctionne pas encore et pourrait planter avec un Mesa qui ne vient pas de la branche de développement main…). Cela ne fonctionne pas avec le pilote propriétaire AMD à cause de bugs. Des contournements pour ces problèmes sont planifiés, mais tous n’ont pas été implémentés à temps pour la sortie de cette version.

À venir

Parmis les développements qui sont déjà testables sur certains serveurs et qui seront disponibles dans la prochaine version, il y a le mode « vampire », qui est un mode alternatif de gestion des ressources : plutôt que de miner du point de construction, chaque équipe se voit dotée d’un lot déterminé de points en début de partie et lorsqu’une équipe détruit une construction adverse elle s’approprie les points de construction associées. Ce mode « vampire » est évalué comme une solution potentielle au problème de certaines parties qui sont trop longues ou semblent bloquées avec des équipes trop bien fortifiées de chaque côté. Ce mode de jeu peut être testé en avant-première sur des serveurs comme Map&Bot Testing, Der Bunker, ou Bug Squash Central.

Il est temps de jouer !

Le jeu Unvanquished se télécharge ici et les parties en cours sont listées ici !

Commentaires : voir le flux Atom ouvrir dans le navigateur

Une intelligence artificielle libre est-elle possible ?

26 février 2025 à 20:47

Ces derniers temps, on a beaucoup parlé d’intelligence artificielle sur LinuxFr.org. D’IA propriétaires, et d’IA libres. Mais peut-on vraiment faire une IA libre ? La notion n’est pas sans poser quelques difficultés. Une (pas si) courte discussion du problème.

    Sommaire

    On appellera IA un réseau de neurones artificiels

    Commençons par définir notre objet d’étude : qu’est-ce qu’une IA ? Par « intelligence artificielle », on pourrait entendre tout dispositif capable de faire réaliser par un ordinateur une opération réputée requérir une tâche cognitive. Dans cette acception, un système expert qui prend des décisions médicales en implémentant les recommandations d’une société savante est une IA. Le pilote automatique d’un avion de ligne est une IA.

    Cependant, ce n’est pas la définition la plus couramment employée ces derniers temps. Une IA a battu Lee Sedol au go, mais ça fait des années que des ordinateurs battent les humains aux échecs et personne ne prétend que c’est une IA. Des IA sont employées pour reconnaître des images alors que reconnaître un chien nous semble absolument élémentaire, mais l’algorithme de Youtube qui te suggère des vidéos pouvant te plaire parmi les milliards hébergées fait preuve d’une certaine intelligence et personne ne l’appelle IA. Il semble donc que le terme « IA » s’applique donc à une technique pour effectuer une tâche plus qu’à la tâche en elle-même, ou plutôt à un ensemble de techniques partageant un point commun : le réseau de neurones artificiels.

    Dans la suite de cette dépêche, j’utiliserai donc indifféremment les termes d’IA et de réseau de neurones1.

    Pour comprendre le réseau de neurones, il est nécessaire de disposer de bases statistiques

    Les statistiques (ou la statistique, on peut dire les deux, comme en Alexandrie), c’est la branche des mathématiques qui s’intéresse aux moyens, à partir de données observées et fondamentalement probabilistes, d’en tirer des conclusions généralisables (et idéalement, de prédire l’avenir à partir du passé).

    La data science, c’est la branche de l’informatique qui s’intéresse aux moyens, à partir de données emmagasinées sur lesquelles on ne fait pas d’hypothèse de mode de génération, d’en tirer des conclusions généralisables (et idéalement, de prédire les données futures).

    Ça vous semble similaire ? Ça l’est. Les deux champs vont avoir des divergences de vocabulaire, de langages (les stateux préfèreront R, les data scientists Python), de formation (les stateux sont plutôt des universitaires, les data scientists plutôt des informaticiens au niveau licence, mais ils ont les mêmes masters et doctorats), mais fondamentalement, et surtout mathématiquement, c’est la même chose. Les connaissances en inférence statistique (notamment bayésienne, pour ceux à qui ça parle) se généralisent très bien à la data science.

    Pour faire court, un statisticien est un data scientist qui se la pète, alors qu’un data scientist est un informaticien qui, n’étant pas assez bon pour survivre à la rude concurrence universitaire, a multiplié son salaire par 10 ou 20 en allant vendre ses compétences statistiques à Facebook.

    Les statistiques reposent sur la modélisation

    En statistique, la manière la plus courante de répondre à une question est de construire un modèle. Prenons une question simple : je dispose d’un jeu de données où j’ai enregistré, pour 1000 personnes, leur IMC et leur taux de cholestérol. Je souhaite savoir s’il y a un lien entre les deux. On souhaiterait, dans ce cas simple, rechercher une relation monotone, sans faire d’hypothèse sur le type de relation.

    Un exemple : la régression linéaire

    Une manière de répondre à ma question est d’écrire Cholestérol = A\times IMC + B et de trouver les meilleurs A et B pour que la droite « colle » le mieux possible au nuage de points. On démontre que la meilleure droite est celle qui minimise un certain critère, la somme des carrés des erreurs. Une fois qu’on a la meilleure droite possible, on peut faire plein de choses avec :

    • On peut rétro-prédire le taux de cholestérol des personnes déjà observées et voir de combien la prédiction s’écarte du réel, ce qui fournit une erreur moyenne de prédiction ;
    • On peut faire de même en prédisant juste le taux de cholestérol moyen pour tous les individus et comparer les erreurs moyennes de prédiction, ce qui permet de voir de combien le modèle améliore la prédiction (et donc de quantifier la quantité d’info apportée par la donnée IMC sur la variable cholestérol) ;
    • On peut étudier le signe de A : si A est négatif, prendre du poids fait baisser le cholestérol : si A est positif, prendre du poids augmente le cholestérol : si A est nul, le poids n’apporte pas d’info sur le cholestérol.
    • Par contre, on ne peut rien dire de la causalité. Tout ce qu’on a observé, ce sont des personnes qui, au même moment, avaient un IMC et un taux de cholestérol donnés. Impossible de dire s’ils ont ce cholestérol parce qu’ils ont cet IMC, s’ils ont cet IMC parce qu’ils ont ce cholestérol, ou s’ils ont ce cholestérol et cet IMC parce qu’ils ont une troisième exposition.
    • On peut enfin faire effectuer de la prédiction à notre modèle : en lui passant une personne dont on ne connaît que l’IMC, on peut estimer son taux de cholestérol et assortir cette prédiction d’un niveau de certitude (ça demande un peu plus de maths, mais c’est l’idée).

    On peut vouloir ajouter une troisième variable, mettons le tabagisme. On écrira alors :

    Avec la variable tabac codée à 0 (non fumeur) ou 1 (fumeur). Noter que notre modèle est alors passé en dimension 3 : on ne cherche plus à faire passer la meilleure droite par rapport au nuage de points en 2D, mais à faire passer le meilleur plan par rapport au nuage de points en 3D. Noter aussi qu’on peut facilement inclure des variables qualitatives : il suffit de les coder 0 ou 1. On peut d’ailleurs inclure des variables à n modalités : il suffit de les recoder en n-1 sous-variables en 0-1 (la modalité de référence étant celle pour laquelle toutes les sous-variables sont à 0).

    Les \beta sont appelés des paramètres : c’est en les faisant varier qu’on ajuste le modèle aux données.

    On peut ainsi ajouter un nombre quelconque de variables… Ou peut-être pas. En effet, on va finir par atteindre un seuil où le meilleur hyperplan est tout simplement celui qui passe par tous les points ! Si j’ai 50 individus et 50 paramètres, il est facile de choisir un plan qui passe par tous les individus. C’est ce qu’on appelle le surapprentissage : le modèle a tout simplement appris le jeu de données par cœur ! Le surapprentissage est un écueil des modèles trop complexes et un réseau de neurones est tout à fait capable de surapprendre.

    Le réseau de neurones

    Le neurone naturel

    Les neurones sont les cellules du système nerveux. Elles sont spécialisées dans la transmission d’information.

    Neurone naturel

    Comme tu peux le voir sur cette image issue de Wikimedia (source), un neurone comprend un nombre quelconque de dendrites, un corps cellulaire, et un axone. Point crucial : l’axone est unique. Il peut lui-même transmettre de l’information à différents neurones en aval, mais il transmet la même information. Or l’information, dans un neurone, peut entrer par les dendrites et par le corps cellulaire, mais elle ne peut ressortir que par l’axone (on peut faire abstraction de la gaine de myéline et des nœuds de Ranvier, qui ont un rôle central dans la vitesse de conduction de l’information mais qui ne changent rien aux calculs effectués). Autrement dit, un neurone transmet la même information à tous les neurones d’aval, et si ceux-ci en font un usage différent, c’est uniquement lié à leurs propres calculs en interne.

    Le neurone formel

    On peut modéliser un neurone, par analogie avec le neurone naturel. Notre neurone formel pourra donc prendre un nombre quelconque d’entrées, mais comme un neurone naturel, il ne produira qu’une seule sortie. Notre neurone est donc une fonction de ses entrées :

    En pratique (mais ça n’a rien d’obligatoire), on prend souvent une fonction d’une combinaison linéaire des entrées :

    Avec une contrainte : la fonction f (qu’on appelle fonction d’activation) doit être monotone (idéalement strictement monotone), dérivable presque partout (c’est nécessaire à l’optimisation du réseau, qu’on verra plus tard), définie sur un intervalle suffisamment large pour qu’on soit toujours dedans, et non linéaire (sinon mettre les neurones en réseau n’a aucun intérêt, autant faire directement une unique régression linéaire).

    En pratique, on prend donc quelques fonctions classiques :

    • La fonction binaire : f(x) = 0 si x < 0, 1 sinon
    • La fonction logistique, une amélioration de la fonction binaire : f(x) = \frac{1}{1 + e^{-x}}. Avantage : elle est strictement monotone, dérivable partout, et elle prend quand même ses valeurs entre 0 et 1.
    • La fonction Rectified Linear Unit (ReLU, qu’on peut prononcer « relou ») : f(x) = 0 si x<0, x sinon. Avantage : elle est très facile (donc rapide) à calculer et à dériver. On peut la rendre strictement monotone en la modifiant à la marge : f(x) = \epsilon\times x si x<0, x sinon, avec 0<\epsilon << 1.

    La mise en réseau

    Tout l’intérêt du neurone formel réside dans sa mise en réseau. Un unique neurone ne fait pas mieux qu’une régression linéaire. On construit donc un réseau de neurones. Pour ce faire, on va donc générer plusieurs neurones, chacun prenant en entrée la sortie de plusieurs neurones et produisant une sortie unique, qui sera à son tour utilisée en entrée par d’autres neurones. On ajoute un ensemble de neurones qu’on pourrait qualifier de « sensitifs », au sens où ils prennent en entrée non pas la sortie d’un neurone antérieur, mais directement l’input de l’utilisateur, ou plutôt une partie de l’input : un pixel, un mot… Enfin, une sortie est ajoutée : elle produit le résultat final.

    Étant donné que les neurones sont virtuels et n’ont pas d’emplacement géographique, il est assez logique de les représenter en couches : la couche 0 est constituée des neurones sensitifs, la couche 1 prend en entrée les résultats de la couche 0, et ainsi de suite. Classiquement, tous les neurones de la couche n+1 prennent en entrée les sorties de tous les neurones de la couche n.

    Se pose alors la question : combien de neurones par couche, et combien de couches au total ?
    On peut considérer deux types de topologies : soit il y a plus de neurones par couche que de couches : le réseau est plus large que long, on parlera de réseau large. Soit il y a plus de couches que de neurones par couche, auquel cas le réseau est plus long que large, mais on ne va pas parler de réseau long parce que ça pourrait se comprendre « réseau lent ». On parlera de réseau profond. C’est de là que viennent les Deep et les Large qu’on voit un peu partout dans le marketing des IA. Un Large Language Model, c’est un modèle, au sens statistique, de langage large, autrement dit un réseau de neurones avec plus de neurones par couche que de couches, entraîné à traiter du langage naturel. On constate empiriquement que certaines topologies de réseau sont plus efficaces pour certaines tâches. Par exemple, à nombre de neurones constant, un modèle large fera mieux pour du langage. À l’inverse, un modèle profond fera mieux pour de la reconnaissance d’images.

    Le réseau de neurones est Turing-complet

    Un résultat théorique important est que les réseaux de neurones sont Turing-complets. C’est-à-dire que, pour tout programme que l’on peut coder et qui sorte une réponse algorithmique, il existe un réseau de neurones qui donne le même résultat. La réciproque est vraie aussi : ce qui est faisable avec un réseau de neurones est faisable en C ou dans un autre langage, au pire en recodant le réseau dans ce langage.

    Le réseau de neurones présente un effet boîte noire important

    Prenons maintenant un élément d’information et essayons de suivre son trajet dans le modèle jusqu’à la sortie. Dans une régression linéaire, c’est assez facile : le poids de l’IMC va peser pour \beta_{IMC} dans le résultat final. Dans une forêt aléatoire, on peut toujours isoler les arbres où apparaît une donnée et essayer de regarder combien elle pèse. C’est fastidieux mais ça reste faisable. Dans un réseau de neurones, c’est impossible. Chaque neurone de la couche 1 va passer un résultat agrégé à la couche 2, où chaque donnée de la couche 0 ne compte plus que comme partie d’un tout. De même, chaque neurone de la couche 2 va agréger tous les résultats de la couche 1. Il devient impossible d’individualiser l’effet d’une donnée ou même celui d’un neurone.

    Ainsi, même si je connais l’intégralité du contenu du modèle, il m’est impossible de donner du sens à une partie du modèle, prise isolément. Le modèle se comporte comme un bloc monolithique, et la seule manière d’étudier un nouvel exemple est de lui appliquer tout le modèle et de voir ce qui sort. C’est ce qu’on nomme l’effet boîte noire.

    Attention : l’effet boîte noire n’est pas lié au nombre de paramètres du modèle. Si je fais de la génétique, et que j’étudie 2000 mutations génétiques individuelles (des SNP, pour single nucleotide polymorphism), je peux assez facilement ajuster un modèle de régression logistique (qui est une variante de la régression linéaire où on fait prédire non pas une variable quantitative, mais une probabilité) à 2000 paramètres (un \beta pour chaque SNP). Chaque paramètre sera parfaitement compréhensible et il n’y aura pas d’effet boîte noire.

    Il n’est pas non plus lié à ta méconnaissance des mathématiques, cher lectorat. Des statisticiens chevronnés se cassent les dents sur l’effet boîte noire. Il est intégralement lié à la structure du modèle. Certains types de modèles en ont, d’autres n’en ont pas. Les réseaux de neurones en ont.

    Cet effet a une conséquence perturbante : même si on sait ce que fait un réseau de neurones, il est impossible de savoir comment il le fait ! On pourrait argumenter que ce n’est pas forcément différent de ce que nous faisons : si on montre à un enfant de 3 ans une photo de chien, il saura dire que c’est un chien, mais il ne saura pas dire pourquoi c’est un chien. Cependant, on demande rarement à un programme d’être réflexif, mais on demande toujours à son auteur de savoir comment il tourne. C’est un peu la base de la programmation.

    Le réseau de neurones est un modèle statistique

    Reprenons : on a un paradigme (le réseau de neurones) capable d’effectuer n’importe quelle tâche pour laquelle il existe une solution algorithmique, à condition de le programmer correctement… Mais on ne sait pas le programmer ! Heureusement, il existe un contournement : on ne va pas le programmer, on va l’ajuster, comme un modèle statistique. Ou l’entraîner, si on préfère le terme de « machine learning ».

    Tu t’en souviens, cher lecteur, un réseau de neurones est un ensemble de fonctions dont chacune prend en entrée différentes données avec des coefficients (les fameux \beta_i). On va commencer par initialiser l’apprentissage en donnant des valeurs aléatoires à ces coefficients. Ensuite, on va soumettre à notre réseau de neurones des tas et des tas de données correctes, et qu’on va comparer ce qu’il prédit à ce qu’on attend. La différence s’appelle l’erreur. Et à chaque itération, on va identifier les neurones les plus générateurs d’erreur et les pénaliser (réduire leur poids, ou plutôt réduire leur poids dans les neurones où c’est nécessaire), tout en favorisant les meilleurs neurones. Les détails de la technique (qui s’appelle la rétropropagation de l’erreur) dépassent largement le cadre de cette courte introduction, mais l’essentiel est qu’à la fin, on obtient un réseau capable de donner des réponses proches de ce qui existait dans l’ensemble des données correctes qu’on lui a passé et de généraliser quand la demande est différente d’une donnée de l’ensemble d’apprentissage. Avantage : en pratique, un réseau de neurones est capable de prendre en entrée n’importe quel type de structure de données : image, texte, son… Tant que les neurones d’entrée sont adaptés et qu’il existe un ensemble d’apprentissage suffisamment grand, c’est bon.

    Tous les modèles sont faux, certains sont utiles, et c’est vrai aussi pour le réseau de neurones

    Bien sûr, il y a des limites. La première est la complexité algorithmique. Un réseau de neurones nécessite de réaliser un nombre astronomique d’opérations simples : pour chaque couche, il faut, pour chaque neurone, calculer la somme des produits des coefficients avec toutes les sorties de la couche antérieure, soit c\times n^2 multiplications, où n est le nombre de neurones par couche et c le nombre de couches. Par exemple, pour un petit réseau de 10 couches de 20 neurones, plus une couche d’entrée, on réaliserait à chaque itération 10\times 20^2 = 4000 multiplications en virgule flottante, et encore, c’est ici un tout petit réseau : un réseau comme ChatGPT a des neurones qui se comptent par millions, voire dizaines de millions !

    Une autre limite est la précision des réponses. Le réseau de neurones étant un modèle statistique, il n’est capable que d’interpoler, c’est-à-dire trouver une réponse à partir de cas similaires. Cette interpolation est rarement aussi précise que celle que donnerait une réponse formelle si elle existait : si Newton avait eu accès à des réseaux de neurones, nous aurions une prédiction du mouvement des planètes qui ne baserait sur aucune théorie, qui serait à peu près exacte mais insuffisamment précise pour envoyer des sondes sur Mars. Quant à s’interroger sur la précession du périhélie de Mercure, on oublie.

    De manière générale, on peut s’interroger sur ce qui amène un réseau de neurones à se planter. On peut diviser les erreurs en plusieurs catégories :

    • La question posée n’a aucun rapport avec les données passées en entrée. Par exemple : « Sachant que la dernière personne que j’ai croisée dans la rue avait 42 ans, indique-moi son genre ». Le modèle n’a pas assez d’information pour répondre.
    • La question posée n’a aucun rapport avec l’ensemble d’apprentissage. Par exemple, demander à un modèle entraîné à reconnaître des photos de chien de reconnaître une voiture. En général, ce problème est résolu en contraignant le format des questions ; dans cet exemple, il suffirait de ne pas permettre à l’utilisateur de poser une question, juste de poster une photo et de recevoir une réponse. D’ailleurs, on ne voit pas très bien pourquoi entraîner un tel modèle à traiter du langage.
    • L’ensemble d’apprentissage est trop restreint/biaisé. L’exemple typique est le modèle qui prétendait reconnaître les délinquants à une simple photo et identifiait en fait tous les noirs : ben oui, ils étaient majoritaires dans les délinquants de l’ensemble d’apprentissage. Noter qu’il existe des problèmes où l’ensemble d’apprentissage sera toujours trop restreint pour un certain niveau de précision exigé. Si on demande à un réseau de dire si un point donné est à l’intérieur ou à l’extérieur d’un flocon de Koch, il va falloir lui passer une infinité de données d’apprentissage pour qu’il apprenne les cas limites juste par interpolation (alors qu’avec un modèle formel, ça serait assez facile).
    • Le modèle est parasité par une donnée annexe : c’est une problématique assez spécifique du réseau de neurones. L’exemple le plus classique est celui des images de mains : après tout, le voisin le plus probable d’un doigt, c’est un autre doigt. L’amusant, c’est que ce problème serait résolu assez facilement en demandant au modèle de compter 4 doigts et un pouce. Mais comme on ne peut pas programmer directement un réseau de neurones…
    • Enfin, si les motifs précédents ont été écartés, je dois me demander si mon modèle n’est pas inadapté : soit qu’il n’a pas assez de neurones, soit que la topologie n’est pas bonne. Plus de neurones permettent de traiter des données plus complexes et leur disposition permet d’augmenter leur efficacité.

    En définitive, on peut voir le réseau de neurones comme un outil qui résout approximativement un problème mal posé. S’il existe une solution formelle, et qu’on sait la coder en un temps acceptable, il faut le faire. Sinon, le réseau de neurones fera un taf acceptable.

    Le but du logiciel libre est de rendre le pouvoir à l’utilisateur

    On a beaucoup glosé, et on continuera de le faire longtemps, sur la philosophie du Libre. Free Software Foundation d’un côté, Open Source Initiative de l’autre, les sujets de discorde ne manquent pas. Mais il faut au moins créditer l’OSI sur un point : avoir clarifié le fait que le Libre est avant tout un mouvement politique, au sens noble du terme : il vise à peser sur la vie de la cité, alors que l’Open Source vise avant tout à disposer de logiciels de qualité.

    La première des libertés est celle de savoir ce que je fais

    Ça paraît évident dans la vie de tous les jours : je sais ce que je fais. Si je décide de prendre une pelle et de planter un arbre dans mon jardin, je sais que je suis en train de prendre une pelle et de planter un arbre dans mon jardin. Si je décide de prendre un couteau et de le planter dans le thorax de mon voisin, je sais ce que je fais. C’est une liberté fondamentale, au sens où elle fonde toutes les autres. Si je ne sais pas ce que je fais, je ne peux signer un contrat, par exemple (c’est d’ailleurs le principe qui sous-tend le régime de la tutelle en droit). D’ailleurs, comme toute liberté, elle fonde une responsabilité. Si je ne savais pas ce que je faisais (et que je peux le prouver), je peux plaider l’abolition du discernement et échapper à ma responsabilité pénale, quelle que soit l’infraction commise, même les plus graves2

    Dans la vie de tous les jours, donc, il est évident que je sais ce que je fais. Mais avec un ordinateur, c’est beaucoup moins évident. Quand j’exécute Windows, je ne sais pas ce que je fais. Pas seulement parce que je ne connais pas la séquence de boot, mais de façon beaucoup plus fondamentale : parce que n’ayant pas accès au code source, je ne sais pas ce que fait le programme que j’exécute. Ce qui pose un problème majeur de confiance dans le logiciel exécuté :

    • Confiance dans le fait que le programme fait bien ce que son programmeur a voulu qu’il fasse (absence de bugs)
    • Confiance dans le fait que le programmeur avait bien mon intérêt en tête et pas seulement le sien (sincérité du programmeur, fréquemment prise en défaut dans le logiciel non libre)

    Dans le système des 4 libertés du logiciel libre, cette liberté est la liberté 1. Elle passe après la liberté 0 (liberté d’exécuter le programme) et avant la liberté 2 (liberté de redistribuer le programme). On pourrait légitimement discuter de sa priorité par rapport à la liberté 0 (est-il raisonnable d’exécuter un programme dont on ne sait pas ce qu’il fait ?) mais ça dépasserait l’objet de cette dépêche.

    Si je sais ce que je fais, je dois pouvoir modifier ce que je fais

    Conséquence logique de la liberté précédente : si je n’aime pas ce que fait un programme, je dois pouvoir l’améliorer. Si je ne sais pas le faire moi-même, je dois pouvoir payer quelqu’un pour l’améliorer. Là encore, ça suppose l’accès au code source, ne serait-ce que pour savoir ce que fait le programme. Il s’agit de la liberté 3 du logiciel libre.

    Le réseau de neurones est difficilement compatible avec le libre

    Personne ne sait vraiment ce que fait un réseau de neurones

    On l’a vu, les réseaux de neurones présentent un effet boîte noire important. Déjà, la plupart des IA commerciales ne sont accessibles qu’au travers d’une interface ou une API. Elles n’exposent que rarement les neurones. Mais même pour une personne disposant de tous les neurones, autrement dit de la description complète du réseau, l’effet boîte noire est tel que le fonctionnement du réseau de neurones est inintelligible. D’ailleurs, s’il était intelligible, il serait très vite simplifié !

    En effet, on peut recoder tout réseau de neurones dans un langage plus rapide, dès lors qu’on comprend ce qu’il fait (puisqu’il est Turing-complet). Vu la consommation astronomique d’énergie des réseaux de neurones, s’il existait un moyen de comprendre ce que fait un réseau de neurones et de le traduire dans un autre langage, on le ferait très vite. Ce qui fournirait d’ailleurs des réponses à des questions théoriques ouvertes comme : qu’est-ce que comprendre une phrase ? Comment reconnaît-on un chien, un visage, un avion ?

    Disposer de la description complète d’un réseau de neurones ne permet pas de l’améliorer

    On l’a vu : si je dispose de la totalité des neurones, je dispose de la totalité de la description du réseau de neurones. Mais comme je suis incapable de savoir ce qu’il fait, je ne suis pas plus avancé pour l’améliorer, qu’il s’agisse de retirer un défaut ou d’ajouter une fonctionnalité. Noter d’ailleurs que ceci n’est pas forcément impactant de la même manière pour tous les aspects du réseau de neurones : si je n’ai aucun moyen d’être sûr de l’absence de bugs (c’est même le contraire ! Il y a forcément des bugs, c’est juste que je ne les ai pas trouvés ou qu’ils ne sont pas corrigeables), j’ai en revanche peu d’inquiétude à avoir concernant la sincérité du programmeur : comme lui non plus ne maîtrise pas sa bestiole, pas de risque qu’il soit insincère3.

    La définition du code source d’un réseau de neurones est ambiguë

    Posons-nous un instant la question : qu’est-ce que le code source d’un réseau de neurones ? Est-ce la liste des neurones ? Comme on l’a vu, ils ne permettent ni de comprendre ce que fait le réseau, ni de le modifier. Ce sont donc de mauvais candidats. La GPL fournit une définition : le code source est la forme de l’œuvre privilégiée pour effectuer des modifications. Dans cette acception, le code source d’un réseau de neurones serait l’algorithme d’entraînement, le réseau de neurones de départ et le corpus sur lequel le réseau a été entraîné.

    Cette ambiguïté fait courir un risque juridique sous certaines licences libres

    Tu devines alors, cher lecteur, là où je veux en venir… Si le corpus comprend des œuvres non libres, tu n’as tout simplement pas le droit de le diffuser sous une licence libre ! Et si tu t’es limité à des œuvres libres pour entraîner ton modèle, tu risques fort d’avoir un ensemble d’apprentissage trop restreint, donc un réseau de neurones sans intérêt.

    Alors il y a quatre moyens de tricher.
    Le premier, c’est de t’asseoir sur la GPL et de considérer qu’en distribuant les neurones, tu as fait le taf. La ficelle est grossière. Je viens de passer une dépêche à te démontrer que c’est faux, tu pourrais au moins me montrer un peu plus de respect.

    Le deuxième, c’est de distribuer sous une licence non copyleft, genre BSD ou WTFPL. Une licence qui ne nécessite pas de distribuer le code source. Certes, mais en fait tu ne fais pas du Libre.

    Le troisième, c’est de considérer le réseau de neurones comme une donnée, pas un exécutable. Donc pas de code source. La partie sous GPL serait alors l’interface graphique, et le réseau, une donnée. C’est assez limite. Une donnée exécutable, ça s’approche dangereusement d’un blob binaire.

    Le quatrième, c’est de repenser complètement le paradigme du logiciel libre et de considérer qu’il vise avant tout à rééquilibrer les rapports de pouvoir entre programmeur et utilisateur, et qu’en redistribuant les neurones, tu as fait le job. Sur les rapports de pouvoir, tu n’as pas tort ! Mais d’une part, ça ne tiendra pas la route devant un tribunal. D’autre part, il persiste une asymétrie de pouvoir : tu as accès au corpus, pas l’utilisateur.

    Quand bien même on admettrait que le code source est l’ensemble corpus + algorithme d’optimisation + réseau de neurones de départ, l’optimisation d’un réseau de neurones consomme autrement plus de ressources que la compilation d’un programme plus classique, des ressources qui sont loin d’être à la portée du quidam classique. À quoi servirait un code source impossible à compiler ?

    Enfin, même cette définition du code source pose problème : elle n’est en fait pas beaucoup plus lisible que le réseau lui-même. Ce n’est pas parce que j’ai accès aux centaines (de milliers) de textes sur lesquels un réseau a été entraîné que je peux prédire comment il va se comporter face à une nouvelle question.

    Comment les boîtes qui font de l’IA non libre résolvent-elles ce dilemme ? Elles ne le résolvent pas

    C’est presque enfoncer une porte ouverte que dire que l’IA pose de nombreuses questions de droit d’auteur, y compris dans le petit microcosme du non-libre. Cependant, les IA non-libres ont un avantage sur ce point : si le réseau de neurones ne permet pas de remonter au corpus initial (donc en l’absence de surapprentissage), alors elles peuvent tranquillement nier avoir plagié une œuvre donnée. Tu ne me verras pas défendre les pauvres auteurs spoliés, car j’ai toujours considéré que la nature même de l’information est de circuler sans barrières (Information wants to be free, tout ça) et que le droit d’auteur en est une, et particulièrement perverse.

    La définition d’une IA open source ressemble furieusement à un constat d’échec

    L’OSI a publié une définition d’IA open source. Cette définition mérite qu’on s’y attarde.

    Premier point intéressant : après des années à tenter de se démarquer du Libre, notamment via la définition de l’Open Source qui tente de reformuler les 4 libertés sans recopier les 4 libertérs, l’OSI baisse les bras : est open source une IA qui respecte les 4 libertés.

    Deuxième point intéressant : est open source une IA qui publie la liste des neurones, le corpus d’entraînement et la méthode d’entraînement. En fait, ça revient à ne pas choisir entre les neurones et leur méthode d’entraînement. Soit, mais ça ne résout pas le problème de l’effet boîte noire. Au mieux, ça revient à admettre qu’il est le même pour le programmeur et l’utilisateur.

    Conclusion : qu’attendre d’une IA libre ?

    Il ne fait aucun doute que développer des IA libres exigera de nouvelles licences. La GPL, on l’a vu, expose à un risque juridique du fait de l’ambiguïté de la définition du code source.

    Il est à noter, d’ailleurs, qu’une IA repose rarement exclusivement sur son réseau de neurones : il y a systématiquement au moins un logiciel classique pour recueillir les inputs de l’utilisateur et les passer au réseau de neurones, et un second en sortie pour présenter les outputs. Ces briques logicielles, elles, peuvent tout à fait suivre le paradigme classique du logiciel libre.

    En définitive, cher lecteur qui ne développes pas d’IA, je t’invite surtout à te demander : qu’attends-tu d’une IA ? Qu’entends-tu quand on te parle d’IA libre ? Plus fondamentalement, l’IA serait-elle un des rares domaines où il existe une distinction pratique entre libre et Open Source ?

    Il n’y a pas de façon simple de faire une IA libre, il n’y a peut-être pas de façon du tout. Mais le principe du libre, c’est que c’est à l’utilisateur in fine de prendre ses décisions, et les responsabilités qui vont avec. Je n’espère pas t’avoir fait changer d’avis : j’espère modestement t’avoir fourni quelques clés pour enrichir ta réflexion sur le sens à donner au vocable IA open source qu’on voit fleurir ici et là.


    1. Et je mettrai « artificiel » à la poubelle parce que Implicit is better than explicit, rien que pour embêter Guido). 

    2. Bon, certaines infractions complexes à exécuter, comme le trafic de drogue ou le génocide, requièrent une certaine implication intellectuelle et sont donc peu compatibles avec l’altération du discernement, mais c’est lié au fait que l’infraction elle-même requiert un certain discernement. 

    3. Du moins au niveau du réseau de neurones lui-même. Les entrées et les sorties peuvent tout à fait passer par une moulinette insincère et codée dans un langage tout à fait classique. 

    Commentaires : voir le flux Atom ouvrir dans le navigateur

    ❌