tarayıcıda yapay zeka etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
tarayıcıda yapay zeka etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

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.

24 Kasım 2025 Pazartesi

WebGPU ile Tarayıcıda Küçük Dil Modeli (LLM) Çalıştırma: Transformers.js ile Adım Adım Rehber

Tarayıcıda çalışan yapay zeka artık bir merak değil, gerçek bir ürün gerekliliği. WebGPU sayesinde GPU hızlandırmalı çıkarım, kullanıcı verisini sunucuya göndermeden, düşük gecikmeyle mümkün hale geldi. Bu rehberde, Transformers.js kullanarak tarayıcı içinde küçük bir dil modelini (LLM) nasıl çalıştırabileceğinizi adım adım anlatıyorum. Kurulumdan performans ayarlamalarına, gerçek dünyada dağıtıma kadar pratik bir yol haritası bulacaksınız.

Neden tarayıcıda LLM? Gizlilik (veri cihazdan çıkmıyor), offline senaryolar, anında yanıt, ölçeklenebilirlik (sunucu maliyetini uç cihazlara dağıtma) ve daha iyi kullanıcı deneyimi. Ayrıca WebGPU, CPU tabanlı WASM’a kıyasla büyük hız artışları sunuyor.

Gereksinimler ve hazırlık

- Güncel bir Chrome/Edge sürümü (WebGPU varsayılan olarak açık). Safari’de güncel sürümlerde kısmi destek mevcut, Firefox’ta ise Nightly/ayrık yapılandırmalar gerekebilir.
- HTTPS üzerinden sunum (yerelde http://localhost kabul edilir).
- GPU destekli bir cihaz (entegre grafikler de iş görür, ancak ayrık GPU belirgin fark yaratır).

Proje iskeleti: Hızlı başlamak için bir ön yüz iskeleti oluşturun. Örneğin Vite kullanıyorsanız: npm create vite@latest webgpu-llm, ardından proje klasörüne geçip npm install ile bağımlılıkları kurun. Ardından @xenova/transformers paketini ekleyin: npm i @xenova/transformers.

Model seçimi ve indirme stratejisi

Tarayıcıda çalıştırılacak modelin boyutu kritik. 0.1B–1B parametre aralığındaki, Transformers.js uyumlu ve WebGPU desteği eklenmiş dönüştürülmüş (ONNX tabanlı) modelleri tercih edin. Hugging Face üzerinde “Transformers.js”, “onnx” ve “text-generation” etiketlerine bakın. Küçük ama iyi ayarlanmış instruction modelleri, sohbet ve kısa metin üretiminde tatmin edici sonuç verir.

İpucu: İlk açılışta model dosyaları indirileceği için yükleme süresini yönetmek gerekir. Uygulamada bir önbellek stratejisi kullanın (Service Worker ile Cache Storage) ve kullanıcıya ilerleme çubuğu gösterin. Dosyaları parça parça (chunk) indirmek ve CDN üzerinden sunmak açılışı hızlandırır.

Transformers.js ile temel akış

- Yükleme: import ile pipeline fonksiyonunu içeri alın.
- Boru hattı: const generator = await pipeline('text-generation', MODEL_ADI, { device: 'webgpu' }). Burada device olarak webgpu vererek GPU hızlandırmayı etkinleştirirsiniz. Uygun olmayan tarayıcılarda otomatik olarak WASM’a düşebilir.
- Çıkarım: await generator('Merhaba, bugün neler öğrenelim?', { max_new_tokens: 64, temperature: 0.7, top_p: 0.9 }). Parametrelerle çıktı kalitesi ve hız arasında denge kurun.

Akıcı deneyim için akış (stream) modu: Token bazlı akış kullanıcıya “yazıyor” hissi verir. UI tarafında bir akış tamponu tutup yeni token geldikçe metni güncelleyin. İlk yanıtın ortaya çıkma süresi (TTFT) kullanıcı memnuniyeti için kilit metriklerden biridir.

Web Worker ile ana iş parçacığını özgür bırakın

GPU çağrıları ve token üretimi zaman zaman ana iş parçacığını meşgul edebilir. Bir Web Worker oluşturup modeli Worker içinde açın. UI’dan gelen prompt’ları postMessage ile Workera gönderin, tokenları da mesaj olarak geri alın. Bu sayede animasyonlar ve girişler takılmaz.

Not: Çok iş parçacıklı WASM’a düşülen senaryolarda SharedArrayBuffer gerekebilir. Bunun için sunucuda Cross-Origin-Opener-Policy: same-origin ve Cross-Origin-Embedder-Policy: require-corp başlıklarını ayarlayarak cross-origin isolation sağlayın.

Performans ve optimizasyon ipuçları

- Model boyutu ve quantization: INT8 veya 4-bit nicemleme bellek kullanımını ve yükleme süresini düşürür. Küçük modellerde kalite düşüşü sınırlıdır, özellikle kısa yanıtlar için.
- max_new_tokens ve repetition_penalty: Gereksiz uzun cevapların önüne geçer, hız kazandırır.
- Top-p/top-k/temperature: Çeşitlilik ve deterministiklik dengesini kurun. Üretimde genellikle temperature 0.6–0.9, top_p 0.8–0.95 iyi başlama noktalarıdır.
- Önbellek (KV cache): Destekleyen modellerde tekrar token üretiminde hesaplama azaltılır.
- Model varlıklarını yakına alın: Bölgesel CDN veya edge cache ile soğuk başlatmayı kısaltın.
- Lazy ve background preload: Uygulama açılır açılmaz arka planda model dosyalarını ısıtın; kullanıcı prompt yazana kadar yükleme tamamlanmış olur.

Donanım ve tarayıcı farklılıkları: iGPU’larda bellek bant genişliği sınırlıdır; daha küçük model + agresif quantization seçin. Mobil tarayıcılarda enerji tüketimi ve termal kısıtlar nedeniyle kısa oturumları hedefleyin. Masaüstü dGPU’larda ise 1B sınıfı modellere kadar makul akış hızları elde edilebilir.

Hata ayıklama ve yayına hazırlık

- WebGPU yok: Özellik algılama yapın ve kullanıcıya “Hızlandırma devre dışı, CPU modunda çalışıyor” mesajı gösterin.
- Büyük dosya indirme hataları: İndirme yönetimi, yeniden deneme ve parça doğrulaması (checksum) ekleyin.
- Hafıza tavanları: Tarayıcı sekmesinin bellek sınırını aşmayın; model boyutunu ve eşzamanlı çıkarımı sınırlayın.
- Gizlilik: Tüm çıkarım yerelde; telemetri topluyorsanız kullanıcıdan açık onay alın.
- UI/UX: Net yükleme durumu, iptal düğmesi, “Yeniden dene” ve token sayacı gerçek kullanıcı deneyimini iyileştirir.

Gerçek dünyada, bir “akıllı arama” veya “özetleyici” aracı yapmak istiyorsanız RAG (Retrieval Augmented Generation) ile tarayıcı içi gömlemeler (embeddings) üretip, küçük bir vektör dizini (ör. IndexedDB üzerinde) tutabilirsiniz. Arama sonucunu prompt’a enjekte ederek küçük bir modeli, büyük bir modelin doğruluğuna yaklaştırmak mümkün olur.

Özetle: WebGPU + Transformers.js, tarayıcıda LLM çalıştırmayı pratik ve üretime uygun hale getiriyor. Doğru model seçimi, iyi bir önbellekleme stratejisi ve Worker tabanlı mimari ile ilk yanıt süresini düşürür, akıcı bir sohbet deneyimi sunarsınız. Küçük başlayın, kullanıcı geri bildirimlerini toplayın ve gerektiğinde model boyutunu artırın. Bugün tarayıcıda çalışan bir yapay zeka prototipi çıkarmak, artık saatler meselesi.

23 Kasım 2025 Pazar

Tarayıcıda WebGPU ile Yerel LLM Çalıştırma: WebLLM Kurulum Rehberi ve Performans İpuçları

Giriş

Tarayıcıda WebGPU desteğinin olgunlaşması, büyük dil modellerini (LLM) tamamen istemci tarafında çalıştırmayı pratik hale getirdi. Bu rehberde, WebLLM kullanarak Chrome/Edge gibi modern tarayıcılarda internet bağlantısı olmadan çalışan, gizliliğe duyarlı ve hızlı bir sohbet asistanını adım adım kuracağız. Amaç, hem geliştirici deneyimini sade tutmak hem de performans, gizlilik ve SEO açısından en iyi uygulamaları özetlemek.

Ön Gereksinimler

- Güncel bir tarayıcı: Chrome 113+ veya Edge 113+ önerilir. Firefox’ta WebGPU Nightly ile etkinleştirilebilir; macOS’te Safari 17+ destek sunar.

- Güncel ekran kartı sürücüleri: Windows’ta D3D12, Linux’ta Vulkan, macOS’te Metal backend ile WebGPU çalışır. Eski sürücüler “uygun GPU adaptörü bulunamadı” hatasına yol açabilir.

- Node.js 18+ (Vite veya benzeri bir bundler kullanacağız). Alternatif olarak CDN ile basit bir HTML sayfası da kullanılabilir.

Neden WebLLM?

WebLLM, MLC ekosisteminin tarayıcıya optimize edilmiş LLM çalışma zamanı. Avantajları:

- Gizlilik: Veriler cihazı terk etmez. Kurumsal ve kişisel gizlilik gerektiren iş akışları için idealdir.

- Kurulum Kolaylığı: Sunucu yok; CDN veya statik hosting ile dağıtım yapılabilir.

- Performans: 4-bit gibi quantization seçenekleriyle orta segment GPU’larda dahi akıcı deneyim sağlanır.

Hızlı Başlangıç: Vite + WebLLM

Aşağıdaki adımlar React örneğiyle gösterilmiştir; vanilla veya başka framework’ler de benzer şekilde ilerler.

1) Proje oluşturma:

npm create vite@latest webllm-demo -- --template react-ts
cd webllm-demo
npm install

2) Paketleri ekleme:

npm i @mlc-ai/web-llm

3) Basit bir sohbet bileşeni oluşturma (src/App.tsx):

import { useEffect, useState } from "react";
import { CreateMLCEngine, InitProgressReport } from "@mlc-ai/web-llm";

export default function App() {
  const [engine, setEngine] = useState<any>(null);
  const [loading, setLoading] = useState("Model hazırlanıyor...");
  const [input, setInput] = useState("");
  const [messages, setMessages] = useState([{ role: "system", content: "Yardımcı asistan." }]);

  useEffect(() => {
    const init = async () => {
      const model = "Llama-3-8B-Instruct-q4f32_1-MLC"; // Donanımınıza göre daha küçük bir model seçebilirsiniz.
      const eng = await CreateMLCEngine(model, {
        initProgressCallback: (p: InitProgressReport) => {
          setLoading(`${Math.round(p.progress * 100)}% - ${p.text}`);
        },
      });
      setEngine(eng);
      setLoading("");
    };
    init();
  }, []);

  const send = async () => {
    if (!engine || !input.trim()) return;
    const next = [...messages, { role: "user", content: input }];
    setMessages(next);
    setInput("");
    const out = await engine.chat.completions.create({
      messages: next,
      temperature: 0.7,
      max_tokens: 256,
    });
    const reply = out.choices[0].message.content;
    setMessages([...next, { role: "assistant", content: reply }]);
  };

  return (
    <div style={{ padding: 16 }}>
      <h3>WebGPU + WebLLM Yerel Sohbet</h3>
      {loading && <p>{loading}</p>}
      {!loading && (
        <>
          <div style={{ whiteSpace: "pre-wrap", marginBottom: 12 }}>
            {messages.map((m, i) => (
              <div key={i}><b>{m.role}:</b> {m.content}</div>
            ))}
          </div>
          <input
            value={input}
            onChange={(e) => setInput(e.target.value)}
            placeholder="Bir soru yazın..."
            style={{ width: "70%" }}
          />
          <button onClick={send} style={{ marginLeft: 8 }}>Gönder</button>
        </>
      )}
    </div>
  );
}

4) Geliştirme sunucusunu çalıştırma:

npm run dev

İlk başlatmada model dosyaları indirileceği için yükleme biraz sürebilir. Tarayıcı konsolunda ilerleme yüzdesi ve ayrıntıları görürsünüz.

Model Seçimi ve Bellek

Model adı genelde “-MLC” soneki ve quantization içeren bir desen izler: örn. q4f32_1 gibi. 4-bit seçenekler performans/bellek dengesini iyi kurar. 7–8B parametreli Llama 3 veya Phi türevleri, modern entegre GPU’larda dahi çalışabilir. Yüksek VRAM’e sahipseniz daha büyük varyantlar deneyebilirsiniz.

Performans İpuçları

- WebGPU f16: Çoğu cihazda varsayılan olarak etkinleşir; mümkünse f16 yolunu kullanan modelleri tercih edin.

- Maksimum token: Yanıt başına max_tokens değerini gereksiz büyütmeyin; daha kısa yanıtlar daha hızlı üretilecektir.

- İlk yükleme önbelleği: Statik sunucuda HTTP cache ve Service Worker kullanarak model dosyalarını yerel önbelleğe alın; tekrar ziyaretlerde soğuk başlangıç azalır.

- İçerik güvenliği: Üretim ortamında COOP/COEP başlıkları ve sıkı CSP ile hem performans hem de güvenlikte tutarlılık sağlayın.

Güvenlik ve Gizlilik

Tarayıcıda çalışan bir LLM, sohbet içeriklerini dış servislere göndermediği için hassas verilerle çalışırken büyük avantaj sağlar. Yine de kullanıcı verilerini kalıcı olarak saklamadan önce açık rıza isteyin ve localStorage/IndexedDB kullanımını minimal tutun.

Karşılaşılan Yaygın Hatalar

- “No suitable GPU adapter”: Tarayıcınızı ve GPU sürücülerinizi güncelleyin. Linux’ta Vulkan, Windows’ta D3D12 desteğinin aktif olduğundan emin olun.

- Yavaş ilk yükleme: Modeli daha küçük bir varyantla değiştirin (ör. 4-bit), CDN/önbellek ayarlarınızı kontrol edin.

- Tarayıcı desteği: Kurumsal kısıtlı cihazlarda WebGPU devre dışı olabilir; BT politikalarını gözden geçirin veya alternatif tarayıcı deneyin.

SEO İçin Küçük Dokunuşlar

Başlık, meta açıklama ve alt başlıklarda “WebGPU”, “tarayıcıda LLM”, “WebLLM” gibi anahtar kelimeleri doğal akışta kullanın. İlk paragrafta hedef terimleri geçirip, alt başlıklarda soru bazlı ifadeler (ör. “Nasıl kurulur?”, “Hangi modeller hızlı?”) eklemek arama sonuçlarında tıklanma oranını artırır.

Sonuç

WebGPU, tarayıcıyı salt bir istemci olmaktan çıkarıp güçlü bir yerel AI yürütme katmanına dönüştürüyor. WebLLM ile dakikalar içinde çalışan bir sohbet asistanı kurabilir, kurumsal ortamlarda gizlilik avantajı sağlayabilir ve kullanıcılarınıza düşük gecikmeli deneyimler sunabilirsiniz. Küçük bir modelle başlayıp donanımınıza göre ölçeklenin; doğru quantization ve önbellekleme stratejileriyle fark edilir bir performans elde edeceksiniz.

14 Kasım 2025 Cuma

WebGPU ile Tarayıcıda Yapay Zeka: Transformers.js Kullanarak Yerel Metin Sınıflandırıcı Kurulumu

Özet

Tarayıcıda çalışan yapay zeka uygulamaları, veriyi cihazdan çıkarmadan işlemek ve sunucu maliyetlerini azaltmak için güçlü bir çözüm haline geldi. WebGPU sayesinde artık yalnızca WebAssembly (WASM) ile sınırlı değiliz; modern ekran kartlarının gücünü doğrudan JavaScript ile kullanabiliyoruz. Bu rehberde, Transformers.js kütüphanesi ile tek sayfalık bir uygulama geliştirerek WebGPU üzerinde yerel metin sınıflandırma (pozitif/negatif duygu analizi) kuracağız. Kod, hiçbir sunucu tarafı model barındırma olmadan çalışacak ve tarayıcı, modeli indirip IndexedDB üzerinde önbellekleyecek.

Neden WebGPU?

WebGPU, grafik ve hesaplama iş yüklerinde tarayıcıya modern bir düşük seviye API sunar. WASM ile CPU üzerinde çalışan modeller, bazen yeterli performansı yakalayamazken, WebGPU destekli ONNX Runtime Web ve Transformers.js kombinasyonu, önemli ölçüde hız kazandırır. Sonuç: daha düşük gecikme, daha akıcı kullanıcı deneyimi ve ölçeklenmesi kolay bir mimari.

Önkoşullar

- Güncel bir Chromium tabanlı tarayıcı (Chrome/Edge 113+). Çoğu sistemde WebGPU varsayılan olarak açıktır. Eğer kapalıysa chrome://flags üzerinden “Enable WebGPU” etkinleştirilebilir.

- Modern bir GPU ve güncel sürücüler önerilir. GPU yoksa, uygulama otomatik olarak WASM’e düşer (daha yavaş olabilir).

- Basit bir yerel sunucu. Örnek olarak python -m http.server 8000 veya npx serve . kullanabilirsiniz.

Proje Yapısı ve Temel Sayfa

Bir klasör oluşturun: webgpu-ai-demo/. İçine index.html adında bir dosya ekleyin ve aşağıdaki iskeleti yerleştirin. COOP/COEP başlıkları, çok iş parçacıklı WASM için önerilir; yerel geliştirmede meta etiketleriyle eşdeğeri sağlanabilir. Üretimde ise HTTP yanıt başlıklarını sunucuda ayarlayın.

Aşağıdaki kodu tek bir HTML dosyasında kullanabilirsiniz:

<!doctype html>
<html lang="tr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>WebGPU ile Metin Sınıflandırma</title>
  <meta http-equiv="Cross-Origin-Opener-Policy" content="same-origin">
  <meta http-equiv="Cross-Origin-Embedder-Policy" content="require-corp">
  <style>body{font-family:system-ui, Arial, sans-serif;max-width:800px;margin:40px auto;padding:0 16px}</style>
</head>
<body>
  <h1>WebGPU ile Tarayıcıda Duygu Analizi</h1>
  <textarea id="input" rows="6" style="width:100%" placeholder="Değerlendirilecek metni yazın..."></textarea>
  <br><br>
  <button id="analyze">Analiz Et</button>
  <pre id="log" style="background:#f6f8fa;padding:12px;white-space:pre-wrap">Hazırlanıyor...</pre>
  <script type="module">
    import { pipeline, env } from 'https://cdn.jsdelivr.net/npm/@xenova/transformers/dist/transformers.min.js';
    // WebGPU varsa kullan, yoksa WASM'e düş.
    const preferGPU = 'gpu' in navigator;  // navigator.gpu modern tarayıcılarda mevcuttur.
    const device = preferGPU ? 'webgpu' : 'wasm';
    // WASM fallback için iş parçacığı sayısı (COOP/COEP ile etkin çoklu iş parçacığı).
    env.backends.onnx.wasm.numThreads = Math.max(1, Math.min(4, (navigator.hardwareConcurrency||4)-1));
    const logEl = document.getElementById('log');
    const btn = document.getElementById('analyze');
    const input = document.getElementById('input');

    log('Model indiriliyor ve hazırlanıyor...');
    const classifier = await pipeline('text-classification', 'Xenova/distilbert-base-uncased-finetuned-sst-2-english', {
      device, quantized: true,
      progress_callback: x => log('İndiriliyor: ' + Math.round((x.progress||0)*100) + '%')
    });
    log('Hazır. Bir metin yazıp "Analiz Et"e basın.');

    btn.addEventListener('click', async () => {
      btn.disabled = true;
      const text = input.value.trim();
      if (!text) { log('Lütfen bir metin girin.'); btn.disabled = false; return; }
      log('Analiz ediliyor...');
      const output = await classifier(text, { topk: 2 });
      log(JSON.stringify(output, null, 2));
      btn.disabled = false;
    });

    function log(msg){ logEl.textContent = msg; }
  </script>
</body>
</html>

Çalıştırma

Proje klasörüne geçip basit bir sunucu açın. Örneğin Python kullanıyorsanız: python -m http.server 8000. Ardından tarayıcıdan http://localhost:8000 adresine gidin. İlk çalıştırmada model ağırlıkları indirileceği için bir miktar bekleme olabilir. Bu dosyalar IndexedDB üzerinde önbelleklenecek; bir sonraki açılışta çok daha hızlı başlayacaktır.

Performans İpuçları

- WebGPU: Kodda device: 'webgpu' geçiliyorsa GPU kullanılacaktır. Tarayıcınız ve ekran kartınız destekliyorsa belirgin hız kazanırsınız.

- Kuantizasyon: quantized: true seçeneğiyle 8-bit ağırlıklar kullanılır; indirme boyutu ve bellek tüketimi düşer, hız genellikle artar.

- Isınma (warm-up): Uygulama açıldığında boş bir metinle hızlı bir “ısınma” çağrısı yapmak, ilk gerçek isteğin gecikmesini azaltır.

- Çok iş parçacığı: WASM’e düşmeniz halinde COOP/COEP etkinse env.backends.onnx.wasm.numThreads ile çekirdek sayınıza göre değer belirleyin.

- Küçük modeller: Tarayıcı için küçük/orta boy modeller tercih edin. Daha büyük LLM’ler (ör. 7B) tarayıcıda pratik olmayabilir; sunucuya veya yerel native uygulamalara yönelin.

Hata Giderme

- “navigator.gpu tanımsız” uyarısı alıyorsanız tarayıcınızı güncelleyin veya WebGPU’yu flags üzerinden etkinleştirin. Bazı kurumsal politikalar WebGPU’yu devre dışı bırakabilir.

- “CORS/COEP/COOP” ile ilgili hatalarda sayfayı mutlaka bir HTTP sunucusundan servis edin. Üretimde, meta etiket yerine gerçek yanıt başlıklarını (COOP/COEP) sunucuda ayarlayın.

- Model indirme yavaşsa farklı bir ağa geçmeyi deneyin. İlk indirme bir kez yapılır; sonraki açılışlarda IndexedDB önbelleği devreye girer.

- Sonuçlar beklediğiniz gibi değilse Türkçe metinler için uygun bir modele geçebilirsiniz; Transformers.js ile Türkçe duygu analizi veya çok dilli modelleri deneyin.

Kısa Değerlendirme

Bu yaklaşım, uçtan uca gizlilik (metin cihazdan çıkmaz), anında ölçeklenebilirlik (sunucu GPU’su gerekmez) ve düşük gecikme gibi avantajlar sunuyor. Chrome ve Edge üzerinde WebGPU ile duyduğum hız artışı belirgin oldu; Safari ve Firefox tarafında ise deneysel destekler hızla olgunlaşıyor. Projenizde basit bir duygu analiziyle başlayıp, soru-cevap ya da özetleme gibi diğer görevler için hafif modellerle devam edebilirsiniz.

Sonuç

WebGPU ve Transformers.js, tarayıcıda çalışan modern yapay zeka uygulamalarını herkes için erişilebilir kılıyor. Bu yazıdaki örneği temel alarak kendi metin moderasyonu, kullanıcı geri bildirimi analizi veya içerik sınıflandırma araçlarınızı birkaç yüz satırlık kodla hayata geçirebilirsiniz. Performansı artırmak için kuantizasyon, uygun model seçimi ve önbellekleme stratejilerinden yararlanmayı unutmayı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.

2 Kasım 2025 Pazar

Tarayıcıda Yerel Yapay Zeka: WebGPU ve ONNX Runtime Web ile Görsel Sınıflandırma Nasıl Çalıştırılır?

Özet ve Neden Önemli?

Tarayıcıda çalışan yapay zeka, gizlilik, gecikme ve kullanıcı deneyimi açısından oyunun kurallarını değiştiriyor. WebGPU ile birlikte ONNX Runtime Web kullanarak bir görsel sınıflandırma modelini tamamen istemcide, yani kullanıcının cihazında çalıştırabilirsiniz. Böylece veriler sunucuya gönderilmez, ağ gecikmesi azalır ve uygulama çevrimdışı senaryolarda dahi işlevini sürdürür. Bu yazıda, sıfırdan bir ön yüz projesine WebGPU destekli ONNX Runtime Web ekleyerek, bir görüntüyü sınıflandırma adımlarını sade ama teknik açıdan tatmin edici bir şekilde ele alacağız.

Gereksinimler ve Mimari

WebGPU, modern tarayıcılarda donanım hızlandırmalı hesaplamaya erişmek için tasarlanmış, Vulkan/Metal/DX12 benzeri bir grafik ve hesap arayüzüdür. Chrome ve Edge’de kararlı; Safari’de Technology Preview; Firefox’ta ise genellikle bayrakla etkinleştirilmektedir. ONNX Runtime Web (kısaca ort), ONNX formatındaki modelleri tarayıcıda WASM, WebGL veya WebGPU üzerinde çalıştırır. Mimari şu şekilde işler: model dosyası (örn. mobilenetv3.onnx), tarayıcıya indirilir; preprocess aşamasıyla görüntü tensöre dönüştürülür; WebGPU yürütücüsü ile ileri besleme yapılır; sonuçlar postprocess ile insan tarafından anlaşılır etiketlere çevrilir.

Kurulum ve Dosya Yapısı

Basit bir yapı için bir HTML dosyası (index.html), bir JavaScript dosyası (app.js) ve model/etiket dosyalarınız (models/mobilenetv3.onnx, labels.txt) yeterlidir. Paket yöneticisi kullanacaksanız onnxruntime-web paketini ekleyebilir veya CDN üzerinden import edebilirsiniz. Yerel geliştirme için npm create vite@latest ile hafif bir iskelet kurup, npm i onnxruntime-web komutuyla kütüphaneyi dahil edebilirsiniz. Veya basit bir HTML sayfasında <script type="module"> ile ESM import yapabilirsiniz.

WebGPU’nun Etkinliği ve Geri Dönüş Planı

Önce tarayıcının WebGPU desteğini kontrol edin: if ('gpu' in navigator). ONNX Runtime Web oturumunu başlatırken yürütücüleri öncelik sırasına koyabilirsiniz: executionProviders: ['webgpu', 'webgl', 'wasm']. Böylece WebGPU yoksa WebGL, o da yoksa WASM’a otomatik düşülür. Bu yaklaşım, geniş bir cihaz/tarayıcı yelpazesini hedeflemenizi sağlar.

Modeli Yükleme ve Oturum Oluşturma

Bir InferenceSession başlatırken, graphOptimizationLevel ve preferredOutputLocation gibi seçeneklerle performansı iyileştirebilirsiniz. Örnek bir akış şu şekildedir: modeli fetch ile indirip await ort.InferenceSession.create çağırarak oturumu hazırlayın; etiket dosyasını (labels.txt) satır satır belleğe alın; giriş tensörünü uygun boyuta (ör. 224x224), kanal sırasına ve normalizasyona getirip Float32Array içine yerleştirin; ardından session.run(feeds) ile çıktı alın.

Ön İşleme: Doğru Tensör, Doğru Sonuç

Ön işleme aşaması, modelden iyi sonuç almak için kritiktir. Tipik olarak aşağıdaki adımları uygularsınız: resmi canvas üzerinde 224x224’e yeniden boyutlandırma; RGB kanallarını çıkarma; piksel değerlerini 0–1 aralığına ölçekleme; modelin beklediği ortalama ve standart sapma ile normalizasyon; kanal sırasını HWC’den CHW’ye çevirme. Son olarak tensörü new ort.Tensor('float32', data, [1, 3, 224, 224]) şeklinde oluşturursunuz.

Çıktının İşlenmesi ve Etiketleme

Modelden alınan ham skorları (logit) softmax ile olasılığa çevirmek, ardından en yüksek değere sahip sınıfı ve olasılığını bulmak temel adımdır. Etiket dosyanızla eşleyip kullanıcıya en olası ilk üç sonucu gösterebilirsiniz. Basit bir kullanıcı arayüzü için bir dosya yükleme alanı ve sonuç listesini güncelleyen kısa bir fonksiyon yeterlidir.

Performans İpuçları

1) WebGPU seçimi: Cihaz destekliyse WebGPU belirgin hız sağlar. 2) Kantizasyon: INT8 veya FP16 kantize modeller daha küçük ve hızlıdır; doğruluk/performans dengesini ölçün. 3) Toplu işleme: Birden fazla görseli ardışık yerine mini-batch olarak çalıştırmak throughput’u artırabilir. 4) WASM ayarları: Geri dönüş halinde ort.env.wasm.numThreads gibi ayarlarla CPU tarafını hızlandırın. 5) IO binding: Gelişmiş senaryolarda giriş/çıkışları GPU belleğinde bağlamak kopyalama maliyetini düşürür. 6) Önyükleme: İlk yüklemede modeli önbelleğe almak (Service Worker, HTTP caching) deneyimi iyileştirir.

Uyumluluk ve Sorun Giderme

Eğer “WebGPU desteklenmiyor” uyarısı alırsanız tarayıcınızı güncelleyin veya geçici olarak WebGL/WASM geri dönüş yolu kullanın. CORS hataları için model ve etiket dosyalarınızı aynı origin’den servis edin veya uygun başlıkları ayarlayın. Bozuk sonuçlar genelde ön işleme hatalarından kaynaklanır: kanal sırası (CHW vs HWC), normalizasyon değerleri ve giriş boyutunu iki kez kontrol edin. Performans düşükse geliştirici araçlarında GPU işlem kullanımını izleyin; entegre GPU’larda FP16/INT8 kazancı değişebilir.

Gizlilik ve Güvenlik

Yerel çıkarım, görsellerin cihazdan çıkmaması sayesinde gizliliği güçlendirir. Yine de kullanıcı izni olmadan dosya okuma, kalıcı depolama veya kamera erişimi gibi API’ler kullanılmamalıdır. Büyük modeller için indirme boyutunu küçültmek (sıkıştırma, kantizasyon) hem veri kullanımı hem de ilk yükleme süresini azaltır.

Sonuç

WebGPU ve ONNX Runtime Web ile tarayıcıda görsel sınıflandırma, artık bir prototipten öteye geçmiş durumda. Doğru model, sağlam ön işleme ve akıllı geri dönüş stratejileriyle, yüksek performanslı ve gizliliğe saygılı deneyimler oluşturabilirsiniz. Küçük bir demoyla başlayın; ardından etkileşimli görsel arama, canlı kamera üzerinde etiketleme veya tamamen çevrimdışı çalışan PWA gibi senaryolara genişleyin. Gelecek, kullanıcıların cihazında—ve siz bugün bunun temelini atabilirsiniz.

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.

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.