ONNX Runtime Web etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
ONNX Runtime Web etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

5 Aralık 2025 Cuma

WebGPU ile Tarayıcıda Makine Öğrenimi: ONNX Runtime Web ile Görsel Sınıflandırma (Adım Adım)

Giriş

WebGPU, modern tarayıcılarda GPU gücünden standart ve güvenli bir şekilde yararlanmayı sağlayan yeni bir web standardı. Bu yazıda, ONNX Runtime Web ve WebGPU kullanarak tarayıcı içinde tamamen istemci tarafında çalışan bir görsel sınıflandırma uygulamasını adım adım kuracağız. Sunucuya veri göndermeden, gizliliğe saygılı ve düşük gecikmeli bir makine öğrenimi deneyimi elde edeceğiz. Bu yaklaşım, SEO açısından da kıymetli; zira “tarayıcıda makine öğrenimi”, “WebGPU”, “ONNX Runtime Web”, “görsel sınıflandırma” gibi anahtar kelimelerle teknik kitlelere doğrudan hitap ediyor.

Ön Koşullar

- Güncel bir tarayıcı: Chrome 113+ sürümlerinde WebGPU masaüstünde varsayılan olarak açıktır. Safari’de ve Firefox’ta destek durumu değişebilir; deneysel bayraklar gerekebilir. Mobilde destek kısmi durumdadır.

- Node.js 18+ (geliştirme sunucusu ve paket yönetimi için)

- Temel HTML/JS bilgisi

Proje Kurulumu

1) Vite ile boş bir proje oluşturun:

npm create vite@latest webgpu-ml -- --template vanilla
cd webgpu-ml
npm install

2) ONNX Runtime Web paketini ekleyin:

npm i onnxruntime-web

3) Basit bir dosya yapısı hazırlayın: index.html, main.js ve bir models/ klasörü. Örnek olarak mobilenetv2.onnx gibi 224x224 giriş alan bir sınıflandırma modelini models/ altına yerleştirin. ONNX model arşivlerinden (örn. ResNet, MobileNet) hafif bir model tercih edin.

index.html İskeleti

Aşağıdaki minimal HTML, bir görsel yükleme alanı ve sonuçları göstermek için basit bir arayüz içerir.

<!doctype html>
<html lang="tr">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>WebGPU ile Görsel Sınıflandırma</title>
  </head>
  <body>
    <h1>WebGPU + ONNX Runtime Web</h1>
    <input type="file" id="file" accept="image/*" />
    <button id="predict">Sınıflandır</button>
    <div id="status">Hazır</div>
    <div id="result"></div>
    <canvas id="canvas" width="224" height="224" style="display:none"></canvas>
    <script type="module" src="/main.js"></script>
  </body>
</html>

WebGPU ve ONNX Runtime Web ile Çalıştırma

Aşağıdaki kodda, tarayıcıda WebGPU desteği kontrol edilir, ONNX modeli yüklenir, görsel 224x224 boyutuna ölçeklenir ve ImageNet ortalama/standart sapma değerleri ile normalize edilerek tensöre dönüştürülür. Ardından model çıkarımı yapılır ve en yüksek olasılıklı sınıf ekrana yazdırılır.

// main.js
import * as ort from 'onnxruntime-web/webgpu';

const statusEl = document.getElementById('status');
const resultEl = document.getElementById('result');
const fileInput = document.getElementById('file');
const predictBtn = document.getElementById('predict');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

let session;

// WebGPU desteğini kontrol edin
if (!('gpu' in navigator)) {
  statusEl.textContent = 'WebGPU desteklenmiyor. Varsayılan WASM ile deneyin.';
}

// Modeli başlat
async function initModel() {
  statusEl.textContent = 'Model yükleniyor...';
  // Fallback ile: önce WebGPU, olmazsa WASM
  session = await ort.InferenceSession.create('/models/mobilenetv2.onnx', {
    executionProviders: ['webgpu', 'wasm']
  });
  statusEl.textContent = 'Model yüklendi.';
}

function imageToTensor(img) {
  const size = 224;
  ctx.clearRect(0, 0, size, size);
  // Görseli 224x224'e çiz
  ctx.drawImage(img, 0, 0, size, size);
  const { data } = ctx.getImageData(0, 0, size, size);

  // NHWC(RGBA) -> NCHW, normalize [0,1], ImageNet mean/std
  const mean = [0.485, 0.456, 0.406];
  const std = [0.229, 0.224, 0.225];

  const input = new Float32Array(1 * 3 * size * size);
  let idx = 0;
  for (let y = 0; y < size; y++) {
    for (let x = 0; x < size; x++) {
      const i = (y * size + x) * 4;
      const r = data[i] / 255;
      const g = data[i + 1] / 255;
      const b = data[i + 2] / 255;
      // Kanal sırası: [R plane][G plane][B plane]
      input[0 * size * size + idx] = (r - mean[0]) / std[0];
      input[1 * size * size + idx] = (g - mean[1]) / std[1];
      input[2 * size * size + idx] = (b - mean[2]) / std[2];
      idx++;
    }
  }
  return new ort.Tensor('float32', input, [1, 3, size, size]);
}

function softmax(arr) {
  const max = Math.max(...arr);
  const exps = arr.map(v => Math.exp(v - max));
  const sum = exps.reduce((a, b) => a + b, 0);
  return exps.map(v => v / sum);
}

async function runInference(img) {
  if (!session) await initModel();

  statusEl.textContent = 'Çıkarım yapılıyor...';
  const tensor = imageToTensor(img);

  const inputName = session.inputNames[0];
  const output = await session.run({ [inputName]: tensor });

  const outputName = session.outputNames[0];
  const logits = Array.from(output[outputName].data);
  const probs = softmax(logits);

  // En yüksek olasılıklı sınıfı bul
  let bestIdx = 0;
  for (let i = 1; i < probs.length; i++) {
    if (probs[i] > probs[bestIdx]) bestIdx = i;
  }

  // Label dosyanız varsa fetch edip eşleyebilirsiniz (örn. imagenet-labels.txt)
  resultEl.textContent = `Tahmin sınıf index: ${bestIdx}, olasılık: ${(probs[bestIdx] * 100).toFixed(2)}%`;
  statusEl.textContent = 'Bitti';
}

// Görsel seç ve çıkarım başlat
predictBtn.addEventListener('click', async () => {
  const file = fileInput.files?.[0];
  if (!file) {
    alert('Lütfen bir görsel seçin.');
    return;
  }
  const img = new Image();
  img.onload = () => runInference(img);
  img.src = URL.createObjectURL(file);
});

// Sayfa yüklenince modeli hazırlayın (isteğe bağlı)
initModel().catch(err => {
  console.error(err);
  statusEl.textContent = 'Model yüklenirken hata oluştu.';
});

Performans İpuçları

- WebGPU genellikle WASM/WASM SIMD’e göre daha yüksek paralellik ve throughput sunar. Ancak küçük modellerde fark az olabilir. Model boyutu ve katman türleri sonucu etkiler.

- Modeli mümkün olduğunca küçük seçin (MobileNet, EfficientNet-Lite gibi). Büyük modeller hem ağdan indirmede hem de bellek kullanımında sorun çıkarabilir.

- İlk çıkarım (warm-up) genellikle daha yavaştır. Gerçek kullanıcı deneyimi için ikinci/üçüncü çıkarımı da ölçün.

- Vite yerine üretime alırken kodu küçültün ve model dosyasını CDN veya HTTP/2 ile hızlı sunun. Cache-Control başlıklarını doğru ayarlayın.

Sorun Giderme

- “WebGPU desteklenmiyor”: Tarayıcınızı güncelleyin veya chrome://flags içinde WebGPU ile ilgili bayrakları kontrol edin. Kurumsal politikalar GPU erişimini kısıtlayabilir.

- “Model giriş/çıkış adı uyuşmuyor” hatası: session.inputNames ve session.outputNames üzerinden gerçek isimleri alın, manuel isim yazmayın.

- Görselin renkleri veya sonuçlar beklenenden farklıysa, normalize adımlarını (mean/std) ve kanal sırasını (NCHW vs NHWC) model dokümantasyonuna göre doğrulayın.

- Bazı platformlarda WebGPU var ama belirli doku formatları kısıtlı olabilir. Fallback olarak WASM sağlayıcısını eklediğinizden emin olun.

Sonuç

WebGPU ve ONNX Runtime Web ile tarayıcıda makine öğrenimi artık gerçek bir seçenek. İstemci tarafında görsel sınıflandırma gibi görevlerde gizlilik, düşük gecikme ve çevrimdışı çalışma avantajları sunar. Bu rehberle temel bir iskelet kurdunuz; bundan sonra model çeşitliliğini artırabilir, etiket dosyaları ile daha anlaşılır sonuçlar gösterebilir, hatta Web Workers kullanarak arayüzü bloklamadan çoklu çıkarım senaryolarını deneyebilirsiniz. Kısacası, WebGPU sayesinde modern web uygulamaları, yapay zeka kabiliyetlerini kullanıcıya en yakın yerde, doğrudan tarayıcıda sunabiliyor.

4 Aralık 2025 Perşembe

WebGPU ile Tarayıcıda Yapay Zeka Çalıştırma: ONNX Runtime Web ve Transformers.js ile Adım Adım Rehber

Tarayıcıda yapay zeka modelleri çalıştırmak, son iki yılda WebGPU’nun olgunlaşmasıyla pratik hale geldi. WebGL ve saf WebAssembly çözümleri artık yerini daha modern, düşük seviye ve yüksek performanslı WebGPU’ya bırakıyor. Bu rehber, WebGPU destekli ONNX Runtime Web ve Transformers.js kullanarak istemci tarafında model çalıştırmayı adım adım anlatır; kurulum, performans ipuçları, geriye uyumluluk ve sorun giderme başlıklarını içerir.

WebGPU neden önemli?

WebGPU, GPU’ya daha doğrudan erişim sağlar, bellek kopyalamayı azaltır ve paralel işlemleri daha verimli yürütür. Görüntü sınıflandırma, metin gömme (embedding), duygu analizi, hatta küçük dil modelleri gibi görevlerde CPU’ya kıyasla ciddi hızlanma sağlayabilirsiniz. Üstelik tüm bunlar, veriyi sunucuya göndermeden, gizliliği koruyarak gerçekleşir.

Önkoşullar ve tarayıcı desteği

Güncel Chrome/Edge (121+), Safari 17+ (veya Technology Preview) ve Firefox Nightly, değişen derecelerde WebGPU desteği sunar. Chrome’da sorun yaşarsanız chrome://flags altında “Unsafe WebGPU” seçeneğini kontrol edin. Kurumsal cihazlarda kısıtlamalar olabilir. Destek yoksa ONNX Runtime Web’in WASM sağlayıcısına otomatik geçiş yapabilirsiniz.

Proje kurulumu (Vite + NPM)

Hızlı başlamak için Vite ile bir ön yüz projesi kurabilir ve hem düşük seviyeli API (onnxruntime-web) hem de yüksek seviyeli bir sarmalayıcı (Transformers.js) ekleyebilirsiniz. Aşağıdaki komutlar, örnek bir React projesi içindir; framework bağımlı değilsiniz, vanilla JS ile de kullanabilirsiniz.

# Proje oluşturma
npm create vite@latest webgpu-ai -- --template react
cd webgpu-ai

# Bağımlılıklar
npm i onnxruntime-web @xenova/transformers

# Geliştirme sunucusu
npm run dev

ONNX Runtime Web ile WebGPU’da model çalıştırma

ONNX Runtime Web (ORT Web), aynı API ile birden fazla yürütme sağlayıcısını (WebGPU, WebGL, WASM) destekler. Aşağıda WebGPU var ise onu, yoksa WASM’i kullanacak minimal bir örnek yer alıyor. Burada mobilenet gibi hafif bir görüntü sınıflandırma modeli varsayılmıştır.

import * as ort from 'onnxruntime-web';

async function loadSession() {
  const hasWebGPU = typeof navigator !== 'undefined' && !!navigator.gpu;

  const session = await ort.InferenceSession.create('/models/mobilenetv2.onnx', {
    executionProviders: hasWebGPU ? ['webgpu'] : ['wasm'],
    graphOptimizationLevel: 'all'
  });

  return session;
}

async function run(session, inputTensor) {
  const [inputName] = session.inputNames;
  const [outputName] = session.outputNames;
  const feeds = { [inputName]: inputTensor };

  const results = await session.run(feeds);
  const output = results[outputName]; // ort.Tensor
  return output;
}

// Basit ön işleme (örnek): 224x224, [1,3,224,224], normalize edilmiş Float32Array
// Gerçek uygulamada resmi canvas ile yeniden boyutlandırıp kanalları CHW formatına çevirin.

Modelin giriş/çıkış adları modellere göre değişir; yukarıdaki gibi session.inputNames ve session.outputNames kullanmak en güvenli yoldur. Performans için FP16’ye dönüştürülmüş modeller ve 224x224 gibi küçük giriş boyutları tercih edin. Ayrıca tek seferde birden fazla örnek (batch) işletecekseniz tarayıcı GPU belleği sınırlamalarını aklınızda tutun.

Transformers.js ile “yüksek seviyeli” kullanım

@xenova/transformers, tarayıcıda hazır NLP ve bazı görsel modelleri kolayca çalıştırmanızı sağlar. Arkada ONNX Runtime Web ve uygun olduğunda WebGPU kullanır. Aşağıdaki örnek duygu analizi içindir:

import { pipeline } from '@xenova/transformers';

async function runSentiment() {
  const hasWebGPU = typeof navigator !== 'undefined' && !!navigator.gpu;
  const device = hasWebGPU ? 'webgpu' : 'cpu'; // 'cpu' = WASM

  const pipe = await pipeline(
    'text-classification',
    'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
    { device }
  );

  const out = await pipe('Bu film şaşırtıcı derecede iyiydi!');
  console.log(out);
}

Transformers.js, ilk çalıştırmada modeli indirip tarayıcı önbelleğine alır. Üretim ortamında model dosyalarını kendi CDN’inizden sunmak ve sürümleri sabitlemek iyi bir pratiktir. Bazı modeller büyük olduğundan, başlangıç gecikmesini azaltmak için “tiny” veya “base” sürümleri tercih edin.

Performans ipuçları

1) Doğru veri türü: FP16 modeller WebGPU’da bellek ve bant genişliği avantajı sağlar. Mümkünse ağırlıkları FP16’ya dönüştürün. 2) Boyutlandırma: Görsel görevlerde 160–224 piksel aralığı mobil cihazlar için iyi bir dengedir. 3) Ön bellekleme: Uygulama açılışında session’ı yükleyip sıcak tutmak (warm-up) soğuk başlangıç gecikmesini azaltır. 4) I/O bağlama: ORT Web’de (sürümünüze bağlı) tensörleri GPU belleğinde tutmak için IOBindings seçeneklerini inceleyin. 5) Paralellik: WASM’a düşerseniz SIMD ve çok iş parçacığı hız kazandırır; bunun için COOP/COEP başlıklarıyla cross-origin isolation etkin olmalı.

Geriye uyumluluk ve düşüş (fallback) stratejisi

Her cihaz WebGPU desteklemeyebilir. Bu yüzden navigator.gpu kontrolüyle otomatik geçiş uygulayın: WebGPU → WASM. Kullanıcıya “hızlandırma kapalı” gibi basit bir durum göstergesi sunmak, deneyimi şeffaf kılar. Mobilde pil ve termal kısıtlar için bir “düşük güç modu” eklemek de değerlidir.

Güvenlik ve gizlilik

İstemci tarafı çıkarım (inference), verinin cihazdan çıkmamasını sağlar. Ancak model dosyaları herkese açık sunuluyorsa, telif ve lisans koşullarını gözden geçirin. Ayrıca büyük modeller cihaz belleğini hızla tüketebilir; kademeli yükleme (lazy load) ve dinamik boşaltma (dispose) uygulayın.

Sorun giderme

WebGPU görünmüyor: Kurumsal politikalar veya eski tarayıcı sürümü olabilir; flags ve sürüm kontrolü yapın. GPU belleği yetersiz: Giriş çözünürlüğünü ve batch boyutunu düşürün, FP16 kullanın. Yavaş ilk çalıştırma: Modeli önden ısıtın ve CDN’de sıkıştırma (gzip/br) + cache headers kullanın. WASM fallback çok yavaş: cross-origin isolation ile WASM SIMD/threads’i etkinleştirin ve daha hafif bir model seçin.

Sonuç

WebGPU, tarayıcıda yapay zekayı gerçek zamanlıya yaklaştırıyor. ONNX Runtime Web ile ince ayarlı, Transformers.js ile hızlı ve pratik bir deneyim kurabilirsiniz. Doğru model boyutu, FP16, akıllı ön/son işlem ve sağlam fallback stratejisiyle hem masaüstü hem mobilde akıcı bir kullanıcı deneyimi sunmak mümkün.

4 Kasım 2025 Salı

WebGPU ile Tarayıcıda Gerçek Zamanlı Nesne Tespiti: ONNX Runtime Web ile Adım Adım

Giriş

Tarayıcıda yapay zekâ çalıştırmak, yerel gizlilik, düşük gecikme ve kurulum gerektirmeyen dağıtım gibi avantajlar sunuyor. WebGPU’nun olgunlaşması ve ONNX Runtime Web’in hızla gelişmesi sayesinde, bugün artık masaüstü veya sunucuya gerek duymadan tarayıcı içinde gerçek zamanlı nesne tespiti mümkün. Bu yazıda, WebGPU ve ONNX Runtime Web kullanarak YOLO tabanlı hafif bir modelle, sıfırdan çalışan bir demo kurulumunun nasıl yapılacağını, performans ipuçlarını ve dikkat edilmesi gereken noktaları adım adım anlatıyorum.

Gereksinimler ve Hazırlık

Öncelikle güncel bir tarayıcıya ihtiyacınız var. WebGPU için Chrome/Edge 121+ tavsiye edilir; bazı cihazlarda WebGPU devre dışı olabilir, bu durumda ONNX Runtime Web otomatik olarak WASM (WebAssembly) yürütücüsüne düşebilir. Uygulamanızı HTTPS üzerinden ve mümkünse yerel geliştirmede localhost ile çalıştırın. Kamera erişimi için getUserMedia iznine de ihtiyaç olacak.

Proje Kurulumu

Hızlı başlamak için Vite kullanacağız. Terminalde aşağıdaki adımları izleyin:
1) npm create vite@latest webgpu-onnx-demo -- --template vanilla
2) cd webgpu-onnx-demo
3) npm install onnxruntime-web
4) npm install ve ardından npm run dev ile geliştirme sunucusunu başlatın.

Model Seçimi ve Dosya Yapısı

Tarayıcı için hafif bir model seçmek kritik. YOLO ailesinden yolov8n veya benzeri küçük bir ONNX modeli başlangıç için ideal. Model dosyasını projenizde public/models/yolov8n.onnx gibi bir yola koyun. Eğer int8/FP16 gibi quantized sürüm elinizde varsa performans kazanabilirsiniz; WebGPU bu tür ağlarda ciddi hız kazandırır.

ONNX Runtime Web ile Oturum Oluşturma

Tarayıcıda model çalıştırmak için onnxruntime-web kütüphanesi tek noktadan çözüm sunar. Basit bir başlatma şeması şöyle olabilir: import * as ort from 'onnxruntime-web' ardından const session = await ort.InferenceSession.create('/models/yolov8n.onnx', { executionProviders: ['webgpu', 'wasm'] }). Bu yapı, WebGPU destekliyse GPU’yu, değilse WASM’ı kullanır. Uygulama açılışında bir kez oturum oluşturup bellekte tutmak başlangıç gecikmesini azaltır.

Görüntü Kaynağı ve Ön İşleme

Kameradan akış almak için navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } }) kullanın. Video karesini bir canvas üzerine çizip modelin beklediği çözünürlüğe (örneğin 640x640) yeniden boyutlandırın. Piksel verisini canvas.getContext('2d').getImageData(...) ile alın, RGB sırasına getirip 0-1 aralığına normalize edin ve tensörü NCHW formatında Float32Array olarak oluşturun. ONNX’a beslemek için new ort.Tensor('float32', data, [1, 3, 640, 640]) şeklinde bir tensör üretin.

Çıktı Sonrası İşleme (Post-Processing)

YOLO benzeri modellerin çıktısı genellikle kutular, sınıf olasılıkları ve skorlar içerir. Sigmoid/Softmax dönüşümlerini uyguladıktan sonra bir Non-Maximum Suppression (NMS) adımı gerekir. NMS için IoU eşiğini (ör. 0.45) ve skor eşiğini (ör. 0.25) kendiniz belirleyin. Tarayıcı performansı için döngüleri optimize edin, mümkünse tek tip diziler (Float32Array) ve önceden ayrılmış tamponlar kullanın.

Çalıştırma Döngüsü ve Çizim

Her karede sırasıyla: videodan canvas’a çizim → ön işleme → session.run(feeds) → post-processing → kutuları ve etiketleri ikinci bir overlay canvas’ına çizim. Çizim için requestAnimationFrame kullanarak akıcı bir döngü yakalayın. WebGPU yürütücüsü açıkken orta sınıf bir dizüstünde 30 FPS ve üzeri değerlere ulaşmak mümkün; WASM yolunda ise 8-15 FPS aralığı gerçekçi bir beklentidir.

Performans İpuçları

1) Web Worker + OffscreenCanvas: Ön işleme ve NMS’i bir Worker içine alarak ana iş parçacığını boşaltabilirsiniz. OffscreenCanvas ile çizimleri de iş parçacığı dışında yapmak mümkün.
2) Isınma (Warm-up): Uygulama açılışında bir yapay girişle bir kez session.run çağırarak ilk kare gecikmesini düşürün.
3) Boyut ve Oran: Giriş çözünürlüğünü cihaz gücüne göre 320, 480, 640 şeklinde seçin. Düşük çözünürlük daha yüksek FPS demektir.
4) Kuantizasyon: FP16 veya INT8 modellerle hem bant genişliği hem de hesap yükünü azaltırsınız. WebGPU ile özellikle FP16 iyi sonuç verir.
5) Bellek Yönetimi: Her karede yeni dizi oluşturmak yerine tamponları yeniden kullanın; gereksiz GC duraklamalarını önleyin.

WebGPU Özel Notlar

Bazı cihazlarda navigator.gpu görünse bile adaptör kısıtları performansı etkileyebilir. adapter = await navigator.gpu.requestAdapter() ve device = await adapter.requestDevice() çağrılarında hata yakalama koyun. Uzun süren işlemlerde device.lost olayını dinleyip yeniden kurulum yapın. Ayrıca, farklı GPU sürücülerinde küçük nüanslar olabilir; kritik bölümlerde tarayıcı konsolunu takip edin.

WASM Yürütücüsü İçin Ek Ayarlar

WebGPU devre dışıysa ONNX Runtime Web’in WASM yürütücüsü devreye girer. graphOptimizationLevel: 'all' gibi seçeneklerle optimizasyonu artırın. Bazı SIMD hızlandırmaları için COOP/COEP başlıkları gereklidir; üretimde sunucu yapılandırmanızı Cross-Origin-Opener-Policy: same-origin ve Cross-Origin-Embedder-Policy: require-corp ile güncellemeyi düşünün. Bu sayede WASM SIMD ve bazı paralel özellikler etkin hale gelir.

Hata Ayıklama ve Ölçüm

FPS’i ölçmek için basit bir sayaç yazın ya da PerformanceObserver kullanın. ONNX katman sürelerini anlamak için giriş/çıkış zamanlarını konsola basmak yeterli olur. Çıktılar boşsa ilk bakacağınız yer ön işleme adımıdır: kanal sırası (NCHW/NHWC), normalize edilmemiş değerler veya çözünürlük uyuşmazlığı genellikle sorumludur.

WebGL mi, WebGPU mu?

WebGL tabanlı çözümler hâlâ iş görse de, makine öğrenmesi iş yüklerinde WebGPU ile daha tutarlı ve modern bir performans elde ediliyor. ONNX Runtime Web’in WebGPU yürütücüsü, operator kapsamını genişlettikçe fark daha da açılıyor. Kısacası, uzun vadede WebGPU tercih etmek mantıklı.

Sonuç

Bu rehberle, WebGPU ve ONNX Runtime Web kullanarak tarayıcıda gerçek zamanlı nesne tespiti uygulamasını uçtan uca kurmanın temel adımlarını gördük. Doğru model, dikkatli ön/post-işleme ve küçük optimizasyonlarla akıcı bir deneyim elde edebilirsiniz. Üstelik tümü istemci tarafında çalıştığı için gizlilik ve dağıtım kolaylığı cabası. Bir sonraki adım olarak, izleme (tracking), bölütleme (segmentation) veya metin çıkarımı (OCR) gibi ek yetenekleri aynı altyapı üzerinde denemeyi düşünebilirsiniz.

26 Ekim 2025 Pazar

Tarayıcıda Yapay Zeka: ONNX Runtime Web ve WebGPU ile YOLOv8 Nesne Tespiti (Adım Adım)

Giriş

Tarayıcıda çalışan yapay zeka uygulamaları son iki yılda WebGPU’nun yaygınlaşmasıyla ciddi ivme kazandı. Sunucu maliyeti olmadan, gecikmeyi düşürerek ve veriyi cihazda tutarak gerçek zamanlı deneyimler kurmak artık mümkün. Bu yazıda, ONNX Runtime Web ve WebGPU kullanarak tarayıcıda YOLOv8 tabanlı nesne tespiti nasıl çalıştırılır adım adım anlatıyorum. Amacımız, sade bir JavaScript projesinde model dosyasını yüklemek, WebGPU hızlandırmalı çıkarım yapmak ve olası performans tuzaklarını aşmak.

Neden Tarayıcıda Nesne Tespiti?

- Gizlilik: Görselleri veya kamera akışını sunucuya göndermeden cihazda işlemek, KVKK ve benzeri regülasyonlara uyumu kolaylaştırır.

- Düşük gecikme: Ağ gecikmesi ortadan kalktığı için özellikle gerçek zamanlı iş akışlarında (ör. kalite kontrol, interaktif demolar) deneyim belirgin şekilde iyileşir.

- Ölçeklenebilirlik: Her kullanıcı kendi cihaz kaynağını kullanır; sunucu GPU’su tahsis etme ihtiyacı azalır.

Gereksinimler

- Güncel bir Chromium tabanlı tarayıcı (Chrome/Edge 113+ sürümleri veya muadilleri) ya da WebGPU destekli Safari. Bazı eski sürümlerde deneysel bayraklar gerekebilir.

- Node.js ve bir paket yöneticisi (npm veya pnpm).

- onnxruntime-web paketi ve YOLOv8’in ONNX formatında bir sürümü (tercihen küçük bir varyant: yolov8n.onnx).

Proje Kurulumu

1) Hızlı bir iskelet için Vite ile başlangıç oluşturun: npm create vite@latest yolo-webgpu -- --template vanilla

2) Projeye girin ve bağımlılığı kurun: cd yolo-webgpu && npm i onnxruntime-web

3) Model dosyasını (ör. yolov8n.onnx) public/models/ klasörüne koyun. Geliştirme sırasında dosyaya /models/yolov8n.onnx yolu ile erişeceğiz.

4) Geliştirme sunucusunu başlatın: npm run dev. Modeli dosya sistemi üzerinden (file://) çağırmayın; tarayıcı CORS kısıtları nedeniyle engelleyebilir.

Modeli Hazırlama

Eğer hazır bir ONNX modeli kullanmıyorsanız, Ultralytics YOLOv8’i ONNX biçimine dışa aktarabilirsiniz. Tipik dışa aktarma, PyTorch modelinden .onnx üretir. Tarayıcı tarafı için küçük boyutlu (n veya s serisi) ve mümkünse nicemlenmiş (INT8) modeller performans ve bellek açısından avantaj sağlar. ONNX Runtime Web, QLinear tabanlı nicemlenmiş modelleri destekleyebilir; ancak operatör kapsaması modele göre değiştiğinden küçük bir varyantla başlamak mantıklıdır.

InferenceSession Oluşturma

Tarayıcı tarafında ONNX Runtime Web’i yükleyip WebGPU sağlayıcısıyla bir oturum açacağız. Güncel sürümlerde WebGPU kullanılabilir değilse otomatik olarak WASM arka ucuna düşecek şekilde bir dizi sağlayıcı tanımlamak iyi bir pratiktir:

import * as ort from 'onnxruntime-web';

const session = await ort.InferenceSession.create('/models/yolov8n.onnx', { executionProviders: ['webgpu', 'wasm'], graphOptimizationLevel: 'all' });

Bu yapılandırma, WebGPU uygunsa GPU hızlandırmayı kullanır; değilse WASM ile çalışmaya devam eder. WASM tarafında çok çekirdek ve SIMD faydası görmek için sayfanın Cross-Origin-Opener-Policy ve Cross-Origin-Embedder-Policy başlıklarıyla izole sunulması gerekir; Vite ve çoğu modern dev sunucu buna uygundur.

Ön İşleme ve Çıkarım

YOLOv8, girdi olarak tipik biçimde [1, 3, H, W] boyutunda, float32 normalleştirilmiş tensör bekler. Tarayıcıda bir <canvas> üzerinden görüntüyü 640×640’a yeniden boyutlandırıp RGB kanallarını alarak tensöre dönüştürebilirsiniz. Kanal sıralamasını (HWC → CHW) unutmayın ve 0–1 aralığına ölçekleyin.

Örnek çağrı akışı şu şekildedir: const feeds = { images: inputTensor }; ardından const output = await session.run(feeds);. Çoğu YOLOv8 ONNX dışa aktarımında çıktı, kutular ve sınıf skorlarını içeren tek bir tensördür. Bu tensörü NMS (Non-Maximum Suppression) ile filtreleyip skor ve sınıf eşikleri ile sonuçları çizmeniz gerekir.

Sonuçların Görselleştirilmesi

Nesne tespiti sonuçlarını çizmek için ikinci bir <canvas> katmanı kullanın. Her kutu için [x1, y1, x2, y2] koordinatlarını orijinal çözünürlüğe geri ölçekleyin. Sınıf adına göre renk paleti oluşturmak, kullanıcı deneyimini iyileştirir. Yüksek kare hızları elde etmek için çizimi requestAnimationFrame döngüsüyle eşleştirin ve her karede gereksiz bellek tahsisinden kaçının.

Performans İpuçları

- Küçük model seçin: yolov8n veya yolov8s web için daha uygundur.

- İlk çağrı ısınması: Uygulama açılışında küçük bir “boş” çıkarım tetikleyerek WebGPU shader derlemelerini önceden yaptırabilirsiniz; bu, ilk gerçek karedeki gecikmeyi düşürür.

- Nicemleme: INT8 veya dinamik nicemlenmiş modellerin boyutu küçülür ve bant genişliği ihtiyacı azalır. Doğruluk-hız dengesini ürün gereksinimlerinize göre ölçün.

- Asenkron iş akışı: Kamera karesini işlerken UI’ı kilitlememek için çıkarımı bir Web Worker içinde yürütmeyi değerlendirin. OffscreenCanvas desteklenen tarayıcılarda çizimi de iş parçacığına taşıyabilirsiniz.

Yayına Alma ve Güvenlik

Üretime alırken modeli bir CDN üzerinden cache-control başlıklarıyla servis etmek yükleme süresini iyileştirir. Model dosyalarınız büyükse gzip veya brotli sıkıştırmayı etkinleştirin. Gizlilik açısından, tüm çıkarımın cihazda kalması önemli bir artıdır; sunucuya yalnızca analitik metrikleri veya anonimleştirilmiş telemetri göndermek yeterli olabilir. Kamera erişimi gerekiyorsa kullanıcıya net bir izin akışı ve kapatma seçeneği sunun.

Sorun Giderme

- navigator.gpu undefined: Tarayıcı WebGPU’yu desteklemiyor olabilir. Sağlayıcı sırasına 'wasm' eklediğinizden emin olun.

- CORS/ERR_BLOCKED_BY_RESPONSE: Modeli file:// üzerinden değil bir HTTP sunucusundan yükleyin; yerelde Vite dev sunucusu yeterlidir.

- Out of memory: Modeli küçültün, çözünürlüğü düşürün (ör. 640 → 512) ve gereksiz kopyaları engellemek için tensörleri tekrar kullanın.

Sonuç

ONNX Runtime Web ve WebGPU kombinasyonu, tarayıcıda gerçek zamanlı nesne tespiti için pratik ve çağdaş bir yaklaşım sunuyor. Doğru model seçimi, düzenli ön işleme ve akıllı görselleştirme ile sunucu maliyeti olmadan yüksek kaliteli deneyimler oluşturabilirsiniz. Küçükten başlayın, performansı ölçerek iterasyon yapın ve kademeli olarak daha gelişmiş modellere geçin. Böylece hem kullanıcı gizliliğini korur hem de modern web’in sunduğu GPU gücünden en iyi şekilde yararlanmış olursunuz.

17 Ekim 2025 Cuma

Tarayıcıda WebGPU ile Yapay Zeka Modellerini Hızlandırma: ONNX Runtime Web ile Adım Adım Rehber

WebGPU ile Tarayıcıda Yapay Zeka Neden Önemli?

WebGPU, tarayıcıda GPU’ya neredeyse yerel erişim sağlayan modern bir web standardıdır. WebGL’in grafik odaklı doğasını aşarak hesaplama iş yüklerini de hızlandırır ve makine öğrenmesi modellerini doğrudan Chrome, Edge veya Safari gibi tarayıcılarda çalıştırırken belirgin performans kazancı sunar. Bu yazıda, ONNX Runtime Web kullanarak WebGPU üzerinden nasıl hızlandırma yapabileceğinizi, gerçek dünya ipuçları ve sorun giderme önerileriyle adım adım anlatıyorum.

Ön Koşullar ve Uyumluluk

WebGPU, Chrome 113+, Edge 113+ sürümlerinde yaygın olarak desteklenir. macOS’te Metal, Windows’ta Direct3D 12, Linux’ta ise Vulkan üzerinden çalışır. Güncel bir tarayıcı kullandığınızdan emin olun. Kurumsal cihazlarda GPU sürücüleri eskiyse veya politika kısıtları varsa WebGPU adaptörü bulunamayabilir; bu durumda ONNX Runtime Web otomatik olarak WASM (WebAssembly) yedek yoluna düşebilir. Eğer eski bir tarayıcı kullanıyorsanız, chrome://flags alanında WebGPU ile ilgili ayarları gözden geçirmeniz gerekebilir; ancak çoğu güncel sürümde ekstra bir işlem yapmadan çalışır.

Ne Kuracağız? Kısa Yol Haritası

Bu rehberde bir web sayfasına ONNX Runtime Web’i entegre edip, bir görüntü sınıflandırma modelini WebGPU üzerinde çalıştıracağız. Adımlar özetle şöyle: ONNX Runtime Web’i projeye eklemek, uygun bir ONNX modeli seçmek, girdi verisini hazırlamak, executionProviders: ["webgpu"] ile oturum açmak ve sonuçları yorumlamak.

Adım 1: Projeye ONNX Runtime Web Eklemek

İki yaygın yöntem var. NPM ile kurulum için modern bir paketleyici (Vite, Webpack, Parcel) kullanabilirsiniz. Komut satırında npm i onnxruntime-web diyerek kurduktan sonra uygulamanızda import * as ort from "onnxruntime-web" ifadesini kullanın. Hızlı denemeler için CDN ile de ilerleyebilirsiniz: HTML dosyanıza ONNX Runtime Web’in CDN bağlantısını eklemek yeterli olur. Her iki yöntemde de tarayıcınızda WebGPU destekliyse arka planda otomatik olarak GPU hızlandırma devreye alınabilir.

Adım 2: Model Seçimi ve Hazırlık

Başlangıç için ONNX Model Zoo’da bulunan hafif bir model tercih edin. Örneğin MobileNet veya SqueezeNet düşük bellek tüketimiyle iyi bir başlangıç sunar. İndirdiğiniz model dosyasını (örnek: model.onnx) sunucunuzdan statik olarak servis edin. Model boyutunu mümkün olduğunca düşük tutmak hem ilk yükleme süresini hem de bellek kullanımını azaltır. FP16 dönüştürülmüş modeller, GPU bellek ayak izini düşürerek performansa katkı sağlar.

Adım 3: WebGPU ile Oturum Oluşturma

ONNX Runtime Web ile bir oturum oluştururken executionProviders: ["webgpu"] parametresini geçerek GPU hızlandırmayı istersiniz. WebGPU uygun değilse kütüphane WASM’a otomatik geçebilir. Bu aşamada önemli nokta, oturumu yalnızca bir kez oluşturmanızdır; inference işlemleri sırasında aynı oturumu tekrar tekrar kullanmak, modelin yeniden yüklenmesini ve derlenmesini önleyerek ciddi zaman kazandırır.

Adım 4: Girdi Hazırlama ve İnference

Görüntü tabanlı bir model için girdiyi modele uygun boyuta ölçekleyip normalleştirmeniz gerekir. Bu işlem genellikle şu adımlardan oluşur: görseli kanallara ayırma (RGB), piksel değerlerini 0-1 aralığına ölçekleme, ortalama/standart sapma ile normalizasyon ve tensörü NCHW biçiminde düzenleme. ONNX Runtime Web için tensör oluştururken new ort.Tensor("float32", data, [1, 3, H, W]) biçimini kullanabilirsiniz. Çıktı yüzlerce sınıf ve olasılık içeriyorsa en yüksek olasılıklı birkaç etiketi seçip kullanıcıya sunmak idealdir.

Adım 5: Performans İyileştirme İpuçları

Performansı artırmak için birkaç pratik öneri: Oturum nesnesini yeniden kullanın ve model dosyasını önbelleğe alarak ilk yükleme süresini kısaltın. Girdi verisini oluştururken gereksiz kopyalardan kaçının; aynı Float32Array tamponunu yeniden kullanmak GC yükünü azaltır. Mümkünse daha küçük çözünürlükte girişler deneyin; bazı modeller 224x224 ile tatmin edici sonuç verir. Ağır iş yüklerini Web Worker içine taşıyarak ana iş parçacığını bloklamayın; UI donmalarını önlemek için hesaplama dilimlerini requestIdleCallback veya küçük partisyonlarla planlayın. Ölçüm için performance.now() ile yükleme, ön işleme, inference ve son işlem sürelerini ayrı ayrı izleyin; darboğazı nokta atışı bularak iyileştirin.

Güvenlik, Gizlilik ve Dağıtım

Tarayıcı içinde yerel inference çalıştırmak, verilerin sunucuya gitmeden işlenmesini sağlar; bu da gizlilik ve gecikme (latency) açısından avantajdır. WASM yedek yolunda iş parçacıkları ve SIMD kullanmayı planlıyorsanız COOP/COEP başlıklarıyla cross-origin isolated bir yapılandırma gerekir. İç ağda veya kurumsal ortamlarda dağıtım yaparken GPU sürücü sürümlerini ve tarayıcı versiyonlarını standardize etmek, destek çağrılarını ciddi ölçüde azaltır.

Yaygın Hatalar ve Çözümler

“Adapter is null” veya “No WebGPU device found” hataları alıyorsanız tarayıcınızı ve ekran kartı sürücünüzü güncelleyin; sanal makinelerde WebGPU kısıtlı olabilir. “Out of memory” uyarılarında giriş boyutunu küçültün, modelin FP16 sürümüne geçin veya daha hafif bir mimari deneyin. “Invalid model input shape” hatası, tensör boyutlarıyla modelin beklediği şeklin uyuşmadığını gösterir; modelin giriş ismini ve beklenen boyutları kontrol edin. WASM’a düşüşte performans çok geriliyorsa, WebGPU’nun gerçekten etkinleştiğini doğrulamak için oturum seçeneklerini ve tarayıcı destek sayfalarını inceleyin.

Gerçek Dünya Senaryoları

Perakende uygulamalarında raf denetimi veya barkod dışı ürün tanıma gibi görevler, mağaza içi tabletlerle çevrimdışı çalıştırılabilir. Eğitim teknolojilerinde çizim veya laboratuvar deneylerinde görüntü analizi, öğrenci cihazlarında gecikme olmadan yapılabilir. Yayıncılıkta canlı metin filtreleme veya basit duygu analizi, kullanıcı tarayıcısında gerçekleşerek sunucu maliyetlerini düşürür.

Sonuç ve Öneriler

WebGPU, tarayıcıda yapay zeka deneyimini yeni bir seviyeye taşıyor. ONNX Runtime Web ile birlikte kullanıldığında, çeşitli cihaz ve tarayıcı kombinasyonlarında tatmin edici performans ve düşük gecikme elde etmek mümkün. Küçük ve optimize edilmiş bir model, doğru ön işleme adımları ve tek seferde başlatılan bir oturum mimarisi, projelerinize stabilite ve hız kazandırır. İlk prototipinizi basit bir görüntü sınıflandırma modeliyle kurup, ardından model boyutu, giriş çözünürlüğü ve iş parçacığı stratejileri üzerinde iterasyon yaparak prodüksiyon seviyesine güvenle geçebilirsiniz.

15 Ekim 2025 Çarşamba

WebGPU ile Tarayıcıda Nesne Tespiti: ONNX Runtime Web ile Adım Adım Kurulum

Giriş

Tarayıcıda makine öğrenmesi artık bir demodan öte; üretim senaryolarına hazır. WebGPU sayesinde GPU hızlandırmalı hesaplama, Chrome ve Edge gibi modern tarayıcılarda varsayılan olarak açıldı. Bu rehberde, ONNX Runtime Web (ORT Web) kullanarak tarayıcı içinde nesne tespiti (YOLO ailesi gibi) modelini çalıştırmayı ve WebGPU yürütme sağlayıcısı ile performansı nasıl artırabileceğinizi anlatıyorum. Kurulum adımlarını, küçük kod parçacıklarıyla ve pratik ipuçlarıyla beraber bulacaksınız.

Neden WebGPU?

WebGPU, WebGL’in ötesine geçerek daha modern bir grafik ve hesaplama API’si sunar. ML tarafında en kritik fark, tensör hesaplamalarını verimli çalıştırabilmesi ve veri kopyalamayı azaltmasıdır. Sonuç olarak, aynı model WebAssembly (WASM) ile 200-400 ms sürerken, WebGPU ile 60-120 ms aralığına inebilir; bu özellikle canlı kamera akışında kare kaçırmamak için belirleyici bir fark yaratır.

Ön Koşullar ve Tarayıcı Desteği

- Chrome 113+ ve Edge 113+ sürümlerinde WebGPU masaüstünde varsayılan olarak açık. Mac’te Apple Silicon ile daha istikrarlı sonuçlar alırsınız. Firefox’ta Nightly ile about:config altında dom.webgpu.enabled bayrağını etkinleştirmeniz gerekebilir. Safari’de ise Technology Preview önerilir.
- Geliştirme için basit bir statik sunucu kullanın: npx serve, python -m http.server veya VS Code Live Server eklentisi işinizi görür. Dosyaları doğrudan diskten açmak (file://) CORS hatalarına yol açar.

Proje Yapısı

Minimum örnek için şu dosyaları oluşturun: index.html, app.js ve model dosyanız (ör. yolov8n.onnx). Test için bir görüntü dosyası veya webcam akışı kullanabilirsiniz. Kamera ile test edecekseniz, HTTPS üzerinde yayınlamayı unutmayın; tarayıcılar güvenlik nedeniyle kamera erişimini HTTP’de kısıtlar.

ONNX Runtime Web’i Ekleme

CDN ile hızlı başlamak için index.html içine ORT Web’i ekleyebilirsiniz: <script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort-web.min.js"></script>. Alternatif olarak modüler kullanım için paket yöneticileriyle onnxruntime-web kurabilir, bundler ile projeye dahil edebilirsiniz. WebGPU hızlandırma için çalışma zamanı seçeneklerinde executionProviders: ['webgpu'] belirtmeniz yeterli.

Oturum Oluşturma ve WebGPU’yu Açma

Temel başlatma adımı şöyledir: const session = await ort.InferenceSession.create('yolov8n.onnx', { executionProviders: ['webgpu'], graphOptimizationLevel: 'all' });. Eğer cihazda WebGPU yoksa otomatik olarak WASM’a düşmek isteyebilirsiniz; o durumda önce WebGPU ile dene, başarısız olursa executionProviders: ['wasm'] ile yeniden oluştur şeklinde bir sarmalayıcı yazın.

Girdi Hazırlama

Nesne tespiti modelleri tipik olarak BxCxHxW float32 tensörü bekler. Tarayıcı tarafında Canvas üzerinden resmi alıp 640x640 gibi modele uygun boyuta yeniden örnekleyin, ardından ImageData piksellerinden Float32Array oluşturun. Kanal sıralaması (NCHW vs NHWC) ve normalizasyon (0-1 arası ölçek, ortalama-standart sapma) modelinize göre değişir; ONNX ihracını yaparken hangi düzen kullanıldıysa ona sadık kalın. Örnek: const input = new ort.Tensor('float32', floatArray, [1,3,640,640]);

Çıktıların İşlenmesi

YOLO tarzı modeller, her kutu için [x, y, w, h, score, class] veya benzeri bir yapı üretir. Post-processing adımları: skor eşiği uygulama (örn. 0.25), Non-Maximum Suppression ile çakışan kutuları eleme ve sınıf etiketleri ile renklendirme. ORT WebGPU bazı durumlarda çıktı tensörünü GPU belleğinde tutabilir; tarayıcı tarafında çizmek için CPU’ya kopyalamanız gerekir. Performans için tek bir canvas üzerinde hem görüntü hem de kutuları çizmek, her karede gereksiz tahsislerden kaçınmak önemlidir.

Performans İpuçları

- Model boyutu: YOLOv8n gibi küçük varyantlarla başlayın; tarayıcıda latency dramatik şekilde düşer.
- Precision: FP16 desteği olan cihazlarda otomatik kazanç sağlanır. ORT Web, WebGPU arka ucunda uygunsa bunu kullanır.
- İşletim birleştirme: graphOptimizationLevel: 'all' genellikle faydalı. Bazı modellerde ek kazanımlar için ONNX’ı optimize edin (Fusion/Constant folding).
- Batch=1: Akış senaryolarında tekli batch en düşük gecikmeyi verir.
- Sıcak çalışma: İlk çalıştırmadan önce bir kez “ısındırma” inference’ı yapın; shader derlemeleri ve önbellekler sonrası kare süreleri iyileşir.

Güvenlik ve Barındırma

Model dosyanız büyükse (ör. 20-50 MB), ilk yükleme süresi kullanıcı deneyimini etkiler. HTTP istemci önbelleği için uzun Cache-Control süreleri ayarlayın ve sürümleme yapın. Kamera kullanan sayfalar için HTTPS zorunlu. Cross-origin model yüklerken CORS başlıklarını doğru verin (Access-Control-Allow-Origin). Ayrıca, kullanıcı donanımlarında GPU kaynakları sınırlı olabilir; bir hata durumunda kibarca WASM’a düşmek, uygulamanın kırılmasını engeller.

Hata Ayıklama

- navigator.gpu yoksa tarayıcı sürümünüzü ve bayrakları kontrol edin.
- ValidationError görüyorsanız tensör şekilleri/hizalamaları uyuşmuyor olabilir. Girdiyi ve modelin beklediği düzeni tekrar gözden geçirin.
- Performance sekmesiyle CPU/GPU zamanlarını izleyin; çoğu darboğaz, görüntü ön-işlemede ortaya çıkar. Web Workers ile ön-işlemeyi ana iş parçacığından ayırmak sayfa akıcılığını artırır.

Sonuç

WebGPU ve ONNX Runtime Web birleşimi, tarayıcıda ML uygulamaları için yeni bir performans eşiği sunuyor. Sunucuya görüntü yüklemeden, gizlilik dostu ve düşük gecikmeli nesne tespiti mümkün. Bu rehberdeki yapı ile kısa sürede çalışan bir prototip çıkarabilir, ardından model optimizasyonu, önbellekleme ve UI cilasıyla üretim seviyesine taşıyabilirsiniz. Bir kez kurduktan sonra, segmentasyon, yüz mesh’i ya da metin tespiti gibi diğer ONNX modellerini de aynı altyapı üzerinde hızla deneyebilirsiniz.

7 Ekim 2025 Salı

WebGPU Destekli ONNX Runtime Web ile Tarayıcıda Yapay Zeka Çalıştırma: Adım Adım Rehber

Giriş

Tarayıcıda yapay zeka çalıştırmak, artık sadece demo projelerin konusu değil. WebAssembly (WASM) ve WebGPU sayesinde, masaüstü benzeri performansla gerçek zamanlı çıkarım almak mümkün. Bu rehberde, ONNX Runtime Web kullanarak bir modeli tarayıcıda çalıştırmayı, WebGPU ve WASM arasında nasıl seçim yapacağınızı ve performansla ilgili pratik ipuçlarını adım adım anlatıyorum.

Neden Tarayıcıda Yapay Zeka?

Tarayıcı üzerinde çıkarımın üç büyük avantajı var: gizlilik (veri cihazdan çıkmıyor), kurulum kolaylığı (ekstra bağımlılık yok) ve dağıtım hızı (sadece bir web sayfası). Örneğin bir görüntü sınıflandırma modeli, web uygulamanızda kullanıcı fotoğrafını anında analiz edebilir ve bu sırada veriyi sunucuya göndermenize gerek kalmaz. Üstelik WebGPU desteği olan tarayıcılarda GPU hızlandırma ile mobil cihazlarda bile akıcı performans elde edebilirsiniz.

Gereksinimler

- Güncel bir tarayıcı (Chrome 113+, Edge 113+, Safari 17+). WebGPU desteği yoksa WASM sağlayıcısı otomatik devreye girer.
- Basit bir HTTP sunucu (ör. npx serve veya python -m http.server). Güvenlik nedeniyle dosyaları doğrudan dosya sistemi üzerinden açmak yerine bir sunucu gerekli.
- Bir ONNX modeli (ör. MobilNet v2 sınıflandırma modeli). Dilerseniz kendi modelinizi torch.onnx.export ile dışa aktarabilirsiniz.

Proje Kurulumu

1) Klasör oluşturun: mkdir ort-web-demo && cd ort-web-demo
2) Model dosyasını model.onnx olarak kök dizine koyun.
3) Aşağıdaki basit HTML dosyasını index.html olarak kaydedin (CDN üzerinden ONNX Runtime Web yüklenecek):

<!doctype html>
<html lang="tr">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <title>ONNX Runtime Web Demo</title>
</head>
<body>
  <h3>Tarayıcıda Yapay Zeka (WebGPU / WASM)</h3>
  <input type="file" id="file" accept="image/*"/>
  <div id="log">Hazır...</div>
  <script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js"></script>
  <script>
  (async () => {
    // WebGPU uygunsa önce onu, değilse WASM'ı dene
    const providers = (navigator.gpu) ? ['webgpu', 'wasm'] : ['wasm'];
    ort.env.wasm.simd = true; // SIMD hızlandırma
    ort.env.wasm.numThreads = Math.min(4, navigator.hardwareConcurrency || 2);

    const session = await ort.InferenceSession.create('model.onnx', { executionProviders: providers });
    document.getElementById('log').innerText = 'Model yüklendi. Sağlayıcı: ' + session.executionProvider;

    const fileInput = document.getElementById('file');
    fileInput.onchange = async () => {
      const file = fileInput.files[0];
      if (!file) return;
      const img = new Image();
      img.src = URL.createObjectURL(file);
      await img.decode();

      // Basit ön işleme: 224x224'e ölçekle, [0,1] normalizasyonu
      const canvas = document.createElement('canvas');
      canvas.width = 224; canvas.height = 224;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0, 224, 224);
      const { data } = ctx.getImageData(0, 0, 224, 224);
      const input = new Float32Array(1 * 3 * 224 * 224);
      for (let i = 0; i < 224 * 224; i++) {
        const r = data[i * 4] / 255;
        const g = data[i * 4 + 1] / 255;
        const b = data[i * 4 + 2] / 255;
        input[i] = r; input[i + 224 * 224] = g; input[i + 2 * 224 * 224] = b;
      }

      const tensor = new ort.Tensor('float32', input, [1, 3, 224, 224]);
      const feeds = {}; feeds[session.inputNames[0]] = tensor;
      const t0 = performance.now();
      const results = await session.run(feeds);
      const t1 = performance.now();
      const output = results[session.outputNames[0]].data;
      const maxIndex = output.indexOf(Math.max(...output));
      document.getElementById('log').innerText = `Sınıf: ${maxIndex}, Süre: ${(t1 - t0).toFixed(1)}ms`;
    };
  })();
  </script>
</body>
</html>

Uygulamayı Çalıştırma

Kök dizinde küçük bir sunucu başlatın. Node.js varsa: npx serve . veya Python ile: python -m http.server 8080. Ardından tarayıcıdan http://localhost:8080 adresine gidin. Bir görsel seçtiğinizde model çıkarımı yapacak ve süreyi ms cinsinden gösterecektir. WebGPU mevcutsa sağlayıcı olarak webgpu, değilse wasm kullanılır.

Performans İpuçları

- SIMD ve çok iş parçacığı: Kodda ort.env.wasm.simd = true ve numThreads ayarları etkin. Tarayıcı buna izin veriyorsa WASM performansı ciddi artar.
- WebGPU avantajı: Büyük modellerde GPU hızlandırma dramatik fark yaratır. Ancak WebGPU, HTTPS ve güvenli bağlam gerektirir. Üretimde daima HTTPS kullanın.
- Model optimizasyonu: ONNX modeli fuse ve constant folding ile optimize edin. INT8 quantization (ör. onnxruntime-tools veya optimum) tarayıcıda boyutu küçültür ve hız kazandırır.
- Lazy yükleme: Modeli sayfa yüklendiğinde değil, kullanıcı etkileşimi başladığında indirin. İlk TTI süresini iyileştirir.
- Önbellek: Model dosyasını IndexedDB veya Cache Storage ile saklayın. İlk açılıştan sonra bekleme neredeyse sıfırlanır.

Hata Ayıklama ve Uyumluluk

- Giriş/çıkış adları: Bazı modellerde giriş ismi input değil, farklı olabilir. session.inputNames ve session.outputNames ile dinamik alın.
- Bellek limitleri: Büyük modeller mobilde bellek sınırına takılabilir. Daha küçük veya quantized sürüme geçin.
- CORS: Modeli farklı bir domain’den çağırıyorsanız CORS başlıklarını doğru ayarlayın (Access-Control-Allow-Origin).
- Tarayıcı farkları: Safari’de GPU bellek kotaları daha katı olabilir; WASM yedek planınızın iyi çalıştığından emin olun.

Güvenlik ve Gizlilik

Tarayıcıda çıkarımın en güçlü yanı, verinin cihazda kalmasıdır. Yine de kullanıcı içeriğini asla arka plana otomatik yüklemeyin ve gerekli olmadıkça loglamayın. Model dosyalarınızı bütünlüğü doğrulanmış bir CDN’den servis edin ve içerik güvenlik politikanızda (Content-Security-Policy) sadece ihtiyaç duyulan kaynaklara izin verin.

Sonuç

ONNX Runtime Web ile WebGPU/WASM arasında otomatik geçiş yaparak, modern tarayıcılarda güçlü bir yapay zeka deneyimi sunmak mümkün. Yukarıdaki basit örnek; görüntü sınıflandırma, metin analizi veya poz tahmini gibi pek çok senaryonun temelini oluşturur. Üretime geçerken model optimizasyonu, önbellekleme ve güvenlik adımlarını uyguladığınızda, native’e yakın bir hız ve akıcılık elde edebilirsiniz.

27 Eylül 2025 Cumartesi

WebGPU ile Tarayıcıda Makine Öğrenmesi: ONNX Runtime Web ile GPU Hızlandırmalı Görüntü Sınıflandırma

Giriş

WebGPU, tarayıcıda modern grafik ve hesaplama iş yüklerini donanıma yakın performansla çalıştırmaya imkan tanıyor. Bu makalede, ONNX Runtime Web kullanarak WebGPU üzerinde GPU hızlandırmalı bir görüntü sınıflandırma örneğini adım adım kuracağız. Amaç, ek bir sunucuya gerek kalmadan, tamamen istemci tarafında çalışan ve gerçek zamanlıya yakın tepki veren bir makine öğrenmesi deneyimi elde etmek.

Neden WebGPU ve ONNX Runtime Web?

WebGL veya WASM ile kıyaslandığında WebGPU, paralel iş yüklerini daha verimli planlayarak tensör işlemlerini hızlandırır. ONNX Runtime Web ise aynı model dosyasını hem WebGPU hem WASM üzerinde çalıştırabilen esnek bir yürütme altyapısı sunar. Bu sayede destekli cihazlarda GPU, diğerlerinde otomatik olarak CPU kullanılabilir; uygulama tek kod tabanıyla geniş bir cihaz yelpazesini kapsar.

Ön Koşullar ve Ortam

- Chrome 121+ veya Edge 121+ gibi WebGPU destekli bir tarayıcı kullanın. Firefox’ta Nightly sürümünde dom.webgpu.enabled bayrağıyla çalışır. Safari’de ise güncel sürümler kısmi destek verir. Uygulamayı güvenli kökenden (https veya localhost) barındırın.

- Node.js 18+ ve npm gereklidir. Örnek, vanilla JS ve Vite ile hazırlanacaktır.

Proje Kurulumu

1) Yeni bir proje oluşturun: npm create vite@latest webgpu-ml -- --template vanilla

2) Klasöre girin ve bağımlılıkları ekleyin: cd webgpu-ml && npm i onnxruntime-web

3) Basit bir dizin yapısı oluşturun: /public/model/mobilenetv3.onnx ve etiketler için /public/model/labels.json. ONNX modelini ONNX Model Zoo’dan veya dönüştürdüğünüz bir MobileNetV3 modelinden alabilirsiniz.

Temel Kod: Oturum, Ön İşleme, Çıkarım

Aşağıdaki kod, WebGPU destekli bir tarayıcıda modeli başlatır, bir görüntüyü 224x224’e ölçekler, normalleştirir, tensöre çevirir ve çıkarım yapar. Destek yoksa WASM’e otomatik düşer.

import * as ort from 'onnxruntime-web';
// 1) Oturum oluşturma (GPU + CPU yedekli)
const session = await ort.InferenceSession.create('/model/mobilenetv3.onnx', {
  executionProviders: ['webgpu', 'wasm'],
  graphOptimizationLevel: 'all'
});

async function loadImageToTensor(imgEl) {
  const size = 224;
  const canvas = document.createElement('canvas');
  canvas.width = size; canvas.height = size;
  const ctx = canvas.getContext('2d');
  ctx.drawImage(imgEl, 0, 0, size, size);
  const { data } = ctx.getImageData(0, 0, size, size);
  const mean = [0.485, 0.456, 0.406];
  const std = [0.229, 0.224, 0.225];
  const chw = new Float32Array(1 * 3 * size * size);
  for (let i = 0; i < size * size; i++) {
    const r = data[i * 4] / 255, g = data[i * 4 + 1] / 255, b = data[i * 4 + 2] / 255;
    chw[i] = (r - mean[0]) / std[0];
    chw[i + size * size] = (g - mean[1]) / std[1];
    chw[i + 2 * size * size] = (b - mean[2]) / std[2];
  }
  return new ort.Tensor('float32', chw, [1, 3, size, size]);
}

async function classify(imgEl) {
  const input = await loadImageToTensor(imgEl);
  const feeds = { [session.inputNames[0]]: input };
  const outputMap = await session.run(feeds);
  const logits = outputMap[session.outputNames[0]].data;
  // Softmax ve top-k
  const exps = logits.map(x => Math.exp(x - Math.max(...logits)));
  const sum = exps.reduce((a, b) => a + b, 0);
  const probs = exps.map(e => e / sum);
  const topK = [...probs].map((p, i) => ({ i, p })).sort((a, b) => b.p - a.p).slice(0, 5);
  const labels = await fetch('/model/labels.json').then(r => r.json());
  return topK.map(({ i, p }) => ({ label: labels[i], prob: p }));
}

Performans İpuçları

- FP16 kullanımı: Bazı modelleri yarım hassasiyetle (Float16) çalıştırmak bellek ve bant genişliği kullanımını düşürerek hız kazandırır. Modeliniz FP16’ya dönüştürülmüşse WebGPU’da belirgin fark görebilirsiniz.

- Girdi boyutu: 224x224 yerine 192x192 gibi daha küçük boyutlar deneyerek gecikmeyi azaltın. Bu değişim doğruluk kaybı ile hız kazanımı arasında bir denge gerektirir.

- Ortak önbellek: Modeli uygulama yaşam döngüsü boyunca bir kez yükleyip aynı oturumu tekrar kullanın. Tekrarlı session.create maliyetlidir.

- Grafik optimizasyon seviyesi: graphOptimizationLevel: 'all' çoğu senaryoda iyi sonuç verir. Bazı modellerde extended veya basic de test edilmeli.

- Çalışma zamanında veri kopyalarını azaltın: Canvas’tan aldığınız ImageData yerine WebCodecs API ile VideoFrame kullanmak (destekliyse) dönüşümleri hızlandırabilir.

Uyumluluk ve Geriye Dönük Çalışma

WebGPU her cihazda aynı düzeyde mevcut olmayabilir. executionProviders: ['webgpu', 'wasm'] sıralaması sayesinde GPU destekli tarayıcılarda hızlanır, diğerlerinde WASM’e düşer. Bu yaklaşım üretim ortamında kesintisiz deneyim sağlar. Ayrıca HTTPS ve güvenli bağlam zorunluluğuna dikkat edin; yerel geliştirmede localhost istisnadır.

Hata Ayıklama

- Model giriş/çıkış adları: session.inputNames ve session.outputNames ile doğrulayın; ONNX ihracında katman adları değişmiş olabilir.

- Bellek taşmaları: Büyük modeller mobil cihazlarda bellek sınırlarına takılabilir. Modeli quantize ederek (INT8/UINT8) veya daha hafif mimarilere geçerek çözebilirsiniz.

- WebGPU hataları: Tarayıcı konsolunda validation error mesajlarını kontrol edin. Sürücü veya adaptör sınırlamaları için navigator.gpu.requestAdapter() ile dönen limitleri inceleyin.

Gerçek Hayat Senaryoları

- Ürün arama: Kullanıcı yüklediği fotoğrafla eşleşen kategoriye gerçek zamanlı yönlendirme.

- İçerik güvenliği: Tarayıcıda ön filtreleme yaparak sunucu maliyetini ve gecikmeyi azaltma.

- Eğitim: Etkileşimli ML demoları ve ders materyalleri, laboratuvar kurulumları olmadan, yalnızca bir URL ile erişilebilir.

Sonuç

WebGPU ve ONNX Runtime Web birlikteliği, tarayıcıda makine öğrenmesi için yeni bir performans eşiği oluşturuyor. Doğru model seçimi, hafif ön/son işleme ve dikkatli optimizasyonlarla, mobil dahi pek çok cihazda tatmin edici hızlara ulaşmak mümkün. Bu temel iskeleti kullanarak; nesne tespiti, metinden görüntü üretimi veya konuşma tanıma gibi daha karmaşık senaryolara ilerleyebilirsiniz. Üstelik tümü, kullanıcı verisini cihazdan çıkarmadan, gizlilik dostu bir şekilde.

14 Eylül 2025 Pazar

WebGPU ile Tarayıcıda Yapay Zeka: ONNX Runtime Web ile Hızlı Görüntü Sınıflandırma Rehberi

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.

3 Eylül 2025 Çarşamba

Tarayıcıda WebGPU ile ONNX Runtime Web Kullanarak YOLOv8 Nesne Tanıma: Adım Adım Kurulum ve Performans İpuçları

Giriş

Tarayıcıda çalışan yapay zeka uygulamaları artık sadece demolarla sınırlı değil. WebGPU ve ONNX Runtime Web sayesinde, YOLOv8 gibi modern nesne tanıma modellerini doğrudan kullanıcıların cihazlarında, sunucuya ihtiyaç duymadan ve düşük gecikmeyle çalıştırmak mümkün hale geldi. Bu yazıda, YOLOv8 modelini ONNX formatına dönüştürüp WebGPU yürütücüsüyle tarayıcıda nasıl çalıştırabileceğinizi, performans odaklı pratik ipuçlarıyla adım adım anlatıyorum.

Neden WebGPU + ONNX Runtime Web?

WebGPU, modern GPU mimarilerine daha yakın bir API sunduğu için WebGL/Canvas tabanlı yaklaşımlara göre çok daha yüksek paralellik ve verimlilik sağlar. ONNX Runtime Web ise modelleri tarayıcıda WebGPU ya da WASM yürütücüleri ile çalıştırır. Bu ikili; hız, taşınabilirlik ve gizlilik avantajlarını aynı anda sunar: veriler tarayıcıdan çıkmaz, gecikme düşer, CDN üzerinden servis edilen statik dosyalarla ölçeklenebilir bir dağıtım sağlanır.

Ön Koşullar

Güncel bir Chromium tabanlı tarayıcı (Chrome/Edge 121+), WebGPU desteği açık bir ortam (HTTPS zorunlu), Node.js 18+ ve temel TypeScript/JavaScript bilgisi yeterli. Geliştirme için Vite ile hafif bir proje yapısı kuracağız.

Modeli Hazırlama (YOLOv8 → ONNX)

Ultralytics YOLOv8 modelini ONNX’e aktarmak için Python tarafında şu adımı izleyebilirsiniz: pip install ultralytics komutuyla paketi kurun ve ardından yolo export model=yolov8n.pt format=onnx opset=12 imgsz=640 komutunu çalıştırın. Bu işlem sonunda yolov8n.onnx dosyasını elde edersiniz. Alternatif olarak resmi depolardan hazır ONNX sürümlerini indirebilir ve doğrudan statik olarak sunabilirsiniz.

Projeyi Kurma (Vite + TypeScript)

Yeni bir proje başlatmak için şu komutu çalıştırın: npm create vite@latest onnx-webgpu -- --template vanilla-ts. Proje klasörüne geçip npm i onnxruntime-web komutuyla ONNX Runtime Web’i ekleyin. Modeli ve etiket dosyalarını public/models klasörüne kopyalayın. Geliştirme sunucusunu başlatmak için npm run dev yeterli olacaktır.

WebGPU Yürütücü ile İnferans

Tarayıcı tarafında WebGPU yürütücüsünü etkinleştirmek için modülü içeri aktarın: import 'onnxruntime-web/webgpu' ve ardından import { InferenceSession, Tensor } from 'onnxruntime-web'. Oturum oluştururken yürütücüyü belirtebilirsiniz: const session = await InferenceSession.create('/models/yolov8n.onnx', { executionProviders: ['webgpu'], graphOptimizationLevel: 'all' }). Eğer cihazda WebGPU uygun değilse bir yakalama bloğunda ['wasm'] ile geriye dönük destek sunmak mümkündür.

Görüntüyü tensöre dönüştürmek için bir <canvas> referansı yeterli. Görüntünün 640x640 boyutuna mektup kutusu (letterbox) ile ölçeklenmesi, ardından piksel verisinin Float32 tensöre [1, 3, H, W] düzeninde (RGB, kanal-öncelikli) aktarılması gerekir. Normalizasyon için genellikle 0–1 aralığı ve gerekiyorsa modelin beklediği ortalama/sapma değerleri kullanılır. Örnek akış: görüntüyü canvas’a çiz, getImageData ile veriyi al, Float32Array’e yaz ve new Tensor('float32', data, [1,3,640,640]) oluştur. Ardından await session.run({ images: inputTensor }) ile çıktıları alabilirsiniz.

YOLOv8 ONNX çıkışında genellikle [1, N, 84] benzeri bir matris döner (ilk 4 değer kutu, takip eden skorlar/sınıflar). Sonuçları yorumlarken skor eşiğini (örneğin 0.25) ve IoU tabanlı NMS adımını uygulayın. Basit bir döngü ile her satırı okuyup en yüksek sınıf skorunu, kutu koordinatlarını ölçekleyerek orijinal görüntü boyutuna geri projekte edebilirsiniz.

Performans ve Optimizasyon İpuçları

Isınma (warm-up): Uygulama açılışında bir kez sahte bir tensörle session.run yaparak JIT derleme/önbellek süreçlerini tetikleyin. Bu, ilk gerçek karedeki gecikmeyi ciddi ölçüde azaltır.

WASM geri dönüşü: WebGPU desteklenmeyen cihazlarda otomatik olarak WASM’a düşmek kullanıcı kapsamını artırır. executionProviders: ['webgpu', 'wasm'] sıralaması pratik bir stratejidir.

Kantizasyon ve hafif modeller: INT8 kantize edilmiş ONNX modelleri bellek ve bant genişliği tüketimini düşürür. Eğer doğruluk kabul edilebilir seviyede kalıyorsa yolov8n veya yolov8s gibi küçük türevleri tercih edin.

Web Worker / OffscreenCanvas: Ön işleme ve NMS’i Web Worker’a taşıyarak ana iş parçacığını serbest bırakabilir, kare atlamalarını azaltabilirsiniz. Destek varsa OffscreenCanvas ile piksel işlemlerini işçi tarafında yapın.

Toplu işleme ve kadans kontrolü: Canlı kamera akışında her kareyi çalıştırmak yerine zamanlayıcıyla kadansı sınırlayın (ör. 30 FPS yerine 15 FPS). Sabit görüntü yükleme senaryolarında, aynı anda birden fazla resmi işlemek yerine küçük partiler halinde ilerleyin.

Bellek yönetimi: Tekrar kullanılan tensör ve arabellekleri yeniden oluşturmak yerine mümkün olduğunca yeniden kullanın. Büyük Float32Array tahsislerinden kaçınmak çöp toplayıcı baskısını azaltır.

Sık Karşılaşılan Hatalar ve Çözümler

GPUUnavailableError: Tarayıcıda chrome://flags altında WebGPU kapalı olabilir veya sayfa HTTPS üzerinden servis edilmiyor olabilir. Yerel geliştirme için localhost genellikle güvenilir sayılır.

Model uyumsuzluğu: ONNX opset sürümü çok düşük/yüksek olduğunda düğümler çözümlenmeyebilir. Çoğu güncel senaryoda opset 12–13+ güvenlidir; export sırasında opseti açıkça belirtin.

Çapraz kaynak sorunları: Model dosyaları farklı bir origin’den yükleniyorsa CORS başlıklarını doğru ayarlayın. Üretimde model ve varlıkları aynı domain/CDN kökünden sunmak en pratik yoldur.

Sonuç

WebGPU ve ONNX Runtime Web ile YOLOv8’i tarayıcıda çalıştırmak, gerçek zamanlı nesne tanımayı istemci tarafında güvenli ve hızlı bir şekilde sunmanıza olanak verir. Doğru ön işleme, hafif model seçimi ve ısınma/optimizasyon teknikleri ile orta seviye cihazlarda bile akıcı deneyim elde edebilirsiniz. Bu yaklaşım; gizlilik, ölçeklenebilirlik ve kullanıcı deneyimi açısından modern web uygulamalarına güçlü bir kapı aralıyor. Birkaç küçük adımla siz de modelinizi WebGPU üzerinde hayata geçirebilirsiniz.