InKAN
Fast B-spline Kolmogorov-Arnold Network layers for PyTorch.
6-15x faster than standard Cox-de Boor implementations (PyKAN, efficient-kan), faster than Gaussian RBF alternatives (FastKAN), while producing exact B-spline basis values with compact support, C2 continuity, and partition of unity.
How it works
Standard KAN implementations compute B-spline basis functions using the Cox-de Boor recursion: 3 sequential passes for cubic splines, each creating intermediate tensors. InKAN replaces this with the truncated power closed form:
N(u) = (1/6) [relu(u)³ - 4·relu(u-1)³ + 6·relu(u-2)³ - 4·relu(u-3)³ + relu(u-4)³]
This single expression computes exact B-spline values with no recursion, no span lookups, and no gather operations. torch.compile fuses all elementwise ops into one GPU kernel.
Installation
pip install inkan
Requirements: Python >= 3.9, PyTorch >= 2.0
Supported devices: CPU, CUDA (NVIDIA), MPS (Apple Silicon)
From source
git clone https://github.com/NAVEENMN/inkan.git
cd inkan
pip install -e .
Quick start
import torch
from inkan import KANLayer, KANNetwork
# Drop-in replacement for nn.Linear
layer = KANLayer(784, 64)
x = torch.randn(32, 784)
y = layer(x) # [32, 64]
# Multi-layer network
net = KANNetwork([784, 64, 10])
y = net(torch.randn(32, 784)) # [32, 10]
MNIST example
import torch
import torch.nn as nn
from inkan import KANNetwork
model = KANNetwork([784, 64, 10])
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
criterion = nn.CrossEntropyLoss()
# Standard PyTorch training loop
for images, labels in train_loader:
output = model(images.view(-1, 784))
loss = criterion(output, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
See examples/ for complete runnable scripts.
Visualization
InKAN includes built-in visualization for learned activation functions, similar to PyKAN's model.plot().
from inkan import KANNetwork, plot_basis, plot_activations, plot_network
model = KANNetwork([784, 32, 10], grid_size=8)
# ... train on MNIST ...
plot_basis(model.layers[0]) # B-spline basis bumps
plot_activations(model.layers[1]) # learned curves per edge
plot_network(model) # full network diagram
B-spline basis functions
The 8 basis bumps (grid_size=5, degree=3), compact support, smooth overlap:
Learned activation functions
After training on MNIST, each edge learns a unique activation curve. Cyan = total, red dashed = spline component, green dotted = SiLU base:
Network diagram
Full [784 → 32 → 10] network with learned curves on edges:
API
KANLayer(in_features, out_features, grid_size=5, spline_order=3)
A single KAN layer. Drop-in replacement for nn.Linear.
| Parameter | Default | Description |
|---|---|---|
in_features |
— | Input dimension |
out_features |
— | Output dimension |
grid_size |
5 | Number of knot intervals (more = finer approximation) |
spline_order |
3 | B-spline degree (3 = cubic, recommended) |
grid_range |
(-1, 1) | Input range for the spline grid |
KANNetwork(layer_dims, grid_size=5, spline_order=3)
Stack of KAN layers.
# 3-layer KAN: 784 -> 128 -> 64 -> 10
net = KANNetwork([784, 128, 64, 10])
Benchmarks
Forward pass time (ms) on Apple M-series GPU (MPS), batch=256:
| Layer | MNIST (784→64) | FashionMNIST (784→64) | CIFAR-10 (3072→64) |
|---|---|---|---|
| InKAN (compiled) | 0.27 | 0.20 | 0.39 |
| FastKAN (Gaussian RBF) | 0.38 | 0.31 | 0.99 |
| NoGather (unrolled) | 0.99 | 1.02 | 4.85 |
| Vanilla (Cox-de Boor) | 1.69 | 1.67 | 5.98 |
InKAN is 6.3x faster than vanilla Cox-de Boor on MNIST and 15.3x faster on CIFAR-10.
Why it's fast
91% of a standard KAN forward pass is spent computing B-spline basis functions. InKAN eliminates this bottleneck:
| Approach | Basis cost | Why |
|---|---|---|
| Cox-de Boor (PyKAN) | 3 sequential GPU passes | Each pass depends on previous |
| Gaussian RBF (FastKAN) | 1 exp() call |
Fast but not a true B-spline |
| Truncated power (InKAN) | 1 fused kernel | clamp + multiply is cheaper than exp() |
B-spline properties preserved
Unlike Gaussian RBF approximations, InKAN computes exact B-spline basis values:
- Compact support: each basis function is exactly zero outside its knot span window
- C2 continuity: second derivatives are continuous at every knot
- Partition of unity: basis values sum to 1 at every point in the interior
- Non-negativity: all basis values are >= 0
Verified: max difference vs Cox-de Boor reference is < 5e-5 in float32.
Project structure
src/inkan/
├── __init__.py # Public API
├── basis.py # Truncated power B-spline + torch.compile (core math)
├── layer.py # KANLayer
├── network.py # KANNetwork
└── visualize.py # plot_basis, plot_activations, plot_network
5 source files. The core innovation is in basis.py: 30 lines of math.
Citation
If you use InKAN in your research, please cite:
@software{inkan2026,
title={InKAN: B-Spline KANs via Truncated Power Form},
author={Mysore, Naveen},
year={2026},
url={https://github.com/NAVEENMN/inkan}
}
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file inkan-0.1.1.tar.gz.
File metadata
- Download URL: inkan-0.1.1.tar.gz
- Upload date:
- Size: 14.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
86f6e5c03ad94439d536b960a615c0b0227a84563547641e17eb3fa428a36b6d
|
|
| MD5 |
8e38954d724ac03015cbc10f34775f4e
|
|
| BLAKE2b-256 |
a8aa52a8a0f3b961bf8e8255f348081384d24c1c15bf1e56ec60cf999f9bcc09
|
File details
Details for the file inkan-0.1.1-py3-none-any.whl.
File metadata
- Download URL: inkan-0.1.1-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19213cd52b8d56f54ffc6ac065df909d007e9d784575f40848973442ebb8f0a9
|
|
| MD5 |
2bb9bc6301b2441a1d927c0d78d83b43
|
|
| BLAKE2b-256 |
5d77150597df73cebdb39b111d3fe9590db185f51460cf72067cfa6f05af34bd
|