10 pontos por GN⁺ 2025-02-28 | 2 comentários | Compartilhar no WhatsApp
  • Nos últimos anos, o Elixir vem ampliando suas capacidades nas áreas de machine learning e dados por meio do projeto Nx (Numerical Elixir)
  • Projetos como Nx, Explorer, Axon, Bumblebee e Scholar surgiram e continuam evoluindo com base nas lições aprendidas nos ecossistemas de Python e R
  • No início, decidiu-se não depender diretamente de bibliotecas Python, para buscar um design otimizado para Elixir e evitar a complexidade da configuração de ambientes Python
  • No entanto, hoje quem está liderando a adoção do Elixir nessa área é o Livebook
    • Uma plataforma de notebooks na linha de frente da reprodutibilidade, execução distribuída e desenvolvimento de aplicativos, baseada nos pontos fortes do Elixir e do Erlang
    • O interesse de equipes e empresas que querem dar seus primeiros passos no ecossistema Elixir por meio do Livebook está crescendo cada vez mais
  • Mas existe um obstáculo
    • A maioria das empresas que pretende adotar Elixir e Livebook em sua infraestrutura já usa workflows, pacotes e repositórios baseados em Python
    • Isso significa ter que encontrar pacotes equivalentes em Elixir ou reescrevê-los do zero, o que aumenta o risco e o custo de adicionar Elixir à stack de dados
  • Para resolver isso, foi anunciado o Pythonx, que incorpora o interpretador Python dentro da Erlang VM

Pythonx

  • O Pythonx oferece conversão automática de dados entre Elixir e Python, execução de código e gerenciamento de ambientes virtuais
  • É possível usar o pacote pytesseract para realizar Optical Character Recognition (OCR)
  • Após baixar uma imagem com req, chama-se Pythonx.uv_init/1 para baixar e inicializar o Python e suas dependências
  • Usa-se Pythonx.eval/2 para executar código Python e converter o resultado em uma string Elixir

Estrutura interna

  • A implementação de referência CPython do Python pode ser incorporada a outras aplicações
  • A funcionalidade central do interpretador Python é fornecida como uma biblioteca em C
  • Aplicações em C/C++ podem linkar essa biblioteca e usar a API para executar código e interagir com objetos
  • O Elixir oferece interoperabilidade com C/C++ por meio de Erlang NIFs
  • O Pythonx usa NIFs para incorporar Python e opera no mesmo processo do sistema operacional
  • A transferência de dados entre Python e Elixir acontece de forma eficiente
Publicidade

Suporte multilíngue no Livebook

  • Com base no Pythonx, está em andamento a adição de suporte a Python no Livebook
  • Elixir e Python poderão interagir dentro do mesmo notebook
  • O Livebook instala automaticamente o Python e suas dependências e gerencia a conversão entre variáveis Elixir e Python
  • Isso garante um ambiente reproduzível
  • Trabalhos adicionais, como autocomplete e documentação, ainda estão em andamento, e já é possível baixar e usar o Livebook nightly

Pontos a considerar no uso e alternativas

  • O principal objetivo do Pythonx é integrar workflows em Python dentro do Livebook e de scripts
  • Devido ao Global Interpreter Lock (GIL) do Python, pode haver limitação de concorrência ao chamar Pythonx a partir de vários processos Elixir
  • É necessário chamar a partir de um único processo Elixir ou verificar se a biblioteca Python consegue lidar com chamadas concorrentes
  • Como alternativa, é possível usar System.cmd/3 ou Port para gerenciar vários processos Python
  • Em workflows de IA, é possível executar modelos pré-treinados com Bumblebee
  • Também é possível executar modelos ONNX com Ortex
  • No caso de LLMs, é possível usar APIs de terceiros ou executar um contêiner Docker do Llama.cpp on-premises
  • Ao usar interfaces baseadas em HTTP, é possível recorrer a ferramentas do Elixir como Instructor e LangChain

Projeto Fine

  • O Pythonx é implementado usando NIFs
  • NIFs são funções Elixir implementadas em C e exigem bastante código boilerplate
  • Há complexidade no gerenciamento de memória e no tratamento de erros
  • Para resolver isso, foi desenvolvida a biblioteca Fine, baseada em C++
  • O Fine oferece conversão automática de estruturas de dados, gerenciamento seguro de objetos de recurso e geração de exceções
  • Isso pode reduzir significativamente a quantidade de código ao escrever NIFs

Conclusão

  • O objetivo do projeto Numerical Elixir é fazer com que o Elixir tenha uma identidade própria no ecossistema de dados e machine learning
  • Agora, a interoperabilidade também se tornou um objetivo principal
  • O Pythonx incorpora Python ao Elixir, permitindo interoperabilidade transparente entre as duas linguagens

2 comentários

 
aer0700 2025-03-01

O Numpy é realmente ótimo...

 
GN⁺ 2025-02-28
Comentários no Hacker News
  • Os recursos do Livebook são muito legais. É elegante como ele chama o CPython diretamente do Elixir por meio de NIFs em C++ e retorna estruturas de dados nativas do Elixir

    • Em servidores de produção, usar Pythonx pode ser um pouco arriscado. Como ele roda no mesmo processo do SO que o app Elixir, acaba contornando os fortes mecanismos de recuperação de falhas do app Elixir/BEAM
    • Em geral, apps Elixir têm árvores de supervisão capazes de lidar com falhas dos próprios processos BEAM de forma graciosa, e essa é uma grande vantagem de linguagens como Elixir, Erlang e Gleam
    • Ao usar NIFs, se ocorrer uma exceção não tratada no Pythonx, isso pode derrubar todo o processo do SO e todos os processos BEAM
    • Rustler é um wrapper de NIF popular para Rust no Elixir; há casos em que NIFs são muito úteis, mas é preciso considerar o risco de derrubar a aplicação inteira
    • Executar outro código nativo, como Python ou Rust, via Ports é menos arriscado nesse aspecto
  • É bom ver pessoas "bem conhecidas" da comunidade Elixir apoiando essa abordagem e desenvolvendo-a ativamente

    • A VM e o runtime parecem muito adequados para orquestrar outras linguagens e tecnologias, como se houvesse uma trilha padrão e uma trilha de offload
    • A diferença entre ideias de offload que "parecem arriscadas" e uma execução segura muitas vezes é só carga de trabalho, mas o runtime incentiva isso
    • Por ser um NIF, existe um pouco de risco, mas é possível iniciar uma instância separada do BEAM e distribuir por meio dela
  • Houve outros comentários apontando questões de segurança no uso de NIFs

    • O escalonador da VM Erlang não pode preemptar um NIF, então chamadas Python de longa duração correm o risco de bloquear a VM
    • O GIL impede execução simultânea de Python, mas o chamador Erlang pode executar múltiplos interpretadores Python, então isso não é um problema com Ports
  • Artigo muito informativo. Foi bom deixar claro que Pythonx não é apenas uma chamada de subprocesso, mas algo que roda no mesmo processo

    • Seria bom acrescentar um exemplo chamando, a partir do Elixir, uma função definida em Python
  • Fico feliz em ver o Elixir alcançando JavaScript e Python na corrida de IA, apesar de estar atrás, mesmo sendo mais adequado

    • Gosto da decisão inicial de expandir a base de ML do Elixir do zero, mas também é bom que agora exista uma forma de aproveitar bibliotecas Python que evoluem rapidamente
  • Sempre pareceu difícil demais entrar no ecossistema Elixir/Erlang vindo do Python, mas com Pythonx o aprendizado gradual parece muito mais viável

    • Fico curioso se experimentaram free threading em relação ao problema do GIL no Python
  • Há alguns recursos no Elixir que eu queria que existissem no Python

    • atoms, o fato de quase tudo ser macro, o pipe |>, imutabilidade real, paralelismo e concorrência reais graças às árvores de supervisão, hot code reloading, tolerância a falhas
  • Como alguém profundamente envolvido com Elixir e que usou bastante Python, acho isso muito prático

    • Tenho ainda mais interesse na biblioteca Fine, que facilita criar NIFs em C++
  • Este projeto e este post de blog parecem ter sido feitos para mim. Quero testar, obrigado