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'ü.
İçindekiler
- Proje Nedir?
- Kurulum
- Modül Haritası
- Hızlı Başlangıç — 3 Senaryo
- Model Zoo — Hazır Mimariler
- Katman Referansı — Tüm Layer API
- Tensor & Autograd Motoru
- Kayıp Fonksiyonları & Optimizatörler
- INT8 Kuantizasyon Motoru
- JIT & Serileştirme Motoru
- PyTorch Ağırlık Aktarımı
- Cihaz Yönetimi — CPU & CUDA
- C++ Backend Mimarisi
- Benchmark Sonuçları
- Transformer & LLM Yetkinliği
- Örnek Projeler & Öğreticiler
- Test Kapsamı
- Katkıda Bulunma
- Güvenlik Politikası
- Sürüm Geçmişi
- 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:
- 80 örnekli 3 sınıflı sentetik veri oluşturur
Linear(16→32) → ReLU → Linear(32→3)mimarisinde bir MLP tanımlar- Adam optimizatörü ile CrossEntropy kaybını minimize eder
- 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ı:
- Girişi Q, K, V projeksiyonlarına ayırır (3 ayrı Linear katman)
- Her başlık (head) için
head_dim = embed_dim / num_headsboyutunda bağımsız attention hesaplar Attention(Q,K,V) = softmax(Q·Kᵀ / √d_k) · V- 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ı:
- Her operasyon bir çocuk düğümü (
_children) ve bir_backwardfonksiyonu kaydeder backward()çağrıldığında topolojik sıralama (topological sort) ile tüm graf tersine gezilir- 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
scaledeğeri. Aşırı uç değerler (outliers) tüm kanalların hassasiyetini bozar. - Per-Channel: Her filtre/kanal için bağımsız
scale_ideğ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
- Depoyu fork'layın
- Feature branch oluşturun:
git checkout -b feature/yeni-ozellik - Değişikliklerinizi commit'leyin:
git commit -m 'feat: yeni özellik ekle' - Branch'inizi push'layın:
git push origin feature/yeni-ozellik - 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
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 newton_vision-1.1.5-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: newton_vision-1.1.5-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 237.1 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d881d6425b04d596556d634f115a515844dae681e3c3a81a584ce88e61e9f31
|
|
| MD5 |
7d8ac34f81198cd88eba69555718a2c0
|
|
| BLAKE2b-256 |
0a4d807882a3a04b41bd08543cae41cfa49cd8f45bdd274e541cd0efed8cf59b
|