A compact define-by-run deep learning framework written in Python
Project description
Pinenut
English | 简体中文
Pinenut is a compact, define-by-run deep learning framework written in Python. It provides automatic differentiation, neural-network modules, optimization algorithms, and a shared NumPy/CuPy API for CPU and NVIDIA GPU execution. Its small codebase is designed to be easy to read, experiment with, and extend.
Highlights
- Dynamic computational graphs with first- and higher-order gradients
- A consistent
Module,Parameter, andOptimizerinterface - Common layers, activations, losses, datasets, and optimizers
- NumPy execution on CPU and optional CuPy acceleration on NVIDIA GPUs
- Model state dictionaries and synchronous multi-GPU training
- Pure Python implementation suitable for learning and small experiments
Requirements
- Python 3.8 or later
- NumPy 1.20 or later
- Optional GPU support: a compatible NVIDIA driver and exactly one supported CuPy package
Installation
Install the latest release from PyPI:
python -m pip install --upgrade pinenut
Or install the current source tree in editable mode:
git clone https://github.com/pinenuthome/pinenut.git
cd pinenut
python -m pip install -e .
For NVIDIA GPUs, install the extra matching your CUDA major version:
# CUDA 12.x
python -m pip install "pinenut[gpu-cu12]"
# CUDA 13.x
python -m pip install "pinenut[gpu-cu13]"
Install only one CuPy distribution in an environment. For virtual-environment setup, distribution-specific prerequisites, CUDA troubleshooting, and a real two-GPU check, see the Linux installation guide.
Automatic differentiation
Build a dynamic graph and differentiate a scalar result:
import numpy as np
import pinenut as pn
x = pn.tensor(np.array([1.0, 2.0, 3.0]))
loss = pn.sum(x ** 2)
loss.backward()
print(loss.data) # 14.0
print(x.grad.data) # [2. 4. 6.]
Set create_graph=True when a later computation needs to differentiate the
resulting gradient:
x = pn.tensor(3.0)
y = x ** 2
y.backward(create_graph=True)
first_derivative = x.grad
x.zero_grad()
first_derivative.backward()
print(x.grad.data) # 2.0
Neural-network training
Modules expose parameters to optimizers and use explicit training and evaluation modes:
import numpy as np
import pinenut as pn
from pinenut import nn, optim
from pinenut.nn import functional as F
model = nn.Sequential(
nn.Linear(2, 32),
nn.ReLU(),
nn.Dropout(0.1),
nn.Linear(32, 3),
)
optimizer = optim.Adam(model.parameters(), lr=0.001)
inputs = pn.tensor(np.random.randn(8, 2))
targets = pn.tensor(np.random.randint(0, 3, size=8))
model.train()
optimizer.zero_grad()
logits = model(inputs)
loss = F.cross_entropy(logits, targets)
loss.backward()
optimizer.step()
model.eval()
with pn.no_grad():
predictions = model(inputs)
Available components include Linear, LazyLinear, Sequential, MLP,
Embedding, Dropout, SGD, Adagrad, and Adam. SGD accepts an optional
momentum value. Classification losses accept unnormalized logits, so the
final layer should not apply softmax when used with F.cross_entropy.
Devices
Use the same model and tensor API on CPU and GPU:
device = 'cuda' if pn.cuda.is_available() else 'cpu'
model.to(device)
inputs.to(device)
targets.to(device)
Specific GPUs can be selected with names such as cuda:1. Calling cpu(),
cuda(), or to(device) moves a tensor or module in place and returns it.
Saving model state
pn.save(model.state_dict(), 'model_weights.npz')
restored = nn.Sequential(
nn.Linear(2, 32),
nn.ReLU(),
nn.Dropout(0.1),
nn.Linear(32, 3),
)
restored.load_state_dict(pn.load('model_weights.npz'))
restored.eval()
Examples
Run the Spiral visualization to train an MLP and save its decision boundary, metrics, and state dictionary:
python examples/nn/test_spiral.py
python examples/nn/test_spiral.py --animate
Outputs are written to demo_outputs/spiral/. Use --help to configure the
dataset, model, training schedule, output directory, and CPU/GPU selection.
Tests
Install the development dependencies and run the CPU-compatible test suite:
python -m pip install -r requirements-dev.txt
python -m pip install -e . --no-deps
python -m unittest discover -s test -v
On a machine with two physical NVIDIA GPUs, run the synthetic multi-GPU smoke test:
CUDA_VISIBLE_DEVICES=0,1 python tools/test_multigpu.py --devices 0,1
To test physical GPUs 2 and 3, remap them to logical devices 0 and 1:
CUDA_VISIBLE_DEVICES=2,3 python tools/test_multigpu.py --devices 0,1
The command prints MULTI-GPU SMOKE TEST PASSED when device placement,
training, parameter synchronization, and finite-value checks all succeed.
Project structure
core/ Automatic differentiation and internal implementations
nn/ Neural-network modules and stateless functions
optim/ Optimization algorithms
datasets/ Built-in datasets
utils/ Data loading and utility interfaces
examples/ Runnable training and visualization examples
test/ Unit and regression tests
tools/ Standalone verification utilities
docs/ Installation and usage guides
Contributing
Issues and pull requests are welcome. Please add or update tests for behavioral changes and run the test suite before submitting a pull request.
License
Pinenut is released under the MIT License.
Project details
Release history Release notifications | RSS feed
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 pinenut-1.2.0.tar.gz.
File metadata
- Download URL: pinenut-1.2.0.tar.gz
- Upload date:
- Size: 41.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f6a40eb79e951937c48aadce437a4a02f87c22a2c5dde1a4e58b2ae97fe2d5a0
|
|
| MD5 |
5524c0740afef2b24ea508bdb5123958
|
|
| BLAKE2b-256 |
dbf12d6a0d85e4481d0a62c59efb4cb6f1d32ed9771f25e8bed1a6d92dac826c
|
File details
Details for the file pinenut-1.2.0-py3-none-any.whl.
File metadata
- Download URL: pinenut-1.2.0-py3-none-any.whl
- Upload date:
- Size: 27.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d36ca268d7865ea66f78ca0e6fd66554a76702ca169c24e855d51771cc1c042
|
|
| MD5 |
0dce66185fcc81415044b00196737184
|
|
| BLAKE2b-256 |
b77df78899790dc307c1070b1f58f065112e779861bf142692b5c36178de83cb
|