10 points par GN⁺ 2025-02-28 | 2 commentaires | Partager sur WhatsApp
  • Ces dernières années, Elixir a étendu ses capacités dans les domaines du machine learning et de la donnée via le projet Nx (Numerical Elixir)
  • Des projets comme Nx, Explorer, Axon, Bumblebee et Scholar ont émergé et progressent en s’appuyant sur les leçons tirées des écosystèmes Python et R
  • Au départ, il avait été décidé de ne pas dépendre directement des bibliothèques Python, afin de poursuivre une conception optimisée pour Elixir et d’éviter la complexité de la configuration d’un environnement Python
  • Pourtant, aujourd’hui, ce qui porte l’adoption d’Elixir dans ce domaine, c’est Livebook
    • Une plateforme de notebooks à la pointe de la reproductibilité, de l’exécution distribuée et du développement d’applications, construite sur les points forts d’Elixir et d’Erlang
    • L’intérêt des équipes et des entreprises qui souhaitent faire leurs premiers pas dans l’écosystème Elixir via Livebook ne cesse de croître
  • Mais il existe un obstacle
    • La plupart des entreprises qui veulent introduire Elixir et Livebook dans leur infrastructure utilisent déjà des workflows, des packages et des dépôts basés sur Python
    • Cela signifie qu’il faut soit trouver des packages équivalents en Elixir, soit les réécrire à partir de zéro, ce qui augmente le risque et le coût liés à l’ajout d’Elixir à la stack data
  • Pour y répondre, annonce de Pythonx, qui intègre l’interpréteur Python dans la VM Erlang

Pythonx

  • Pythonx fournit la conversion automatique des données entre Elixir et Python, l’évaluation de code et la gestion des environnements virtuels
  • Il est possible d’utiliser le package pytesseract pour effectuer de l’OCR (Optical Character Recognition)
  • Après avoir téléchargé une image avec req, on peut télécharger et initialiser Python et ses dépendances via l’appel à Pythonx.uv_init/1
  • Pythonx.eval/2 permet d’exécuter du code Python et de convertir le résultat en chaîne Elixir

Structure interne

  • L’implémentation de référence CPython de Python peut être embarquée dans d’autres applications
  • Les fonctions essentielles de l’interpréteur Python sont fournies sous forme de bibliothèque C
  • Une application C/C++ peut lier cette bibliothèque et utiliser son API pour exécuter du code et interagir avec les objets
  • Elixir offre l’interopérabilité avec C/C++ via les NIFs d’Erlang
  • Pythonx s’appuie sur les NIFs pour embarquer Python et fonctionne dans le même processus OS
  • Le transfert de données entre Python et Elixir est ainsi effectué efficacement

Support multilingue de Livebook

  • Sur la base de Pythonx, l’ajout du support de Python dans Livebook est en cours
  • Elixir et Python pourront interagir dans un même notebook
  • Livebook installera automatiquement Python et ses dépendances, et gérera les conversions entre variables Elixir et Python
  • Cela garantit un environnement reproductible
  • Des travaux supplémentaires sont en cours, notamment sur l’autocomplétion et la documentation, et il est déjà possible de télécharger et d’utiliser Livebook nightly

Points à considérer et alternatives

  • L’objectif principal de Pythonx est d’intégrer des workflows Python dans Livebook et dans des scripts
  • En raison du Global Interpreter Lock (GIL) de Python, il peut y avoir des limitations de concurrence lorsque plusieurs processus Elixir appellent Pythonx
  • Il peut être nécessaire de l’appeler depuis un seul processus Elixir ou de vérifier si la bibliothèque Python peut gérer des appels concurrents
  • En alternative, il est possible de gérer plusieurs processus Python avec System.cmd/3 ou Port
  • Pour les workflows IA, il est possible d’exécuter des modèles préentraînés via Bumblebee
  • Il est possible d’exécuter des modèles ONNX avec Ortex
  • Pour les LLM, on peut utiliser une API tierce ou exécuter un conteneur Docker Llama.cpp on-premise
  • Si l’on utilise une interface basée sur HTTP, on peut s’appuyer sur des outils Elixir comme Instructor et LangChain

Projet Fine

  • Pythonx est implémenté à l’aide de NIFs
  • Les NIFs sont des fonctions Elixir implémentées en C et nécessitent beaucoup de code boilerplate
  • La gestion mémoire et le traitement des erreurs y sont complexes
  • Pour répondre à cela, la bibliothèque C++ Fine a été développée
  • Fine fournit la conversion automatique des structures de données, la gestion sûre des objets ressources et la possibilité de lever des exceptions
  • Elle permet de réduire fortement la quantité de code nécessaire lors de l’écriture de NIFs

Conclusion

  • L’objectif du projet Numerical Elixir est de permettre à Elixir d’avoir sa propre identité dans l’écosystème de la donnée et du machine learning
  • Désormais, l’interopérabilité est également devenue un objectif majeur
  • Pythonx embarque Python dans Elixir et permet une interconversion transparente entre les deux langages

2 commentaires

 
aer0700 2025-03-01

J’adore vraiment Numpy...

 
GN⁺ 2025-02-28
Avis sur Hacker News
  • Les fonctionnalités de Livebook sont vraiment très chouettes. Le fait d’appeler directement CPython depuis Elixir via des NIFs C++ et de renvoyer des structures de données natives à Elixir est élégant

    • Utiliser Pythonx sur un serveur de production peut être un peu risqué. Comme il s’exécute dans le même processus OS que l’application Elixir, cela contourne les solides mécanismes de reprise sur panne des applis Elixir/BEAM
    • En général, les applications Elixir disposent d’un arbre de supervision capable de gérer avec élégance les échecs de leurs propres processus BEAM, et c’est l’un des grands atouts de langages comme Elixir, Erlang et Gleam
    • Lorsqu’on utilise des NIFs, une exception non gérée dans Pythonx peut arrêter l’ensemble du processus OS ainsi que tous les processus BEAM
    • Rustler est un wrapper NIF populaire pour Rust dans Elixir ; les NIFs peuvent être très utiles dans certains cas, mais il faut garder à l’esprit le risque de faire tomber l’application entière
    • Exécuter d’autres codes natifs comme Python ou Rust via des Ports est moins risqué de ce point de vue
  • C’est agréable de voir des figures « bien connues » de la communauté Elixir soutenir cette approche et la développer activement

    • La VM et le runtime sont particulièrement adaptés pour orchestrer d’autres langages et technologies, au point qu’on a l’impression qu’il existe une voie standard et une voie de déport de charge
    • La différence entre des idées de déport qui « semblent risquées » et une exécution sûre se résume souvent à la quantité de travail, mais le runtime l’encourage
    • Comme il s’agit d’un NIF, il y a un certain risque, mais il est possible de lancer une instance BEAM séparée et de distribuer via celle-ci
  • D’autres commentaires ont souligné les problèmes de sécurité liés à l’utilisation des NIFs

    • Le scheduler de la VM Erlang ne peut pas préempter un NIF, donc un appel Python de longue durée risque de bloquer la VM
    • Le GIL empêche l’exécution concurrente de Python, mais comme l’appelant Erlang peut lancer plusieurs interpréteurs Python, ce n’est pas un problème avec les Ports
  • Article très instructif. C’est bien qu’il mentionne clairement que Pythonx n’est pas un simple appel à un sous-processus, mais qu’il s’exécute dans le même processus

    • J’aurais aimé qu’on ajoute un exemple d’appel depuis Elixir à une fonction définie en Python
  • Cela fait plaisir de voir Elixir rattraper son retard dans la bataille de l’IA, même s’il est mieux adapté que JavaScript et Python

    • J’aime la décision initiale d’étendre dès le départ la base ML d’Elixir, mais c’est aussi une bonne chose d’avoir désormais un moyen de tirer parti des bibliothèques Python qui évoluent rapidement
  • Entrer dans l’écosystème Elixir/Erlang depuis Python m’a toujours semblé trop difficile, mais avec Pythonx, un apprentissage progressif paraît beaucoup plus envisageable

    • Je me demande s’ils ont expérimenté le free-threading pour les problèmes liés au GIL de Python
  • Elixir possède quelques fonctionnalités que j’aimerais voir en Python

    • les atoms, le fait que la plupart des choses soient des macros, le pipe |>, la véritable immutabilité, le vrai parallélisme et la vraie concurrence grâce aux arbres de supervision, le hot code reloading, la tolérance aux pannes
  • En tant que personne fortement impliquée dans Elixir et ayant beaucoup utilisé Python, je trouve cela très pratique

    • Je suis encore plus intéressé par la bibliothèque Fine, qui facilite la création de NIFs C++
  • J’ai l’impression que ce projet et ce billet de blog ont été faits pour moi. J’ai envie de l’essayer, merci