Giriş
Tarayıcıda yapay zeka çalıştırmak artık bir deney olmaktan çıktı; WebGPU ve ONNX Runtime Web gibi teknolojiler sayesinde ciddi performans elde etmek mümkün. Bu rehberde, WebGPU hızlandırmasıyla bir ONNX görüntü sınıflandırma modelini tamamen tarayıcı içinde, ek bir sunucu tarafı altyapı olmadan nasıl koşturabileceğinizi adım adım anlatıyorum. Hedefimiz düşük gecikme, daha iyi gizlilik (veri cihazı terk etmez) ve çevrimdışı çalışma imkânı.
Neden WebGPU?
WebGPU, WebGL’in ötesine geçen, modern GPU mimarilerinden doğrudan faydalanmayı kolaylaştıran bir tarayıcı API’sidir. Hesaplama (compute) kabiliyetleri, daha düşük sürücü ek yükü ve daha öngörülebilir performans sunar. ONNX Runtime Web de bu yeteneklerden yararlanarak modeli GPU üzerinde çalıştırabilir; GPU desteklenmiyorsa otomatik olarak WASM (CPU) yoluna düşer.
Önkoşullar ve Ortam
• Tarayıcı: Chrome/Edge 113+ sürümlerinde WebGPU varsayılan olarak açıktır. Safari’de kısmi, Firefox’ta Nightly ve bayrak ile destek var. En güncel Chrome önerilir.
• Temel JS/HTML bilgisi ve statik bir sunucu (ör. npx serve veya Vite).
• Model dosyası: ONNX Model Zoo’dan MobileNetV2-7 küçük ve hızlı bir başlangıçtır. Alternatif olarak SqueezeNet veya EfficientNet-Lite tercih edilebilir.
Proje İskeleti
Basit bir index.html dosyasıyla başlayın. Aşağıdaki minimal iskelet, bir dosya girişi, bir tuş ve sonucu göstermek için alan içerir:
<!doctype html>
<html lang="tr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WASM + WebGPU Sınıflandırma</title>
</head>
<body>
<input id="file" type="file" accept="image/*">
<button id="run">Çalıştır</button>
<canvas id="canvas" width="224" height="224"></canvas>
<div id="out"></div>
<script type="module" src="./app.js"></script>
</body>
</html>
ONNX Runtime Web’i Entegre Etme
CDN üzerinden ORT’yi kullanabilirsiniz. app.js dosyasında ORT’yi içe alın ve WebGPU’yu tercih eden bir oturum oluşturun. WASM fallback’i yedekte kalsın:
import * as ort from "https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js";
// WASM dosyalarının yolu (CDN veya yerel) - doğru ayarlayın
ort.env.wasm.wasmPaths = "https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/";
// Daha yüksek performans için çoklu iş parçacığı (COOP/COEP gerektirebilir)
// ort.env.wasm.numThreads = navigator.hardwareConcurrency || 4;
const preferGPU = !!navigator.gpu;
const session = await ort.InferenceSession.create("./models/mobilenetv2-7.onnx", {
executionProviders: preferGPU ? ["webgpu", "wasm"] : ["wasm"],
graphOptimizationLevel: "all"
});
Ön İşleme: Görseli Tensore Dönüştürme
MobileNet türü modeller genelde 224x224 giriş, RGB kanal sırası ve kanal başta (NCHW) düzeni bekler. Pixel değerlerini 0-1 aralığına getirip normalize etmek gerekir. Örnek bir dönüştürme:
async function imageToTensor(file) {
const img = new Image();
img.src = URL.createObjectURL(file);
await img.decode();
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, 224, 224);
const { data } = ctx.getImageData(0, 0, 224, 224);
const chw = new Float32Array(1 * 3 * 224 * 224);
const mean = [0.485, 0.456, 0.406];
const std = [0.229, 0.224, 0.225];
let p = 0;
for (let y = 0; y < 224; y++) {
for (let x = 0; x < 224; x++) {
const i = (y * 224 + x) * 4;
const r = data[i] / 255;
const g = data[i + 1] / 255;
const b = data[i + 2] / 255;
// NCHW: önce tüm R, sonra G, sonra B kanalı
chw[0 * 224 * 224 + p] = (r - mean[0]) / std[0];
chw[1 * 224 * 224 + p] = (g - mean[1]) / std[1];
chw[2 * 224 * 224 + p] = (b - mean[2]) / std[2];
p++;
}
}
return new ort.Tensor("float32", chw, [1, 3, 224, 224]);
}
Çalıştırma ve Sonuçları Yorumlama
Girdi tensörünü oluşturduktan sonra oturumu çalıştırın. Çoğu sınıflandırma modelinde çıktı tek bir tensördür; en büyük olasılığı seçip etikete dönüştürürsünüz. ImageNet etiketlerini küçük bir JSON dosyası olarak projeye ekleyebilirsiniz:
import labels from "./labels-imagenet.json" assert { type: "json" };
document.getElementById("run").addEventListener("click", async () => {
const file = document.getElementById("file").files[0];
if (!file) return;
const input = await imageToTensor(file);
const feeds = { input: input }; // Modelin gerçek girdi ismini kontrol edin
const out = await session.run(feeds);
const outputName = session.outputNames[0];
const data = out[outputName].data;
let idx = 0, max = -Infinity;
for (let i = 0; i < data.length; i++) { if (data[i] > max) { max = data[i]; idx = i; } }
document.getElementById("out").textContent = labels[idx] + " (" + max.toFixed(3) + ")";
});
Performans İpuçları
• İlk yüklemede bir “ısındırma” (warm-up) çağrısı yapın; modelin derlenmesi ve GPU kaynaklarının hazırlanması süre alabilir.
• WebGPU aktifleştirilmişse IOBinding ile giriş/çıkışları GPU üzerinde tutmak ek hız kazandırır (ileri kullanım).
• Modellerin quantized (INT8) sürümlerini tercih ederek dosya boyutunu ve gecikmeyi azaltın.
• Model dosyasını Brotli/Gzip ile sıkıştırıp uygun cache header’ları ayarlayın; tarayıcı önbelleğini ve Service Worker ile Cache Storage’ı kullanın.
• Görüntü ön işlemesini OffscreenCanvas veya Web Worker içinde yaparak ana iş parçacığını serbest bırakın.
Güvenlik ve Uyumluluk Notları
WASM tarafında çoklu iş parçacığı ve SharedArrayBuffer kullanmak istiyorsanız COOP/COEP başlıklarını etkinleştirmeniz gerekir. Bu mümkün değilse tek iş parçacığı da gayet iş görür; WebGPU varsa GPU hızlandırması zaten ciddi bir fark yaratır. Tarayıcı uyumluluğunda problem yaşıyorsanız, geçici olarak executionProviders: ["wasm"] ile çalışmaya devam edebilirsiniz.
Sonuç
Bu rehberle, yalnızca statik dosyalardan oluşan basit bir web projesinde ONNX Runtime Web ve WebGPU kullanarak gerçek zamanlıya yakın görüntü sınıflandırma kurdunuz. Avantajları açık: düşük gecikme, veri gizliliği ve dağıtım kolaylığı. Bir sonraki adım olarak kamera akışı (getUserMedia) ile canlı sınıflandırma, farklı model mimarileri (ResNet, EfficientNet, ViT), otomatik etiketleme veya yerleşik önbellekle çevrimdışı kullanım gibi özellikleri ekleyebilirsiniz. WebGPU ekosistemi hızla olgunlaşıyor; bugün attığınız adımlar, yarının tarayıcı tabanlı yapay zeka uygulamalarının temelini oluşturacak.
3.