Durante años, quien quería hacer machine learning en un lenguaje funcional solo tenía una opción real: Haskell, con su ecosistema fragmentado y su curva de aprendizaje brutal. Elixir se estaba quedando fuera de esa conversación. Eso cambió en 2021 cuando José Valim anunció Nx, la librería de tensores para la BEAM, y el ecosistema que ha crecido alrededor de ella hace que en 2026 la situación sea muy diferente.
Nx: tensores numéricos en Elixir
Nx (Numerical Elixir) es una librería de tensores multidimensionales con soporte para operaciones en CPU y GPU. Su API está inspirada en NumPy pero diseñada para Elixir, con compilación JIT a través de backends como EXLA (basado en XLA de Google) o Torchx (basado en LibTorch de PyTorch).
# Crear tensores
a = Nx.tensor([[1, 2, 3], [4, 5, 6]])
b = Nx.tensor([[7, 8, 9], [10, 11, 12]])
# Operaciones básicas
suma = Nx.add(a, b)
producto = Nx.multiply(a, b)
transpuesta = Nx.transpose(a)
# Operaciones matriciales
c = Nx.dot(a, Nx.transpose(b))
# Reducciones
media = Nx.mean(a)
suma_por_fila = Nx.sum(a, axes: [1])
# Shape y tipo
IO.inspect(Nx.shape(a)) # {2, 3}
IO.inspect(Nx.type(a)) # {:s, 64}
Defn: compilación acelerada
La característica más importante de Nx es defn, un compilador de funciones numéricas que puede compilar a código optimizado para CPU o GPU:
defmodule MiModelo do
import Nx.Defn
# Esta función se compila con el backend configurado (EXLA, Torchx, etc.)
defn normalizar(tensor) do
media = Nx.mean(tensor)
desviacion = Nx.standard_deviation(tensor)
(tensor - media) / desviacion
end
defn softmax(tensor) do
exp = Nx.exp(tensor)
exp / Nx.sum(exp)
end
end
# Configurar el backend (en config/config.exs)
# config :nx, :default_backend, EXLA.Backend
Las funciones defn se comportan como funciones normales de Elixir pero se compilan la primera vez que se ejecutan. En ejecuciones posteriores usan la versión compilada, que puede ser órdenes de magnitud más rápida.
Axon: redes neuronales en Elixir
Axon es la librería de deep learning del ecosistema Nx. Define modelos como grafos computacionales y los entrena usando Nx como base:
# Definir un modelo de clasificación simple
modelo =
Axon.input("entrada", shape: {nil, 784})
|> Axon.dense(256, activation: :relu)
|> Axon.dropout(rate: 0.3)
|> Axon.dense(128, activation: :relu)
|> Axon.dense(10, activation: :softmax)
# Entrenar
{estado_inicial, _} = Axon.build(modelo)
loop =
modelo
|> Axon.Loop.trainer(:categorical_cross_entropy, :adam)
|> Axon.Loop.metric(:accuracy)
|> Axon.Loop.run(datos_entrenamiento, estado_inicial, epochs: 10)
Explorer: datos tabulares
Explorer es la librería de dataframes de Elixir, similar a pandas en Python o Polars en Rust (de hecho, usa Polars como backend por defecto, lo que la hace muy rápida):
alias Explorer.DataFrame, as: DF
alias Explorer.Series, as: S
# Cargar datos
df = DF.from_csv!("datos.csv")
# Explorar
IO.inspect(DF.shape(df)) # {1000, 5}
IO.inspect(DF.dtypes(df)) # %{edad: :integer, nombre: :string, ...}
# Filtrar y transformar
resultado =
df
|> DF.filter(col("edad") > 18)
|> DF.select(["nombre", "edad", "ciudad"])
|> DF.sort_by(col("edad"))
|> DF.head(10)
# Estadísticas
media_edad = df["edad"] |> S.mean()
Livebook: notebooks para la BEAM
Livebook es el equivalente a Jupyter Notebook para Elixir. Es una aplicación web open source que permite escribir notebooks interactivos donde el código Elixir se ejecuta en celdas. Está construido con Phoenix LiveView, lo que hace que la colaboración en tiempo real sea nativa.
Lo que distingue a Livebook de Jupyter no es solo el lenguaje: es el modelo de ejecución. En Jupyter, las celdas comparten estado de forma global y el orden de ejecución importa. En Livebook, cada sección puede tener su propio proceso con estado aislado, y el grafo de dependencias entre celdas es explícito.
Para instalar y usar Livebook:
# Instalar como escript mix escript.install hex livebook # O correr con Docker # docker run -p 8080:8080 ghcr.io/livebook-dev/livebook # En Livebook, explorar datos con Kino Kino.DataTable.new(df) # tabla interactiva Kino.VegaLite.new() # gráficos con Vega-Lite
El ecosistema en 2026
El ecosistema de ML en Elixir ha madurado considerablemente. Hay bindings para modelos de Hugging Face a través de Bumblebee, que permite cargar modelos preentrenados (BERT, Whisper, Stable Diffusion) y ejecutarlos directamente en Elixir:
# Clasificación de texto con BERT
{:ok, modelo} = Bumblebee.load_model({:hf, "bert-base-uncased"})
{:ok, tokenizer} = Bumblebee.load_tokenizer({:hf, "bert-base-uncased"})
servicio = Nx.Serving.new(Bumblebee.Text.fill_mask(modelo, tokenizer))
output = Nx.Serving.run(servicio, "Elixir es un lenguaje [MASK].")
Elixir no va a sustituir a Python para ML en el corto plazo. Python tiene décadas de ecosistema, librerías especializadas para cada nicho y una comunidad enorme. Pero para equipos que ya usan Elixir y quieren añadir capacidades de ML sin cambiar de stack, o para pipelines de inferencia donde la concurrencia y la tolerancia a fallos importan, el ecosistema Nx es una opción seria. Para comparar con el estado del arte en Python para ML, el artículo sobre Python y LLMs en 2026 da una perspectiva complementaria.
Imagen: Pexels / Google DeepMind
