Skip to main content

LowMind Neural Network Banner

⚡ Get Started in Seconds

pip install lowmind

Two dependencies. No CUDA. No cloud. Just NumPy.


🌟 Why LowMind?

Feature 🔥 PyTorch 🟢 TensorFlow LowMind
Install Size ~2.5 GB ~600 MB ~3 MB
Dependencies 50+ 30+ 2 only
Raspberry Pi Ready ❌ Painful ⚠️ Limited ✅ Native
PyTorch-like API
Reverse-mode Autograd
Zero CUDA Required
Embedded / IoT / Edge
System Health Monitor

LowMind is a pure-NumPy deep learning framework built from scratch for Raspberry Pi, embedded systems, and any resource-constrained environment. Train real models on a $35 computer.


🎯 Feature Coverage

  Core Capabilities                              Coverage
  ─────────────────────────────────────────────────────────
  🧠 Autograd Engine        ████████████████████  100%
  🏗️  Neural Layers         ████████████████████  100%
  ⚡ Activations            ████████████████████  100%
  📉 Loss Functions         ████████████████████  100%
  🚀 Optimizers (5 types)   ████████████████████  100%
  📅 LR Schedulers (7)      ████████████████████  100%
  📦 Data Pipeline          ████████████████████  100%
  📊 Metrics Suite          ████████████████████  100%
  🎯 High-level Trainer     ████████████████████  100%
  🔔 Callbacks              ████████████████████  100%
  🤖 Pre-built Models       ████████████████████  100%
  🖥️  System Monitor        ████████████████████  100%
  ⚙️  Model I/O (gzip)      ████████████████████  100%
  🔢 INT8 Quantization      ████████████████████  100%
  🔄 LSTM / GRU             ████████████████████  100%
  🔌 Embedded C++ Exporter  ████████████████████  100%
  🌐 Distributed Pi Cluster ░░░░░░░░░░░░░░░░░░░░  Planned

🗺️ Architecture

graph LR
    A[📂 Your Data<br/>numpy arrays] --> B

    subgraph DATA ["📦 Data Pipeline"]
        B[TensorDataset] --> C[DataLoader<br/>batch + shuffle]
    end

    subgraph MODEL ["🏗️  Model — Sequential / Custom Module"]
        D[Linear / Conv2d] --> E[Activation<br/>ReLU · GELU · Softmax]
        E --> F[BatchNorm / Dropout]
        F --> G[Output Layer]
    end

    subgraph ENGINE ["⚡ Training Engine"]
        H[Loss Function] --> I[loss.backward<br/>Autograd Graph]
        I --> J[Optimizer.step<br/>SGD · Adam · AdamW]
        J --> K[LR Scheduler]
    end

    subgraph CALLBACKS ["🔔 Callbacks"]
        L[EarlyStopping]
        M[ModelCheckpoint]
        N[History Logger]
    end

    subgraph MONITOR ["🖥️  System Monitor"]
        O[CPU · RAM · Temp]
        P[health_score 0–100]
        Q[memory_trace]
    end

    C --> D
    G --> H
    K --> CALLBACKS
    CALLBACKS --> R[💾 model.lmz<br/>Compressed]
    R --> S[🍓 Raspberry Pi<br/>Inference]
    MODEL --- MONITOR

    style DATA fill:#1a2a4a,color:#7dd3fc
    style MODEL fill:#1a3a2a,color:#86efac
    style ENGINE fill:#2a1a3a,color:#c4b5fd
    style CALLBACKS fill:#3a2a1a,color:#fdba74
    style MONITOR fill:#3a1a1a,color:#fca5a5

🚀 Quick Start

import lowmind as lm
import numpy as np

# ┌─────────────────────────────────────────────────────────┐
# │  1. Build Model                                         │
# └─────────────────────────────────────────────────────────┘
model = lm.Sequential(
    lm.Linear(784, 256),
    lm.ReLU(),
    lm.BatchNorm1d(256),
    lm.Dropout(0.3),
    lm.Linear(256, 128),
    lm.ReLU(),
    lm.Linear(128, 10),
)

print(model)              # prints architecture
model.num_parameters()    # → total trainable params

# ┌─────────────────────────────────────────────────────────┐
# │  2. Data                                                │
# └─────────────────────────────────────────────────────────┘
X = np.random.randn(1000, 784).astype(np.float32)
y = np.random.randint(0, 10, 1000)

X_train, X_val, y_train, y_val = lm.train_test_split(X, y, test_size=0.2)
train_loader = lm.DataLoader(lm.TensorDataset(X_train, y_train), batch_size=64, shuffle=True)
val_loader   = lm.DataLoader(lm.TensorDataset(X_val,   y_val),   batch_size=64)

# ┌─────────────────────────────────────────────────────────┐
# │  3. Train — one line                                    │
# └─────────────────────────────────────────────────────────┘
trainer = lm.Trainer(
    model     = model,
    optimizer = lm.Adam(model.parameters(), lr=1e-3),
    loss_fn   = lm.cross_entropy_loss,
    callbacks = [lm.EarlyStopping(patience=10), lm.ModelCheckpoint('/tmp/best.lmz')],
    clip_grad = 1.0,
    verbose   = 1,
)

history = trainer.fit(train_loader, val_loader, epochs=100)

# ┌─────────────────────────────────────────────────────────┐
# │  4. Evaluate & Save                                     │
# └─────────────────────────────────────────────────────────┘
val_loss, val_acc = trainer.evaluate(val_loader)
print(f"Val Accuracy: {val_acc:.2%}")
model.save('/tmp/model.lmz')         # compressed — ~70% smaller

📚 Full API Reference

🔢 Tensors & Autograd

lm.Tensor — N-dimensional array with automatic gradient tracking.

# ── Creating ────────────────────────────────────────────────
t = lm.Tensor([1., 2., 3.])                      # from list
t = lm.Tensor(np.array([[1, 2],[3, 4]]))          # from numpy
t = lm.Tensor(5.0, requires_grad=True)            # scalar with grad
lm.zeros(3, 4);  lm.ones(2, 2)                   # factory
lm.randn(10,10); lm.rand(5, 5)                   # random
lm.arange(0, 10, 2)   # → [0, 2, 4, 6, 8]

# ── Arithmetic ──────────────────────────────────────────────
c = a + b;  c = a - b;  c = a * b                # element-wise
c = a / b;  c = a ** 2; c = a @ b                # divide, power, matmul

# ── Reductions ──────────────────────────────────────────────
x.sum(axis=0);  x.mean(axis=(2, 3));  x.max(axis=1)

# ── Activations ─────────────────────────────────────────────
x.relu();  x.sigmoid();  x.tanh();  x.gelu()
x.softmax(axis=-1);  x.clip(-1, 1);  x.leaky_relu(0.01)

# ── Shape Ops ───────────────────────────────────────────────
x.reshape(6, 4);  x.flatten(start_dim=1)
x.transpose((0,2,1));  x.squeeze(1);  x.unsqueeze(0)

# ── Autograd Example ────────────────────────────────────────
x = lm.Tensor(3.0, requires_grad=True)
y = x**2 + 2*x + 1
y.backward()
print(x.grad)   # → 8.0  ✓  (dy/dx = 2x+2)

# Gradient clipping
lm.clip_grad_norm(model.parameters(), max_norm=1.0)

# ── Utilities ───────────────────────────────────────────────
t.item();  t.numpy();  t.detach();  t.copy()
t.shape;   t.ndim;    t.size;     t.zero_grad()

🏗️ Layers & Modules

# Linear
lm.Linear(784, 256, bias=True)                   # (N,784)→(N,256)

# Convolution
lm.Conv2d(3, 32, kernel_size=3, stride=1, padding=1)   # (N,3,H,W)→(N,32,H,W)

# Normalization
lm.BatchNorm1d(256)    # for (N, features)
lm.BatchNorm2d(32)     # for (N, C, H, W)

# Pooling
lm.MaxPool2d(2, 2)     # halves spatial dims
lm.AvgPool2d(2)

# Utility
lm.Flatten(start_dim=1)
lm.Dropout(p=0.5)      # auto-disabled at model.eval()
lm.Embedding(10000, 128)

# ── Custom Module ───────────────────────────────────────────
class ResBlock(lm.Module):
    def __init__(self, d):
        super().__init__()
        self.fc1 = lm.Linear(d, d)
        self.bn  = lm.BatchNorm1d(d)
        self.fc2 = lm.Linear(d, d)

    def forward(self, x):
        return (self.bn(self.fc2(self.fc1(x).relu())) + x).relu()

# ── Sequential ──────────────────────────────────────────────
model = lm.Sequential(
    lm.Linear(784, 256), lm.ReLU(), lm.BatchNorm1d(256),
    lm.Dropout(0.3),     lm.Linear(256, 10),
)
model.num_parameters()    # count params
model.summary()           # architecture table

📉 Loss Functions

lm.cross_entropy_loss(logits, targets)             # classification
lm.cross_entropy_loss(logits, targets, reduction='sum')
lm.binary_cross_entropy_loss(probs, targets)       # binary
lm.binary_cross_entropy_loss(logits, targets, from_logits=True)
lm.mse_loss(preds, targets)                        # regression
lm.mae_loss(preds, targets)                        # outlier-robust
lm.huber_loss(preds, targets, delta=1.0)           # smooth L1
lm.nll_loss(log_probs, targets)                    # after log-softmax

🚀 Optimizers

# All share the same interface:
optimizer.zero_grad()    loss.backward()    optimizer.step()

lm.SGD(model.parameters(), lr=0.01, momentum=0.9,
       weight_decay=1e-4, nesterov=True)

lm.Adam(model.parameters(), lr=1e-3, betas=(0.9,0.999),
        eps=1e-8, amsgrad=False)

lm.AdamW(model.parameters(), lr=1e-3, weight_decay=0.01)   # ← preferred

lm.RMSprop(model.parameters(), lr=1e-3, alpha=0.99, momentum=0.0)

lm.AdaGrad(model.parameters(), lr=0.01)

Convergence (lower is better, epoch 10):

SGD       ████████████████████░░░░░░░  0.42
AdaGrad   ████████████████░░░░░░░░░░░  0.28
RMSprop   █████████████░░░░░░░░░░░░░░  0.31
Adam      ████████░░░░░░░░░░░░░░░░░░░  0.18 ⭐
AdamW     ███████░░░░░░░░░░░░░░░░░░░░  0.16 ⭐⭐

📅 LR Schedulers

lm.StepLR(optimizer, step_size=10, gamma=0.5)
lm.MultiStepLR(optimizer, milestones=[30,60,90], gamma=0.1)
lm.ExponentialLR(optimizer, gamma=0.95)
lm.CosineAnnealingLR(optimizer, T_max=50, eta_min=1e-6)
lm.ReduceLROnPlateau(optimizer, mode='min', patience=5, factor=0.5)
lm.LinearWarmupLR(optimizer, warmup_steps=1000, target_lr=1e-3)
lm.CyclicLR(optimizer, base_lr=1e-4, max_lr=1e-1,
            step_size=2000, mode='triangular')   # step per batch!

📦 Data Utilities

# Datasets
ds = lm.TensorDataset(X_train, y_train)

class MyDataset(lm.Dataset):
    def __init__(self, X, y): self.X, self.y = X, y
    def __len__(self):         return len(self.X)
    def __getitem__(self, i):  return self.X[i], self.y[i]

# DataLoader
loader = lm.DataLoader(ds, batch_size=64, shuffle=True, drop_last=False)
for X_batch, y_batch in loader: ...

# Split
X_tr, X_val, y_tr, y_val = lm.train_test_split(
    X, y, test_size=0.2, shuffle=True, seed=42)

📊 Metrics

# Classification
lm.accuracy(preds, targets)                              # 0-1 float
lm.top_k_accuracy(logits, targets, k=5)
lm.precision(logits, targets, num_classes=10)            # macro
lm.recall(logits, targets,   num_classes=10)
lm.f1_score(logits, targets, num_classes=10)
lm.f1_score(logits, targets, num_classes=10, average='none')  # per-class
lm.confusion_matrix(logits, targets)                     # (C,C) array

# Regression
lm.r2_score(preds, targets)
lm.mean_squared_error(preds, targets)
lm.mean_absolute_error(preds, targets)

🤖 Pre-built Models

# Tabular / flat data
lm.MicroMLP(input_size=784, hidden_sizes=[256,128], output_size=10, dropout=0.3)

# Small images  (N, 3, 32, 32) → (N, 10)
lm.MicroCNN(in_channels=3, num_classes=10, input_size=32, dropout=0.2)

# Residual connections — more capacity
lm.TinyResNet(in_channels=3, num_classes=10, input_size=32, base_filters=16)

# ── Model I/O ───────────────────────────────────────────────
model.save('/path/model.lmz')             # compressed gzip
model.save('/path/model.lm', compress=False)
model.load('/path/model.lmz')
sd = model.state_dict()
model.load_state_dict(sd, strict=False)

🖥️ System Monitor

lm.configure_memory(max_mb=128)          # set budget

monitor = lm.SystemMonitor()
monitor.print_status()                   # CPU%, RAM, temp
score   = monitor.health_score()         # 0–100
stats   = monitor.get_stats()

with lm.memory_trace("Forward Pass"):
    out = model(X)

lm.memory_manager.optimize_for_inference()
lm.memory_manager.get_memory_info()
# {'allocated_mb': 12.3, 'max_mb': 128.0, 'usage_percent': 9.6}

🔌 Embedded C++ Inference Engine Exporter

Export your trained LowMind Sequential models directly into standard, highly-efficient, standalone C++ header files ready to compile and run on microcontrollers (Arduino, ESP32, STM32) without Python!

import lowmind as lm

# 1. Define input shape (C, H, W) or flat features
input_shape = (1, 8, 8)

# 2. Export model weights, biases, and layers to a self-contained header file
lm.export_to_cpp(model, input_shape, "embedded_model.h", namespace="my_embedded_model")

Key Advantages:

  • Ping-Pong Static Buffer Architecture: Avoids dynamic memory allocation (malloc/new) completely. Keeps memory consumption perfectly predictable and constant on small microcontrollers.
  • Pure Self-Contained C++: Generated with standard <cmath> and arrays. Zero external dependencies required.
  • Extensive Layer Support: Supports Linear, Conv2d, BatchNorm1d/BatchNorm2d, MaxPool2d, AvgPool2d, Flatten, ReLU, LeakyReLU, Sigmoid, Tanh, and Softmax layers.

✂️ Weight Pruning & Sparsity

Magnitude-based weight pruning API to zero out low-magnitude weights and calculate overall model sparsity.

import lowmind as lm

# Create a pruner for your model
pruner = lm.Pruner(model)

# Prune the entire model (skip biases by default) to a target sparsity ratio (0.0 to 1.0)
pruner.prune_model(sparsity_ratio=0.5)

# Prune specific weight parameters of a layer
pruner.prune_module_weight("fc.weight", sparsity_ratio=0.5)

# Re-apply pruning masks (vital to call after optimizer.step() during training)
optimizer.step()
pruner.apply_masks()

# Calculate current sparsity percentage of the model
sparsity_pct = pruner.calculate_sparsity()
print(f"Model Sparsity: {sparsity_pct:.2f}%")

🎯 INT8 Model Quantization

Post-Training Integer (INT8) Quantization helper to convert float32 weights to simulated 8-bit integer weights.

import lowmind as lm

# In-place quantization of model weights to simulate 8-bit integers
model.quantize()

# Alternatively, extract integer weights and scale factor of a specific tensor
q_data, scale = lm.quantize_weight(model[0].weight)

# Wrap quantized data in a container
quantized_tensor = lm.QuantizedTensor(q_data, scale)

# Convert back to float32 representation
float_data = quantized_tensor.dequantize()

🏋️ Quantization Aware Training (QAT)

Simulate the effects of 8-bit integer quantization during training using Straight-Through Estimators (STE). This allows the model's weights to adapt and learn quantization robust features, resulting in almost 0% accuracy drop when finally quantized to INT8!

import lowmind as lm

# 1. Enable QAT (Straight-Through Estimators) on all layers of a model
lm.prepare_qat(model, enabled=True)

# 2. Train the model normally using any trainer or custom loop
# Standard SGD, Adam, and backpropagation are fully supported
trainer.fit(loader, epochs=5)

# 3. Toggle QAT off after training
lm.prepare_qat(model, enabled=False)

# 4. Perform final INT8 quantization
model.quantize()

🎓 Knowledge Distillation

Knowledge Distillation Trainer to transfer knowledge from a heavy, pre-trained Teacher model to a lightweight Student model.

import lowmind as lm

# Setup DistillationTrainer (combines hard label loss and soft temperature-scaled loss)
trainer = lm.DistillationTrainer(
    student_model=student_model,
    teacher_model=teacher_model,
    optimizer=optimizer,
    loss_fn=lm.cross_entropy_loss,
    temperature=3.0,  # Soft target scaling temperature (default 3.0)
    alpha=0.5,        # Coefficient weight for soft loss vs hard loss (default 0.5)
    clip_grad=1.0,
    grad_accum_steps=1,
    verbose=1
)

# Train the student model
history = trainer.fit(train_loader, val_loader, epochs=10)

🗜️ Gradient Accumulation

Simulate large batch sizes on low-memory edge devices by accumulating gradients over multiple steps before performing an optimizer update.

import lowmind as lm

# Pass grad_accum_steps parameter to Trainer
trainer = lm.Trainer(
    model=model,
    optimizer=optimizer,
    loss_fn=lm.cross_entropy_loss,
    grad_accum_steps=4  # Accumulate over 4 steps (effectively 4x batch size)
)

🛡️ Gradient Checkpointing

Trade compute for massive memory savings on edge devices. Only save activations at checkpoints and recompute the rest during the backward pass on-the-fly.

import lowmind as lm

# Wrap Sequential block or any sub-module function in checkpoint
out = lm.checkpoint(model_block, input_tensor)

🚀 Hardware Bottleneck Accelerator

Check if hardware acceleration is active. Incorporates blazingly fast memory stride tricks and optional Numba Just-In-Time (JIT) compiler fallback to accelerate k-D convolutions at assembly-level speed (10x - 50x speedup!).

import lowmind as lm

# Check if hardware JIT/stride acceleration is active on this system
print("JIT Accelerated:", lm.is_jit_accelerated())

🔄 ONNX Model Export

Exports a LowMind model to standard ONNX format for cross-platform deployment on PyTorch, TensorFlow, ONNX Runtime, TensorRT, or Android/iOS accelerators.

import lowmind as lm
import numpy as np

# Define dummy input
dummy_input = np.random.randn(1, 3, 32, 32).astype(np.float32)

# Export and verify to standard .onnx file
onnx_model = lm.export_to_onnx(model, dummy_input, "model.onnx")

💡 10 Complete Examples

# Script Topic
01 01_basic_tensors.py Tensor creation, arithmetic, autograd from scratch
02 02_linear_regression.py Linear regression · SGD · custom loop
03 03_mlp_classification.py XOR classification · Adam · DataLoader
04 04_mnist_like.py Full pipeline · MicroMLP · EarlyStopping · Checkpointing
05 05_cnn_image.py MicroCNN · BatchNorm · MaxPool
06 06_optimizers_comparison.py SGD vs Adam vs RMSprop vs AdaGrad benchmark
07 07_custom_layer.py Attention layer · LayerNorm · Transformer block
08 08_save_load_model.py Save / load · state_dict · transfer learning
09 09_lr_schedulers.py Compare all 7 scheduler strategies
10 10_raspberry_pi_monitor.py System monitoring · memory tracing · health score
git clone https://github.com/dhaval-vedra/lowmind.git && cd lowmind
python examples/01_basic_tensors.py
python examples/04_mnist_like.py

📂 Project Structure

lowmind/
├── 📦 lowmind/                 ← Main package
│   ├── __init__.py             ← Public API (all exports here)
│   ├── core/
│   │   ├── tensor.py           ← 🧠 Tensor + autograd engine
│   │   ├── memory.py           ← 💾 MemoryManager (LRU, GC)
│   │   └── module.py           ← 🏗️  Module base class
│   ├── nn/
│   │   ├── layers.py           ← Linear, Conv2d, BatchNorm, Pool…
│   │   ├── activation.py       ← ReLU, GELU, Sigmoid, Softmax…
│   │   ├── loss.py             ← cross_entropy, bce, mse, huber…
│   │   └── sequential.py       ← Sequential container
│   ├── optim/
│   │   ├── sgd.py              ← SGD + Nesterov
│   │   ├── adam.py             ← Adam, AdamW, RMSprop, AdaGrad
│   │   └── scheduler.py        ← 7 LR schedulers
│   ├── data/
│   │   └── dataloader.py       ← Dataset, DataLoader, split
│   ├── utils/
│   │   ├── metrics.py          ← accuracy, f1, r2, confusion…
│   │   ├── trainer.py          ← High-level Trainer
│   │   ├── callbacks.py        ← EarlyStopping, Checkpoint, History
│   │   └── monitor.py          ← SystemMonitor, memory_trace
│   └── models/
│       └── micro_cnn.py        ← MicroMLP, MicroCNN, TinyResNet
├── 📁 examples/                ← 10 complete runnable examples
├── 🧪 tests/                   ← pytest test suite
├── 📖 docs/                    ← Extended documentation
├── setup.py
├── requirements.txt
└── README.md

🍓 Raspberry Pi — Deployment Guide

┌──────────────────┬────────────┬────────────┬─────────────────┬──────────────┐
│ Device           │ Memory     │ max_mb     │ batch_size      │ Best Model   │
├──────────────────┼────────────┼────────────┼─────────────────┼──────────────┤
│ Pi Zero W        │ 512 MB     │ 64         │ 4–8             │ MicroMLP     │
│ Pi 3 Model B     │ 1 GB       │ 128        │ 16              │ MicroCNN     │
│ Pi 4 (2 GB)      │ 2 GB       │ 256        │ 32              │ TinyResNet   │
│ Pi 4 (4 GB+)     │ 4–8 GB     │ 512        │ 64              │ TinyResNet   │
└──────────────────┴────────────┴────────────┴─────────────────┴──────────────┘
import lowmind as lm

# ① Set memory limit for your Pi
lm.configure_memory(max_mb=128)   # Pi 3

# ② Small batch sizes
loader = lm.DataLoader(ds, batch_size=16)

# ③ Pi-optimized architectures
model = lm.MicroCNN(in_channels=1, num_classes=10, input_size=28)

# ④ Monitor health during training
monitor = lm.SystemMonitor()
if monitor.health_score() < 40:
    print("⚠️  System stressed — reduce batch size or lr")

# ⑤ Free memory after training
lm.memory_manager.optimize_for_inference()
import gc; gc.collect()

# ⑥ Save compressed for deployment (~70% smaller)
model.save('/tmp/model.lmz', compress=True)

🤝 Contributing

Contributions are very welcome! Priority areas:

Area Difficulty Impact
📊 Pi benchmark suite Easy High
🔄 LSTM / GRU layers Medium High
⚡ INT8 Quantization Hard Very High
🌐 Multi-Pi distributed Hard Very High
# Fork → Branch → Code → Test → PR
git clone https://github.com/<you>/lowmind && cd lowmind
git checkout -b feature/my-awesome-feature
pip install pytest && pytest tests/ -v
# then open a PR 🎉

🧪 Running Tests

pip install pytest
pytest tests/ -v

📄 License

MIT License — free to use, modify, and distribute. See LICENSE.


Built with ❤️ in India 🇮🇳 by Dhaval Vedra

Empowering AI at the edge — from data centers down to $35 computers


GitHub stars   GitHub forks   GitHub watchers   Twitter Follow


Star this repo if LowMind helped you — it keeps the project alive!

Download files

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

Source Distribution

lowmind-2.2.0.tar.gz (109.2 kB view details)

Uploaded Source

Built Distribution

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

lowmind-2.2.0-py3-none-any.whl (78.0 kB view details)

Uploaded Python 3

File details

Details for the file lowmind-2.2.0.tar.gz.

File metadata

  • Download URL: lowmind-2.2.0.tar.gz
  • Upload date:
  • Size: 109.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.14

File hashes

Hashes for lowmind-2.2.0.tar.gz
Algorithm Hash digest
SHA256 88b23a6857b7c090fcacf0b93de7ba2aa5aab391f473b9c7dcd40dd87301c4f0
MD5 0a6f800baf24938162cd858194e61ff2
BLAKE2b-256 03771e6d3131f538b58b34e5e9d64ff7cc8ff8a64bd3bf9e5fe0ff7f547d8c22

See more details on using hashes here.

File details

Details for the file lowmind-2.2.0-py3-none-any.whl.

File metadata

  • Download URL: lowmind-2.2.0-py3-none-any.whl
  • Upload date:
  • Size: 78.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.14

File hashes

Hashes for lowmind-2.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dd8ac0bd1f6d59e70f5b00e1a8b0858d6d5314fd1616dcd2d9d200fa696958d9
MD5 75b1e424c3084b4788e3a0aa307c5322
BLAKE2b-256 6820ab1f1738284d843855268991b8e71a9e674c3f8e43352b23fa279dd2ac01

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

2.2.0 This release

2 files

2.1.0

1 file

1.8.1

2 files

1.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page