Skip to main content

High-Performance Computer Vision & Deep Learning Framework in C++ & CUDA with PyTorch Parity

Project description

🌌 newton-vision

C++17 ve CUDA çekirdekli, PyTorch ekosistemiyle uyumlu, eğitim ve araştırma odaklı hafif derin öğrenme framework'ü.

PyPI Version License: MIT Python 3.9+


İçindekiler

  1. Proje Nedir?
  2. Kurulum
  3. Modül Haritası
  4. Hızlı Başlangıç — 3 Senaryo
  5. Model Zoo — Hazır Mimariler
  6. Katman Referansı — Tüm Layer API
  7. Tensor & Autograd Motoru
  8. Kayıp Fonksiyonları & Optimizatörler
  9. INT8 Kuantizasyon Motoru
  10. JIT & Serileştirme Motoru
  11. PyTorch Ağırlık Aktarımı
  12. Cihaz Yönetimi — CPU & CUDA
  13. C++ Backend Mimarisi
  14. Benchmark Sonuçları
  15. Transformer & LLM Yetkinliği
  16. Örnek Projeler & Öğreticiler
  17. Test Kapsamı
  18. Katkıda Bulunma
  19. Güvenlik Politikası
  20. Sürüm Geçmişi
  21. Lisans

❓ Proje Nedir?

Bu Framework Ne Yapar?

newton-vision aşağıdaki yetenekleri sıfırdan C++17, CUDA ve Python ile gerçekleştirir:

Yetenek Açıklama
Reverse-Mode Autograd Topolojik sıralama ile otomatik türev hesaplama (backward pass)
CNN Katmanları Conv2d, MaxPool2d, AvgPool2d, BatchNorm2d (C++ im2col + GEMM ile)
Transformer Katmanları MultiHeadAttention, LayerNorm, GELU, PatchEmbedding
Model Zoo ResNet-18, MobileNetV2, ViT-Tiny, ViT-Base
Eğitim Döngüsü CrossEntropyLoss, MSELoss, Adam, SGD (momentum destekli)
INT8 Kuantizasyon Per-Channel ve Global INT8 kuantizasyon, QuantizedLinear
PyTorch Uyumluluğu state_dict birebir yükleme desteği
JIT / Serileştirme .nv (sıkıştırılmış), .nv.bin (saf C++ ikili), ONNX export
InferenceEngine FPS ve gecikme takipli canlı çıkarım motoru
Cihaz Yönetimi CPU/CUDA geçişi, AVX2 SIMD otomatik tespiti

Neden Var?

Derin öğrenme algoritmalarının arkasındaki matematiksel ve donanımsal mantığı (L1/L2 Cache Locality, SIMD AVX2, Topolojik Autograd Sıralaması) şeffaf bir şekilde göstermek, deneyler yapmak ve C++ ortamında bağımsız hızlı çıkarım çalıştırmak için geliştirilmiştir.

Kim Kullanmalı?

  • Derin öğrenme motorlarının iç çalışma mekanizmasını öğrenmek isteyen araştırmacılar ve öğrenciler
  • PyTorch'ta eğittiği modelleri Python bağımlılığı olmadan C++ ortamında çalıştırmak isteyen mühendisler
  • INT8 kuantizasyon ile bellek optimizasyonu yapmak isteyen geliştiriciler

Kim Kullanmamalı?

  • Petabaytlarca veri üzerinde binlerce GPU ile devasa LLM eğitimi yapacak büyük endüstriyel dağıtık sistem ekipleri (PyTorch / JAX kullanmaya devam etmelidirler)

PyTorch İle İlişkisi Ne?

newton-vision, PyTorch'un rakibi veya "katili" değildir. PyTorch .pth state_dict ağırlıklarını birebir yükleyebilen, PyTorch ekosistemiyle uyumlu çalışan bir kardeş altyapıdır.


🚀 Kurulum

pip install newton-vision

Gereksinimler:

  • Python 3.9+
  • NumPy >= 1.20.0
  • C++17 uyumlu derleyici (build için: MSVC, GCC, Clang)
  • CUDA Toolkit (opsiyonel, GPU ivmelendirme için)

🗺️ Modül Haritası & API Referansı

newton-vision Newton fiziği temalı bir isimlendirme sistemine sahiptir:

newton_vision
├── optics         → Görsel Katmanlar (Conv2d, Linear, BatchNorm2d, LayerNorm, GELU, MultiHeadAttention...)
├── fluxion        → Autograd Türev Motoru (Tensor, backward, .cuda(), .cpu(), .to(device))
├── gravity        → Kayıp & Optimizatörler (MSELoss, CrossEntropyLoss, SGD, Adam)
├── principia      → Cihaz Yönetimi (is_cuda_available, get_device, set_device)
├── models         → Model Zoo (ResNet18, MobileNetV2, VisionTransformer, vit_tiny, vit_base)
├── quantization   → INT8 Kuantizasyon (quantize_model, quantize_tensor, QuantizedLinear)
├── weights        → PyTorch Ağırlık Aktarıcı (load_state_dict)
└── jit            → Serileştirme & Çıkarım (InferenceEngine, save/load_model, export_onnx)

Her modüle import newton_vision as nv ile erişilir:

import newton_vision as nv

# Katmanlar (optics aracılığıyla veya doğrudan):
nv.Conv2d, nv.Linear, nv.ReLU, nv.GELU, nv.BatchNorm2d, nv.LayerNorm, nv.MultiHeadAttention

# Modeller:
nv.models.resnet18(), nv.models.mobilenet_v2(), nv.models.vit_tiny(), nv.models.vit_base()

# Eğitim:
nv.gravity.CrossEntropyLoss(), nv.gravity.Adam(), nv.gravity.SGD()

# Kuantizasyon:
nv.quantize_model(), nv.quantize_tensor(), nv.QuantizedLinear()

# JIT / Serileştirme:
nv.save_model(), nv.load_model(), nv.export_onnx(), nv.InferenceEngine()

# Cihaz:
nv.principia.is_cuda_available(), nv.principia.set_device("cuda")

⚡ Hızlı Başlangıç — 3 Temel Senaryo

Senaryo 1: Sıfırdan Model Eğitimi (Sadece newton-vision)

Hiçbir harici framework'e ihtiyaç duymadan, saf Autograd türev grafı ile model eğitimi:

import newton_vision as nv
import numpy as np

# ── 1. Sentetik Veri Seti ──────────────────────────────────────────
np.random.seed(42)  # Tekrarlanabilirlik
X_train = np.random.randn(80, 16).astype(np.float32)
y_train = np.random.randint(0, 3, size=(80,)).astype(np.int64)

# ── 2. Model Mimarisi (2 Katmanlı MLP) ────────────────────────────
fc1 = nv.Linear(16, 32)
relu = nv.ReLU()
fc2 = nv.Linear(32, 3)

# ── 3. Optimizatör & Kayıp ────────────────────────────────────────
all_params = fc1.parameters() + fc2.parameters()
optimizer = nv.gravity.Adam(all_params, lr=0.02)
loss_fn = nv.gravity.CrossEntropyLoss()

# ── 4. Eğitim Döngüsü (30 Epoch) ─────────────────────────────────
for epoch in range(1, 31):
    x = nv.Tensor(X_train, requires_grad=True)

    # Forward Pass
    logits = fc2(relu(fc1(x)))
    loss = loss_fn(logits, y_train)

    # Backward Pass (Otomatik Türev)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 10 == 0:
        pred = np.argmax(logits.data, axis=1)
        acc = np.mean(pred == y_train) * 100
        print(f"Epoch {epoch:02d}/30 | Loss: {float(loss.data):.4f} | Acc: {acc:.1f}%")

# Beklenen Çıktı:
# Epoch 10/30 | Loss: 0.8234 | Acc: 68.8%
# Epoch 20/30 | Loss: 0.4512 | Acc: 87.5%
# Epoch 30/30 | Loss: 0.2103 | Acc: 96.2%

Bu Kod Ne Yapıyor:

  1. 80 örnekli 3 sınıflı sentetik veri oluşturur
  2. Linear(16→32) → ReLU → Linear(32→3) mimarisinde bir MLP tanımlar
  3. Adam optimizatörü ile CrossEntropy kaybını minimize eder
  4. Her epoch'ta loss.backward() çağrısı ile topolojik sıralamaya göre tüm parametrelerin gradyanlarını otomatik hesaplar

Senaryo 2: ViT-Tiny ile Çıkarım (Inference)

import newton_vision as nv
import numpy as np

# ── 1. Görüntü Tensörü (Batch=1, C=3, H=224, W=224) ──────────────
x = nv.Tensor(np.random.randn(1, 3, 224, 224).astype(np.float32))

# ── 2. Vision Transformer Modeli ──────────────────────────────────
model = nv.models.vit_tiny(num_classes=1000)

# ── 3. İleri Geçiş ───────────────────────────────────────────────
logits = model(x)
print(f"Çıktı boyutu: {logits.data.shape}")  # (1, 1000)

# ── 4. Tahmin ─────────────────────────────────────────────────────
predicted_class = np.argmax(logits.data, axis=1)
print(f"Tahmin edilen sınıf: {predicted_class[0]}")

ViT-Tiny Mimarisi:

  • Embed Dim: 192, Depth: 12 Transformer blok, Heads: 3
  • Patch Size: 16×16, Image Size: 224×224
  • Parametre sayısı: ~5.7M
  • Toplam katman akışı: PatchEmbedding → [CLS Token + Positional Embedding] → 12x TransformerBlock → LayerNorm → Linear Head

Senaryo 3: PyTorch Ağırlık Aktarımı & INT8 Kuantizasyon

import newton_vision as nv
import numpy as np

# ── PyTorch'ta eğitilmiş ağırlıkları yükle ────────────────────────
# (PyTorch kurulu değilse bile .npy dosyasından yüklenebilir)
try:
    import torch
    torch_model = torch.nn.Linear(10, 5)
    w_np = torch_model.weight.detach().numpy().T  # PyTorch: (out, in) → newton: (in, out)
    b_np = torch_model.bias.detach().numpy()
except ImportError:
    # PyTorch yoksa rastgele ağırlık
    w_np = np.random.randn(10, 5).astype(np.float32) * 0.1
    b_np = np.zeros(5, dtype=np.float32)

# ── INT8 Kuantize Katman Oluştur ──────────────────────────────────
q_layer = nv.QuantizedLinear(in_features=10, out_features=5)
q_layer.load_fp32_weights(w_np, b_np)

# ── 4x Küçük Bellekle Çıkarım ────────────────────────────────────
test_input = np.random.randn(4, 10).astype(np.float32)
output = q_layer(test_input)
print(f"INT8 çıktı boyutu: {output.data.shape}")  # (4, 5)

# ── Bellek Tasarrufu Hesaplama ────────────────────────────────────
fp32_size = 10 * 5 * 4  # 200 byte
int8_size = 10 * 5 * 1 + 4  # 54 byte (ağırlıklar + scale)
print(f"Bellek tasarrufu: {(1 - int8_size/fp32_size)*100:.1f}%")  # ~73%

🏗️ Model Zoo — Hazır Mimariler

ResNet-18

model = nv.models.resnet18(num_classes=10)
x = nv.Tensor(np.random.randn(1, 3, 224, 224).astype(np.float32))
logits = model(x)  # (1, 10)

Mimari: Conv2d(7×7) → BN → ReLU → MaxPool → 4×[ResidualBlock(3×3)] → AvgPool → Linear

ResidualBlock skip-connection ile gradient vanishing sorununu çözer:

input ──→ Conv → BN → ReLU → Conv → BN ──→ (+) → ReLU → output
  │                                          ↑
  └──────────── identity shortcut ───────────┘

MobileNetV2

model = nv.models.mobilenet_v2(num_classes=10)
x = nv.Tensor(np.random.randn(1, 3, 224, 224).astype(np.float32))
logits = model(x)  # (1, 10)

Mimari: Inverted Residual Block yapısı — depthwise separable convolution ile parametre verimliliği:

input → 1×1 Conv(expand) → BN → ReLU → 3×3 DWConv → BN → ReLU → 1×1 Conv(project) → BN → (+) → output

Vision Transformer (ViT)

# ViT-Tiny (5.7M parametre)
model_tiny = nv.models.vit_tiny(num_classes=1000)

# ViT-Base (86M parametre)
model_base = nv.models.vit_base(num_classes=1000)

# Özel yapılandırma
from newton_vision.models.vit import VisionTransformer
custom_vit = VisionTransformer(
    img_size=224,
    patch_size=16,
    in_channels=3,
    num_classes=100,
    embed_dim=384,
    depth=6,
    num_heads=6,
    mlp_ratio=4.0
)

ViT Çalışma Prensibi (adım adım):

1. PatchEmbedding: 224×224 görüntüyü 16×16 patch'lere böl → 196 patch
2. Her patch'i Conv2d(16×16, stride=16) ile embed_dim boyutuna projekte et
3. [CLS] token'ı dizinin başına ekle → 197 token
4. Positional Embedding ekle (öğrenilebilir)
5. 12× TransformerBlock:
   ├── LayerNorm → MultiHeadAttention → Residual Connection
   └── LayerNorm → MLP(Linear→GELU→Linear) → Residual Connection
6. Son LayerNorm
7. [CLS] token çıktısını al → Linear Head → sınıf logits

ViT Yapılandırma Karşılaştırması:

Yapılandırma Embed Dim Depth Heads MLP Ratio Parametre
ViT-Tiny 192 12 3 4.0 ~5.7M
ViT-Base 768 12 12 4.0 ~86M

🧱 Katman Referansı — Tüm Layer API

Conv2d — 2D Evrişim Katmanı

conv = nv.Conv2d(
    in_channels=3,       # Giriş kanal sayısı
    out_channels=64,     # Çıkış kanal sayısı (filtre sayısı)
    kernel_size=3,       # Filtre boyutu (3×3)
    stride=1,            # Kayma adımı
    padding=1,           # Kenar dolgusu
    dilation=1,          # Dilated convolution genişlemesi
    groups=1,            # Grouped convolution (depthwise için groups=in_channels)
    bias=True,           # Bias vektörü kullanılsın mı
    device="cpu"         # "cpu" veya "cuda"
)

# İleri geçiş
x = nv.Tensor(np.random.randn(1, 3, 32, 32).astype(np.float32), requires_grad=True)
y = conv(x)  # (1, 64, 32, 32) — padding=1 ile boyut korunur

# Autograd destekli — backward() otomatik çalışır
y.sum().backward()
print(x.grad.shape)  # (1, 3, 32, 32)

C++ Backend'de im2col + GEMM ile çalışır. 2D görüntüyü sütun matrisine dönüştürerek BLAS-tarzı matris çarpımı yapar. Bu yöntem iç içe döngülü naif evrişime göre ~10x hızlanma sağlar.

Linear — Tam Bağlantılı Katman

fc = nv.Linear(in_features=512, out_features=10, bias=True, device="cpu")
x = nv.Tensor(np.random.randn(4, 512).astype(np.float32), requires_grad=True)
y = fc(x)  # (4, 10)

Matematik: y = x @ W + b (Kaiming He başlatma ile)

Aktivasyon Fonksiyonları

relu = nv.ReLU()          # max(0, x)
leaky = nv.LeakyReLU(0.01)  # x if x > 0 else 0.01*x
sigmoid = nv.Sigmoid()     # 1 / (1 + exp(-x))
tanh = nv.Tanh()           # (exp(x) - exp(-x)) / (exp(x) + exp(-x))
gelu = nv.GELU()           # x * Φ(x) — Transformer'ların standart aktivasyonu

Tüm aktivasyonlar C++ backend ile hızlandırılmıştır. GELU ve ReLU autograd backward desteğine sahiptir.

BatchNorm2d — Batch Normalizasyonu

bn = nv.BatchNorm2d(num_features=64, eps=1e-5, device="cpu")
x = nv.Tensor(np.random.randn(8, 64, 16, 16).astype(np.float32))
y = bn(x)  # (8, 64, 16, 16) — normalize + scale + shift

Running mean ve running variance takibi ile eğitim sırasında istatistik toplama.

LayerNorm — Katman Normalizasyonu

ln = nv.LayerNorm(normalized_shape=192, eps=1e-5, device="cpu")
x = nv.Tensor(np.random.randn(4, 197, 192).astype(np.float32))
y = ln(x)  # (4, 197, 192) — son boyut üzerinden normalize

Transformer mimarilerinde her bloktan önce kullanılır.

MultiHeadAttention — Çok Başlı Öz-Dikkat

mha = nv.MultiHeadAttention(embed_dim=192, num_heads=3, bias=True, device="cpu")
x = nv.Tensor(np.random.randn(2, 197, 192).astype(np.float32))
y = mha(x)  # (2, 197, 192)

İç Çalışma Mekanizması:

  1. Girişi Q, K, V projeksiyonlarına ayırır (3 ayrı Linear katman)
  2. Her başlık (head) için head_dim = embed_dim / num_heads boyutunda bağımsız attention hesaplar
  3. Attention(Q,K,V) = softmax(Q·Kᵀ / √d_k) · V
  4. Tüm başlıkları birleştirip çıkış projeksiyonu uygular

MaxPool2d & AvgPool2d — Havuzlama Katmanları

maxpool = nv.MaxPool2d(kernel_size=2, stride=2)
avgpool = nv.AvgPool2d(kernel_size=7, stride=1)

x = nv.Tensor(np.random.randn(1, 64, 32, 32).astype(np.float32), requires_grad=True)
y_max = maxpool(x)  # (1, 64, 16, 16) — boyutu yarıya indirir
y_avg = avgpool(x)  # (1, 64, 26, 26)

MaxPool2d autograd backward desteğine sahiptir.


🔬 Tensor & Autograd Motoru (Fluxion)

Tensor Oluşturma

import newton_vision as nv
import numpy as np

# NumPy dizisinden
x = nv.Tensor(np.array([1.0, 2.0, 3.0]), requires_grad=True)

# Çok boyutlu
x = nv.Tensor(np.random.randn(2, 3, 224, 224).astype(np.float32), requires_grad=True)

# Cihaz belirtme
x = nv.Tensor(np.zeros((4, 10)), device="cuda")

Temel Özellikler

x = nv.Tensor(np.random.randn(2, 3, 4).astype(np.float32), requires_grad=True)

print(x.shape)     # (2, 3, 4)
print(x.ndim)      # 3
print(x.strides)   # (48, 16, 4) — byte cinsinden
print(x.device)    # "cpu"
print(x.data)      # NumPy ndarray'e doğrudan erişim
print(x.grad)      # Gradyan (backward sonrası dolar)

Desteklenen Operasyonlar (Autograd Destekli)

a = nv.Tensor(np.array([2.0, 3.0]), requires_grad=True)
b = nv.Tensor(np.array([4.0, 5.0]), requires_grad=True)

c = a + b        # Toplama (backward destekli)
d = a * b        # Çarpma (backward destekli)
e = a - b        # Çıkarma (backward destekli)
f = a.sum()      # Toplam skaler (backward destekli)
g = a.mean()     # Ortalama skaler (backward destekli)
h = a[0]         # İndeksleme / dilimleme (backward destekli)

Backward — Otomatik Türev Hesaplama

x = nv.Tensor(np.array([2.0, 3.0]), requires_grad=True)
w = nv.Tensor(np.array([0.5, -1.0]), requires_grad=True)

# Forward
y = (x * w).sum()

# Backward — tüm requires_grad=True tensörlerin gradyanlarını hesaplar
y.backward()

print(x.grad)  # [0.5, -1.0] — ∂y/∂x = w
print(w.grad)  # [2.0,  3.0] — ∂y/∂w = x

Autograd Mekanizması:

  1. Her operasyon bir çocuk düğümü (_children) ve bir _backward fonksiyonu kaydeder
  2. backward() çağrıldığında topolojik sıralama (topological sort) ile tüm graf tersine gezilir
  3. Zincir kuralı (chain rule) ile her düğümün gradyanı hesaplanır

Cihaz Transferi

x = nv.Tensor(np.zeros((2, 3)), device="cpu")

# CPU → CUDA
x_gpu = x.cuda()       # veya x.to("cuda")

# CUDA → CPU
x_cpu = x_gpu.cpu()     # veya x_gpu.to("cpu")

📉 Kayıp Fonksiyonları & Optimizatörler (Gravity)

CrossEntropyLoss — Çapraz Entropi Kaybı

loss_fn = nv.gravity.CrossEntropyLoss()

logits = nv.Tensor(np.random.randn(4, 10).astype(np.float32), requires_grad=True)
labels = np.array([3, 7, 1, 0])  # Hedef sınıf indeksleri

loss = loss_fn(logits, labels)
loss.backward()  # Gradyanlar otomatik hesaplanır

Dahili olarak numerik kararlı softmax uygular: exp(x - max(x))

MSELoss — Ortalama Kare Hata

loss_fn = nv.gravity.MSELoss()

pred = nv.Tensor(np.array([1.0, 2.0, 3.0]), requires_grad=True)
target = nv.Tensor(np.array([1.5, 2.5, 3.5]))

loss = loss_fn(pred, target)
loss.backward()

Adam Optimizatörü

optimizer = nv.gravity.Adam(
    params=model.parameters(),  # Eğitilebilir parametre listesi
    lr=0.001,                   # Öğrenme oranı
    beta1=0.9,                  # 1. moment üstel azalma faktörü
    beta2=0.999,                # 2. moment üstel azalma faktörü
    eps=1e-8                    # Sayısal kararlılık epsilon değeri
)

# Eğitim adımı
optimizer.zero_grad()   # Gradyanları sıfırla
loss.backward()         # Gradyanları hesapla
optimizer.step()        # Parametreleri güncelle

Adam, bias-corrected first & second moment estimation uygular:

m̂ = m / (1 - β₁ᵗ)
v̂ = v / (1 - β₂ᵗ)
θ = θ - lr · m̂ / (√v̂ + ε)

SGD Optimizatörü (Momentum Destekli)

optimizer = nv.gravity.SGD(
    params=model.parameters(),
    lr=0.01,
    momentum=0.9   # 0 = klasik SGD, > 0 = momentum destekli
)

🧊 INT8 Kuantizasyon Motoru

Neden Kuantizasyon?

FP32 ağırlıkları INT8'e dönüştürerek:

  • 4x bellek tasarrufu (4 byte → 1 byte per parametre)
  • Daha hızlı çıkarım (INT8 aritmetiği daha ucuzdur)
  • Minimal doğruluk kaybı (Per-Channel kuantizasyon ile)

Tensör Düzeyinde Kuantizasyon

import newton_vision as nv
import numpy as np

data = np.random.randn(4, 4).astype(np.float32)

# ── Global Kuantizasyon ───────────────────────────────────────────
q_int8, scale = nv.quantize_tensor(data)
print(f"INT8 veri tipi: {q_int8.dtype}")   # int8
print(f"Scale faktörü: {scale:.6f}")

# ── Geri Dönüştürme (Dequantize) ─────────────────────────────────
recovered = nv.dequantize_tensor(q_int8, scale)
error = np.mean(np.abs(data - recovered))
print(f"Ortalama kuantizasyon hatası: {error:.6f}")  # Tipik: < 0.02

# ── Per-Channel Kuantizasyon ──────────────────────────────────────
q_pc, scales = nv.quantize_tensor_per_channel(data, axis=0)
print(f"Kanal bazlı scale vektörü: {scales}")

Per-Channel vs Global Kuantizasyon:

  • Global: Tüm tensör için tek bir scale değeri. Aşırı uç değerler (outliers) tüm kanalların hassasiyetini bozar.
  • Per-Channel: Her filtre/kanal için bağımsız scale_i değeri. Outlier'lar sadece kendi kanallarını etkiler. Her zaman Per-Channel tercih edin.

Model Düzeyinde Kuantizasyon

model = nv.models.resnet18(num_classes=10)

# Tüm Linear ve Conv2d katmanlarını INT8'e dönüştür
stats = nv.quantize_model(model, per_channel=True)

print(f"Kuantize parametre sayısı: {stats['total_quantized_params']:,}")
print(f"FP32 bellek:  {stats['fp32_memory_kb']:.1f} KB")
print(f"INT8 bellek:  {stats['int8_memory_kb']:.1f} KB")
print(f"Tasarruf:     {stats['memory_reduction_percent']:.1f}%")  # ~75%

QuantizedLinear — INT8 Lineer Katman

q_linear = nv.QuantizedLinear(in_features=512, out_features=10, bias=True)

# FP32 ağırlıkları yükle (otomatik INT8'e dönüşür)
w_fp32 = np.random.randn(512, 10).astype(np.float32) * 0.01
q_linear.load_fp32_weights(w_fp32)

# INT8 çıkarım
x = np.random.randn(4, 512).astype(np.float32)
output = q_linear(x)  # INT8 matris çarpımı → FP32 çıktı

Dahili INT8 matris çarpımı:

Y_fp32 = (X_int8 @ W_int8).to_int32() × (scale_x × scale_w)

💾 JIT & Serileştirme Motoru

Model Kaydetme & Yükleme

model = nv.models.vit_tiny(num_classes=10)

# ── Format 1: .nv (Sıkıştırılmış NumPy) ──────────────────────────
nv.save_model(model, "my_model.nv")
nv.load_model(model, "my_model.nv")

# ── Format 2: .nv.bin (Saf C++ İkili) ────────────────────────────
# C++ uygulamalarında Python bağımlılığı olmadan yüklenebilir
nv.save_model_bin(model, "my_model.nv.bin")
nv.load_model_bin(model, "my_model.nv.bin")

.nv.bin Formatı: NVBIN100 magic header + tensör adı + 4D boyut + FP32 veri. C++ tarafında fread() ile doğrudan okunabilir.

ONNX Export

dummy_input = np.random.randn(1, 3, 224, 224).astype(np.float32)
nv.export_onnx(model, dummy_input, "my_model.onnx")

Not: Mevcut ONNX export, graf tanımlayıcı üretir (giriş/çıkış boyutu, parametre sayısı). Tam ONNX operatör grafi desteği gelecek sürümlerde planlanmaktadır.

InferenceEngine — Canlı Çıkarım Motoru

model = nv.models.vit_tiny(num_classes=1000)
engine = nv.InferenceEngine(model)

# Tek kare çıkarımı
frame = np.random.randn(1, 3, 224, 224).astype(np.float32)
output, latency_ms, fps = engine.predict(frame)
print(f"Gecikme: {latency_ms:.2f} ms | FPS: {fps:.1f}")

# 100 kare akışı simülasyonu
for i in range(100):
    frame = np.random.randn(1, 3, 224, 224).astype(np.float32)
    output, lat, fps = engine.predict(frame)

# Ortalama istatistikler
avg_lat, avg_fps = engine.get_average_stats()
print(f"Ortalama Gecikme: {avg_lat:.2f} ms | Ortalama FPS: {avg_fps:.1f}")

🤝 PyTorch Ağırlık Aktarımı

Mekanizma

newton-vision, PyTorch'un state_dict() sözlük yapısını birebir destekler:

import torch
import newton_vision as nv

# ── PyTorch'ta Eğit ───────────────────────────────────────────────
torch_model = torch.nn.Sequential(
    torch.nn.Linear(784, 256),
    torch.nn.ReLU(),
    torch.nn.Linear(256, 10)
)
# ... eğitim kodu ...

# ── State Dict'i Çıkar ───────────────────────────────────────────
state_dict = {k: v.detach().cpu().numpy() for k, v in torch_model.state_dict().items()}

# ── newton-vision Modeline Yükle ──────────────────────────────────
nv_model = ...  # Aynı mimaride newton-vision modeli
nv.load_state_dict(nv_model, state_dict)

Parametre Eşleme:

PyTorch Adı newton-vision Adı
weight w (Tensor)
bias bias (Tensor)
weight (BatchNorm) gamma (Tensor)
bias (BatchNorm) beta (Tensor)
running_mean running_mean (ndarray)
running_var running_var (ndarray)

Dikkat: PyTorch Linear ağırlıkları (out_features, in_features) şeklindedir. newton-vision (in_features, out_features) kullanır. Aktarım sırasında transpoz gerekebilir.


🖥️ Cihaz Yönetimi — CPU & CUDA

import newton_vision as nv

# ── CUDA Kullanılabilirliği ───────────────────────────────────────
if nv.principia.is_cuda_available():
    print("CUDA GPU mevcut!")
    nv.principia.set_device("cuda")
else:
    print("CPU modu aktif")

# ── Mevcut Cihaz ─────────────────────────────────────────────────
print(nv.principia.get_device())  # "cpu" veya "cuda"

# ── Tensör Cihaz Transferi ────────────────────────────────────────
x = nv.Tensor(np.zeros((2, 3)), device="cpu")
x_gpu = x.cuda()
x_cpu = x_gpu.cpu()

AVX2 SIMD Tespiti: C++ backend çalışma zamanında CPUID komutu ile CPU'nun AVX2 desteğini kontrol eder. AVX2 varsa SIMD hızlandırılmış GEMM kullanılır; yoksa fallback yoluna geçilir. Bu sayede ARM (Apple Silicon) veya eski x86 işlemcilerde SIGILL çökmesi yaşanmaz.


⚙️ C++ Backend Mimarisi

newton-vision'ın tüm ağır hesaplama işlemleri C++17 ile yazılmıştır:

Dosya Yapısı

cpp/
├── layers.h           → Tüm fonksiyon imzaları (API)
├── layers.cpp         → CPU implementasyonları (im2col, GEMM, aktivasyonlar, backward)
├── simd_gemm.h        → AVX2 SIMD ile hızlandırılmış matris çarpımı
├── cuda_layers.h      → CUDA kernel imzaları
├── cuda_layers.cu     → CUDA GPU kernel implementasyonları
└── binding.cpp        → pybind11 Python bağlama katmanı

C++ ile İmplemente Edilen Fonksiyonlar

Fonksiyon Açıklama
im2col_cpu() 2D görüntüyü sütun matrisine dönüştürür (stride, dilation, padding destekli)
gemm_cpu() Paralel matris çarpımı C = A × B + bias
conv2d() Forward: im2col + GEMM tabanlı 2D evrişim
conv2d_backward() Backward: ∂L/∂x, ∂L/∂w, ∂L/∂b gradyan hesaplama
relu() Forward: max(0, x)
relu_backward() Backward: x > 0 ? 1 : 0
leaky_relu() Forward: x > 0 ? x : αx
sigmoid_fn() Forward: 1/(1+e⁻ˣ)
tanh_fn() Forward: tanh(x)
gelu_fn() Forward: x·Φ(x) Gaussian Error Linear Unit
maxpool2d() Forward: bölgede maksimum değer
maxpool2d_backward() Backward: maksimum konumuna gradyan yönlendirme
avgpool2d() Forward: bölgede ortalama değer
batchnorm2d() Forward: kanal bazlı normalizasyon
layernorm() Forward: özellik boyutunda normalizasyon
has_cuda() CUDA GPU mevcut mu?
has_avx2_hardware() CPU AVX2 SIMD destekliyor mu?

im2col + GEMM Evrişim Stratejisi

Naif 6-katlı iç içe döngü yerine:

Giriş (N,C,H,W) → im2col → Sütun Matrisi (C×kH×kW, H_out×W_out)
                              × Filtre Matrisi (C_out, C×kH×kW)
                              = Çıkış Matrisi (C_out, H_out×W_out)
                              → reshape → (N, C_out, H_out, W_out)

Bu yaklaşım L1/L2 önbellek yerelliği (cache locality) sağlayarak ~10x hızlanma verir.


📊 Benchmark Sonuçları

Intel64 Family 6 (12 Threads) üzerinde PyTorch v2.6.0 CPU ile dürüst ve istatistiksel karşılaştırma (Warmup=5, Runs=20):

Model Framework Mean (ms) Std (ms) Min (ms) Max (ms) FPS Karşılaştırma
ViT-Tiny newton-vision 210.62 ±18.33 174.47 240.62 4.7 2.28x Hızlı 🚀
PyTorch CPU 472.23 ±29.48 458.22 585.02 2.1 Referans
ResNet-18 newton-vision 119.95 ±12.37 98.28 146.52 8.3 4.63x Yavaş
PyTorch CPU 25.90 ±0.77 24.97 27.74 38.6 Referans
MobileNetV2 newton-vision 4842.70 ±819.54 3619.07 7078.85 0.2 81.01x Yavaş
PyTorch CPU 59.78 ±2.94 54.99 66.91 16.7 Referans

Yorum: Transformer mimarisinde (ViT-Tiny) PyTorch'u geçiyoruz çünkü saf matris operasyonlarında im2col+GEMM avantajlıdır. CNN mimarilerinde (ResNet, MobileNet) ise PyTorch'un yıllardır optimize edilmiş MKL/oneDNN backend'i nedeniyle arkadayız. Bu, beklenen ve dürüst bir sonuçtur. newton-vision birincil olarak eğitim/araştırma aracıdır, production CNN inference için PyTorch/TensorRT önerilir.


🤖 Transformer & LLM Yetkinliği

Mevcut Durum (v1.1.x)

newton-vision aşağıdaki Transformer bileşenlerini tamamen sıfırdan implemente etmiştir:

Bileşen Durum Açıklama
MultiHeadAttention ✅ Tam Q/K/V projeksiyonları, Scaled Dot-Product Attention, çıkış projeksiyonu
LayerNorm ✅ Tam Öğrenilebilir γ ve β parametreleri
GELU ✅ Tam Backward destekli
TransformerBlock ✅ Tam Pre-LN yapısı, MLP bloğu, Residual Connection
PatchEmbedding ✅ Tam Conv2d tabanlı patch tokenizasyonu
VisionTransformer ✅ Tam CLS token, Positional Embedding, Classification Head
CrossEntropyLoss ✅ Tam Autograd backward destekli
Adam ✅ Tam Bias-corrected moment estimation

LLM Eğitebilir mi?

Kısa cevap: Yapı taşları mevcut, ancak henüz production-ready bir LLM eğitim pipeline'ı yok.

Mevcut olan:

  • Transformer encoder blokları (attention + MLP + residual)
  • Autograd motoru (backward pass)
  • Adam optimizatörü
  • CrossEntropyLoss

Henüz olmayan:

  • Causal/Masked Self-Attention (decoder-only mimariler için)
  • Token Embedding ve Text Tokenizer
  • Positional Encoding (sinüzoidal veya RoPE)
  • Dağıtık eğitim (multi-GPU, data parallelism)
  • Gradient checkpointing / mixed precision (FP16/BF16)
  • Flash Attention veya benzeri memory-efficient attention
  • Büyük veri seti yükleme pipeline'ı

Sonuç: newton-vision şu an Vision Transformer (ViT) ile görsel sınıflandırma eğitimi ve çıkarımı yapabilir. Metin tabanlı LLM (GPT, LLaMA tarzı) eğitimi için yukarıdaki bileşenlerin eklenmesi gerekmektedir. Transformer altyapısı mevcuttur ve bu bileşenler üzerine inşa edilebilir — bu, yol haritamızın bir parçasıdır.


📚 Örnek Projeler & Öğreticiler

Aşağıdaki dosyalar proje deposunda examples/ ve tutorials/ dizinlerinde bulunmaktadır.

Örnek 1: MNIST LeNet Sınıflandırma (examples/01_image_classification_lenet.py)

LeNet-5 mimarisinde MNIST el yazısı rakam sınıflandırması:

import newton_vision as nv
import numpy as np

# LeNet-5 Mimarisi
conv1 = nv.Conv2d(1, 6, kernel_size=5, padding=2)
conv2 = nv.Conv2d(6, 16, kernel_size=5)
pool = nv.MaxPool2d(2, 2)
relu = nv.ReLU()
fc1 = nv.Linear(16 * 5 * 5, 120)
fc2 = nv.Linear(120, 84)
fc3 = nv.Linear(84, 10)

# Forward Pass
def forward(x):
    x = pool(relu(conv1(x)))
    x = pool(relu(conv2(x)))
    N = x.data.shape[0]
    flat = nv.Tensor(x.data.reshape(N, -1), requires_grad=True)
    return fc3(relu(fc2(relu(fc1(flat)))))

Örnek 2: PyTorch ResNet-18 Ağırlık Aktarımı (examples/02_resnet18_pytorch_weights.py)

import torch
import torchvision.models as tmodels
import newton_vision as nv

# PyTorch pretrained ResNet-18
torch_resnet = tmodels.resnet18(weights=tmodels.ResNet18_Weights.DEFAULT)
state_dict = {k: v.cpu().numpy() for k, v in torch_resnet.state_dict().items()}

# newton-vision ResNet-18'e aktar
nv_resnet = nv.models.resnet18(num_classes=1000)
nv.load_state_dict(nv_resnet, state_dict)

Örnek 3: ViT Transformer Çıkarımı (examples/03_vit_transformer_inference.py)

import newton_vision as nv
import numpy as np

model = nv.models.vit_tiny(num_classes=1000)
engine = nv.InferenceEngine(model)

for i in range(10):
    frame = np.random.randn(1, 3, 224, 224).astype(np.float32)
    output, latency, fps = engine.predict(frame)
    print(f"Frame {i+1:02d} | {latency:.1f} ms | {fps:.1f} FPS")

Örnek 4: INT8 Kuantizasyon Demosu (examples/04_int8_quantization_demo.py)

import newton_vision as nv
import numpy as np

model = nv.models.resnet18(num_classes=10)

# Kuantizasyon öncesi çıkarım
x = nv.Tensor(np.random.randn(1, 3, 224, 224).astype(np.float32))
fp32_out = model(x)

# INT8 kuantizasyon uygula
stats = nv.quantize_model(model, per_channel=True)
int8_out = model(x)

# Karşılaştırma
diff = np.mean(np.abs(fp32_out.data - int8_out.data))
print(f"FP32 vs INT8 farkı: {diff:.6f}")
print(f"Bellek tasarrufu: {stats['memory_reduction_percent']:.1f}%")

Örnek 5: ONNX Export (examples/05_onnx_export_guide.py)

import newton_vision as nv
import numpy as np

model = nv.models.vit_tiny(num_classes=10)
dummy = np.random.randn(1, 3, 224, 224).astype(np.float32)
nv.export_onnx(model, dummy, "vit_tiny.onnx")

Öğretici 1: Tekrarlanabilir MNIST Eğitimi (tutorials/01_train_mnist.py)

Seed=42 ile her zaman aynı sonucu veren tam eğitim pipeline'ı:

import newton_vision as nv
import numpy as np

np.random.seed(42)

# Sentetik MNIST benzeri veri (gerçek MNIST için sklearn veya manual yükleme gerekir)
N_TRAIN, N_TEST = 600, 100
X_train = np.random.randn(N_TRAIN, 1, 28, 28).astype(np.float32)
y_train = np.random.randint(0, 10, N_TRAIN)
X_test = np.random.randn(N_TEST, 1, 28, 28).astype(np.float32)
y_test = np.random.randint(0, 10, N_TEST)

# Basit CNN
conv1 = nv.Conv2d(1, 8, 3, padding=1)
pool = nv.MaxPool2d(2, 2)
relu = nv.ReLU()
fc1 = nv.Linear(8 * 14 * 14, 64)
fc2 = nv.Linear(64, 10)

params = conv1.parameters() + fc1.parameters() + fc2.parameters()
optimizer = nv.gravity.Adam(params, lr=0.001)
loss_fn = nv.gravity.CrossEntropyLoss()

# Eğitim
for epoch in range(1, 11):
    x = nv.Tensor(X_train, requires_grad=True)
    h = pool(relu(conv1(x)))
    N = h.data.shape[0]
    h_flat = nv.Tensor(h.data.reshape(N, -1), requires_grad=True)
    logits = fc2(relu(fc1(h_flat)))

    loss = loss_fn(logits, y_train)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    acc = np.mean(np.argmax(logits.data, axis=1) == y_train) * 100
    print(f"Epoch {epoch:02d} | Loss: {float(loss.data):.4f} | Train Acc: {acc:.1f}%")

Öğretici 2: 3 Aşamalı Canlı Demo (tutorials/live_3stage_demo.py)

3 aşamalı karşılaştırma: Saf Eğitim → PyTorch Aktarımı → INT8 Kuantizasyon.

import newton_vision as nv
import numpy as np

print("=" * 60)
print("AŞAMA 1: Saf newton-vision Eğitimi")
print("=" * 60)

fc1 = nv.Linear(16, 32)
fc2 = nv.Linear(32, 3)
relu = nv.ReLU()
optimizer = nv.gravity.Adam(fc1.parameters() + fc2.parameters(), lr=0.01)
loss_fn = nv.gravity.CrossEntropyLoss()

X = np.random.randn(50, 16).astype(np.float32)
y = np.random.randint(0, 3, 50)

for ep in range(20):
    logits = fc2(relu(fc1(nv.Tensor(X, requires_grad=True))))
    loss = loss_fn(logits, y)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
print(f"Son Loss: {float(loss.data):.4f}")

print("\n" + "=" * 60)
print("AŞAMA 2: Model Kaydetme & Yükleme")
print("=" * 60)

# Model parametrelerini .nv formatında kaydet ve geri yükle
# (tam model serileştirme için wrapper gerekir)

print("\n" + "=" * 60)
print("AŞAMA 3: INT8 Kuantizasyon")
print("=" * 60)

q_fc1 = nv.QuantizedLinear(16, 32)
q_fc1.load_fp32_weights(fc1.w.data, fc1.bias.data if fc1.bias is not None else None)
q_out = q_fc1(X)
print(f"INT8 çıktı boyutu: {q_out.data.shape}")

C++ Saf Çıkarım (examples/cpp_inference_demo.cpp)

Python bağımlılığı olmadan C++ ile çıkarım:

#include "layers.h"
#include <vector>
#include <cstdio>
#include <fstream>

int main() {
    // .nv.bin dosyasından ağırlıkları oku
    FILE* f = fopen("model.nv.bin", "rb");
    // ... ağırlık yükleme kodu ...

    // Conv2d forward pass
    int H_out, W_out;
    auto output = nv::conv2d(input_data, input_shape,
                              weight_data, 64, 3, 3,
                              bias_data, 1, 1, 1, 1,
                              H_out, W_out);

    // ReLU
    auto activated = nv::relu(output.data(), output.size());

    printf("Output shape: (%d, %d)\n", H_out, W_out);
    return 0;
}

✅ Test Kapsamı

Proje aşağıdaki test dosyalarını içerir (tümü tests/ dizininde):

Test Dosyası Kapsam
test_autograd.py Tensor operasyonları, backward pass, gradient doğruluğu
test_correctness.py Conv2d, Linear, ReLU çıktı doğruluğu (PyTorch ile karşılaştırma)
test_models.py ResNet-18, MobileNetV2 forward pass boyut doğruluğu
test_vit.py VisionTransformer, PatchEmbedding, TransformerBlock doğruluğu
test_quantization.py INT8 kuantizasyon, dequantizasyon, QuantizedLinear doğruluğu
test_jit.py Model kaydetme/yükleme, .nv ve .nv.bin formatları
test_cpp_core.cpp C++ backend birim testleri

Testleri çalıştırma:

python -m pytest tests/ -v

🤝 Katkıda Bulunma

  1. Depoyu fork'layın
  2. Feature branch oluşturun: git checkout -b feature/yeni-ozellik
  3. Değişikliklerinizi commit'leyin: git commit -m 'feat: yeni özellik ekle'
  4. Branch'inizi push'layın: git push origin feature/yeni-ozellik
  5. Pull Request açın

Commit Mesajı Formatı: Conventional Commits (feat:, fix:, docs:, refactor:, test:, perf:)

Kod Stili: PEP 8 (Python), Google C++ Style Guide (C++)


🔒 Güvenlik Politikası

Güvenlik açığı bulursanız:

  • Public issue açmayın
  • E-posta ile bildirin: info@newton-vision.org
  • 48 saat içinde yanıt alacaksınız

Desteklenen sürümler: v1.1.x (en güncel minor sürüm)


📋 Sürüm Geçmişi

v1.1.4 (Güncel)

  • README tamamen yeniden yazıldı (PyPI uyumlu, self-contained)
  • Tüm dahili link bağımlılıkları kaldırıldı
  • LLM yetkinlik durumu belgelendi

v1.1.0

  • Vision Transformer (ViT-Tiny, ViT-Base) eklendi
  • MultiHeadAttention, LayerNorm, GELU katmanları eklendi
  • PatchEmbedding ve TransformerBlock eklendi
  • Per-Channel INT8 Kuantizasyon eklendi
  • InferenceEngine (FPS/gecikme takibi) eklendi
  • ONNX Export desteği eklendi

v1.0.0

  • İlk kararlı sürüm
  • Conv2d (im2col + GEMM), Linear, ReLU, MaxPool2d, AvgPool2d, BatchNorm2d
  • Reverse-mode Autograd motoru
  • ResNet-18 ve MobileNetV2
  • PyTorch state_dict uyumluluğu
  • .nv ve .nv.bin serileştirme
  • CPU/CUDA cihaz yönetimi
  • AVX2 SIMD otomatik tespiti

📜 Lisans

Bu proje MIT Lisansı ile lisanslanmıştır. Telif hakkı (c) 2025 newton-vision Core Team.

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software...

newton-vision — Derin öğrenmenin fiziğini anla, motorunu kendin yaz. 🌌

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

newton_vision-1.1.5-cp313-cp313-win_amd64.whl (237.1 kB view details)

Uploaded CPython 3.13Windows x86-64

File details

Details for the file newton_vision-1.1.5-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for newton_vision-1.1.5-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 1d881d6425b04d596556d634f115a515844dae681e3c3a81a584ce88e61e9f31
MD5 7d8ac34f81198cd88eba69555718a2c0
BLAKE2b-256 0a4d807882a3a04b41bd08543cae41cfa49cd8f45bdd274e541cd0efed8cf59b

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