Skip to main content

Hyperbolic Deep Learning in JAX

Project description

Hyperbolix

Hyperbolic Deep Learning in JAX

Tests Python JAX License

Pure JAX implementation of hyperbolic deep learning with manifold operations, neural network layers, and Riemannian optimizers. Built with Flax NNX and Optax.

Features

  • 🌐 5 Manifolds: Euclidean, Poincaré Ball, Hyperboloid, Proper Velocity, and Product Manifold (mixed-curvature composition)
  • 🎛️ Learnable Curvature: LearnableCurvature module bundles parameter + reparameterization (softplus or log/exp) + optional clamp. Works with any nnx.Optimizer — no Riemannian optimizer needed
  • 🧠 20+ Neural Network Layers: Linear, convolutional, regression, attention, positional encoding, PV
  • 5 Hyperbolic Activations: ReLU, Leaky ReLU, Tanh, Swish, GELU
  • 📈 Riemannian Optimizers: RAdam and RSGD with automatic manifold detection
  • 🚀 Pure JAX/Flax NNX: vmap-native API, JIT-compatible (10-100x speedup)
  • 4,400+ tests passing (618 test functions, parametrized across seeds, dtypes, manifolds) with comprehensive benchmark suite

Quick Start

import jax.numpy as jnp
from flax import nnx
from hyperbolix.manifolds import Poincare
from hyperbolix.nn_layers import HypLinearPoincare

# Plain Python manifold class (optionally float64; pass `c=` for fixed curvature)
poincare = Poincare()  # add dtype=jnp.float64 as needed

# Manifold operations (single-point; use jax.vmap for batches)
x = jnp.array([0.1, 0.2])
y = jnp.array([0.3, -0.1])
distance = poincare.dist(x, y, c=1.0)

# Neural network layer
layer = HypLinearPoincare(
    manifold_module=poincare,
    in_dim=128,
    out_dim=64,
    rngs=nnx.Rngs(0),
)
output = layer(x_batch, c=1.0)

Mixed-Curvature Product Spaces

from hyperbolix.manifolds import ProductManifold, Hyperboloid, Poincare, Euclidean

# H^5 × P^3 × E^4 — points live in R^12, each factor keeps its own curvature
product = ProductManifold(
    (Hyperboloid(c=1.0), 5),
    (Poincare(c=0.1), 3),
    (Euclidean(), 4),
)
cs = product.curvatures        # (1.0, 0.1, 0.0) — pass per-factor at call time
d = product.dist(x, y, cs)     # sqrt(sum d_i^2) over factors

To make any factor's curvature trainable, store one LearnableCurvature instance per factor on your model and call it to obtain c for per-factor operations (see "Learnable curvature" below).

Installation

git clone https://github.com/hyperbolix/hyperbolix.git
cd hyperbolix
uv sync  # or: pip install -e .

Requirements: Python 3.12+, JAX 0.4.20+, Flax 0.8.0+, Optax 0.1.7+

Documentation

📖 Full Documentation

Build docs locally: uv run mkdocs serve

Key Concepts

Plain-class manifolds, curvature passed at call time: Each manifold is a plain Python class (not an nnx.Module) with automatic dtype casting; the curvature c is supplied per call so it can be static, dynamic, or a traced jax.Array driven by a learnable parameter on your model.

from hyperbolix.manifolds import Poincare
poincare = Poincare()  # add dtype=jnp.float64 as needed
dist = poincare.dist(x, y, c=1.0)  # (dim,) → scalar

vmap-native API: Methods operate on single points; use jax.vmap for batching.

distances = jax.vmap(poincare.dist, in_axes=(0, 0, None))(
    x_batch, y_batch, 1.0
)

Learnable curvature: Use the LearnableCurvature module — assign one instance per distinct curvature in your model and call it to obtain a positive (optionally clamped) value. The manifold itself stays a fixed plain Python class, which keeps it out of the NNX state pytree (safe to share the same instance across layers and inside nnx.scan / nnx.fori_loop). The default clamp [0.1, 10.0] matches published reference ranges; pass c_min=None, c_max=None to disable. Use parameterization="log" (MERU-style) when c may span orders of magnitude or for long compiled training loops; the default "softplus" matches van Spengler 2023.

from hyperbolix import LearnableCurvature
from hyperbolix.manifolds import Hyperboloid

class Model(nnx.Module):
    def __init__(self, rngs):
        self.manifold = Hyperboloid(c=1.0)               # static, shared
        self.curvature = LearnableCurvature(init_c=1.0)  # one per distinct c
        self.fc = HypLinearHyperboloidPP(self.manifold, 33, 65, rngs=rngs)

    def __call__(self, x):
        c = self.curvature()                              # positive, clamped
        return self.fc(x, c=c)

# Updated by any standard Euclidean optimizer — no Riemannian optimizer needed.
optimizer = nnx.Optimizer(model, optax.adam(1e-3), wrt=nnx.Param)

Citation

@software{hyperbolix2026,
  title = {Hyperbolix: Hyperbolic Deep Learning in JAX},
  author = {Klein, Timo and Lang, Thomas},
  year = {2026},
  url = {https://github.com/hyperbolix/hyperbolix}
}

References

Implements methods from:

  • Ganea et al. (2018): Hyperbolic Neural Networks
  • Bécigneul & Ganea (2019): Riemannian Adaptive Optimization
  • Gu et al. (2019): Learning Mixed-Curvature Representations in Product Spaces
  • Nagano et al. (2019): Wrapped Normal Distribution on Hyperbolic Space
  • Shimizu et al. (2020): Hyperbolic Neural Networks++
  • Bdeir et al. (2023): Fully Hyperbolic CNNs
  • Bdeir et al. (2025): Robust Hyperbolic Learning
  • Klis et al. (2026): Fast and Geometrically Grounded Lorentz Neural Networks
  • Chen et al. (2026): Proper Velocity Neural Networks

See individual module docstrings for detailed references.

Contributing

Contributions welcome! See DEVELOPER_GUIDE.md for setup and guidelines.

For bugs or questions, open an issue.

License

MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hyperbolix-0.8.0.tar.gz (110.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hyperbolix-0.8.0-py3-none-any.whl (145.1 kB view details)

Uploaded Python 3

File details

Details for the file hyperbolix-0.8.0.tar.gz.

File metadata

  • Download URL: hyperbolix-0.8.0.tar.gz
  • Upload date:
  • Size: 110.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for hyperbolix-0.8.0.tar.gz
Algorithm Hash digest
SHA256 1fef675364f0bdd6f5d42c7f2e9fbe414b2b8eeacc90407fd263839854aa1a8a
MD5 c51ca0542951b5daac56e840b4178a59
BLAKE2b-256 5b46420c77bd926fd155d9eb41067a881c538be73f82984d8c34c794bad7d97d

See more details on using hashes here.

File details

Details for the file hyperbolix-0.8.0-py3-none-any.whl.

File metadata

  • Download URL: hyperbolix-0.8.0-py3-none-any.whl
  • Upload date:
  • Size: 145.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for hyperbolix-0.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c22c66c7f09da96011af55b9e62c42b7bb98f805da5867d43e52caeca01a8d64
MD5 98654b2d13f5aaf3469d66b5b95d7407
BLAKE2b-256 acf3c85d6f350affb49109aa93f6bda11bdefd54e3c66467b461bf0008a5156e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page