Ternlight - Tarayıcıda (WASM) çalışan 7MB gömme modeli
(ternlight-demo.vercel.app)- Sunucu çağrısı olmadan tarayıcı içinde metin gömme ve benzerlik araması yaparak anlamsal (semantic) aramayı hızlıca kurmayı sağlar
- GPU olmadan yalnızca CPU ile çalışır; varsayılan paket, motor ve ağırlıklar birlikte 7MB, mini ise 5MB
- Motor, model ve BERT tokenizer tek bir
.wasmdosyasında birleştirilmiştir; postinstall ya da çalışma zamanında fetch gerekmez all-MiniLM-L6modelinden BitNet b1.58 tarzı kuantizasyon farkındalıklı eğitim (QAT) uygulanarak damıtılmıştır@ternlight/basekurulduktan sonraembedvesimilariçe aktarılarak 3 satır kodla semantic search akışı kurulabilir- 30× sıkıştırma sağlarken doğruluk kaybı düşük kalır; ağ gidiş-dönüşü olmadan gizlilik, çevrimdışı ve edge arama mümkün olur
ternlight - tarayıcının içinde tamamlanan embedding
- 5–7MB WebAssembly bundle olarak sunulan bir semantic embedding aracıdır; motor + model + tokenizer tek dosyada yer alır ve CPU üzerinde embedding araması yapar
- Metni milisaniyeler içinde embedding'e dönüştürür ve sunucu çağrısı yapmaz
- Aynı API ile iki katman sunar; boyut/kalite dengesine göre seçim yapılabilir
@ternlight/base— kalite katmanı (7MB wire, embedding başına yaklaşık 5ms)@ternlight/mini— küçük ve hızlı katman (5MB wire, embedding başına yaklaşık 2.5ms)
Temel API
- Tek bir primitive: string → 384 boyutlu L2 normalize Float32Array döndürür
embed,cosineSim,similarolmak üzere üç fonksiyon sunarcosineSim(embed('reset my password'), embed('I forgot my password'))→ 0.88similar, korpus üzerinde en yakın komşu aramasını destekler vetopKbelirtilebilir- Örnek: 'I want my money back' arandığında 'Refunds: how to get your money back' (sim 0.70) ve 'Update your billing address' (sim 0.24) döner
- Node ≥ 18, tarayıcı (bundler üzerinden), Cloudflare Workers, Vercel Edge, Deno ve Bun üzerinde çalışır; ortama uygun yükleyiciye otomatik yönlendirme yapar
Tasarım ilkeleri
all-MiniLM-L6üzerinden damıtılmış ve BitNet b1.58 tarzı kuantizasyon farkındalıklı eğitim uygulanmıştır; üç tasarım seçimiyle birkaç MB boyut elde edilir-
Üçlü ağırlıklar (Ternary weights)
- Tüm ağırlıklar
-1,0,+1değerlerinden biridir; böylece çıkarım toplama ve çıkarma ile yapılır - Model baştan itibaren üçlü model olarak eğitildiği için kalite korunur
- Tüm ağırlıklar
-
Tek bundle (One bundle)
- Model + BERT tokenizer + motor tek bir
.wasmiçine entegredir - postinstall aşaması ya da çalışma zamanında fetch yoktur
- Model + BERT tokenizer + motor tek bir
-
SIMD çıkarım motoru
- Elle yazılmış Rust kodu WASM SIMD olarak derlenmiştir
- Toplama/çıkarma işlemleri CPU vektör komutlarını kullanır
Performans metrikleri
- Tüm sayılar yayınlanan int4 build üzerinden ölçülmüştür (M serisi Mac, Node/V8)
-
@ternlight/mini
- Wire size (gzip wasm): 5.0MB, Latency (p50): 2.5ms
- Throughput (tek iş parçacığı): yaklaşık 400 emb/s
- Spearman (öğretmene göre): 0.820, Retrieval (SciFact NDCG@10): 0.439
- Mimari: 2-layer · d_model=256 · 4 heads, yaklaşık 9.5M parametre
-
@ternlight/base
- Wire size (gzip wasm): 7.2MB, Latency (p50): 5.1ms
- Throughput (tek iş parçacığı): yaklaşık 195 emb/s
- Spearman (öğretmene göre): 0.844, Retrieval (SciFact NDCG@10): 0.465
- Mimari: 2-layer · d_model=384 · 6 heads, yaklaşık 15.4M parametre
-
Ortak özellikler
- Çıktı: 384 boyutlu L2 normalize
- Maksimum girdi: 128 token (yaklaşık 95 kelime)
- Kuantizasyon: üçlü ağırlıklar · int4 embedding
Cihaz üstü embedding kullanım alanları
-
Yazarken arama (Search-as-you-type)
- Kullanıcı yazmayı bitirmeden sonuç gösterir; her türlü ağ gidiş-dönüşünden daha hızlıdır
-
Gizlilik hassasiyeti olan uygulamalar
- Sorgular ve belgeler cihazdan çıkmaz; veri işleme sözleşmesi veya sızıntı riski yoktur
-
Çevrimdışı öncelikli uygulamalar
- Tarayıcı uzantıları, Obsidian eklentisi, masaüstü uygulamaları
-
Edge runtime uygulamaları
- Cloudflare Workers, Deno Deploy, Vercel Edge üzerinde embedding, istek işleyiciyle aynı yere yerleştirilir; ayrı bir çıkarım servisini çağırmak gerekmez
-
Edge cihazları ve IoT donanımı
- Raspberry Pi, tek kartlı bilgisayarlar, endüstriyel ağ geçitleri, kiosklar
- Toplama/çıkarma işlemleri ARM çekirdeklerinde verimli çalıştığı için GPU ya da NPU gerekmez
-
Statik siteler
- Jekyll, Hugo, Astro ile model bundle'ın yanında dağıtılır; backend olmadan semantic search çalışır
Kurulum ve kullanım örneği
- Tek bir npm paketi olarak sunulur; ayrıca model indirme adımı ya da sunucu gerekmeden kullanılabilir
- Kurulum komutu şöyledir
npm install @ternlight/base @ternlight/baseiçindenembedvesimilaralınarak anlam tabanlı arama çalıştırılırimport { embed, similar } from '@ternlight/base'; similar('easy weeknight dinner ideas', recipes, { topK: 3 }); // → ranked matches · ~5 ms · zero network
Dayandığı açık kaynaklar ve lisans
- BitNet b1.58 (Ma et al., Microsoft Research, 2024) — üçlü ağırlık eğitimi için mimari araştırma
bitlinear— BitLinear'ın PyTorch referans uygulaması; eğitim sırasında doğrudan kullanılmıştır (bitlinear==2.4.6) ve Rust çıkarım motoru ileri yayılım işlemlerini birebir yansıtırsentence-transformers/all-MiniLM-L6-v2— öğrenci modelin damıtıldığı öğretmen model- Lisans: MIT
1 yorum
Hacker News yorumları
Hobi projesi olarak tarayıcıda işe yarar bir model çalıştırmak istediğim için MiniLM’den küçük bir cümle kodlayıcı damıttım ve ternary quantization-aware training uyguladım.
Çıkarım motorunu da kendim yazıp Rust → WASM SIMD olarak dağıttım.
Bu bir LLM değil, embedding modeli; metin verdiğinizde 384 boyutlu bir vektör çıkarıyor ve iki vektörün kosinüs benzerliğiyle metinlerin ilişkisini değerlendiriyor. Örneğin "reset my password" ile "I forgot my password" 0.88 gibi bir değer veriyor.
Anlam tabanlı arama, FAQ/niyet eşleştirme ve kümeleme için kullanılabilir; cihaz içinde çalıştığı için API’ye bağımlı olmadan, giriş yapılır yapılmaz hızlıca semantik arama yapılabiliyor.
Demo, 2 bin React dokümanını tamamen cihaz içinde arıyor: https://ternlight-demo.vercel.app
npm’de iki kademe var: @ternlight/base (7MB, embedding başına yaklaşık 5ms, daha iyi embedding’ler) ve @ternlight/mini (aktarımda 5MB, embedding başına yaklaşık 2.5ms); Node ve tarayıcı için paketlenmiş.
Depoda teknik ayrıntılar, MIT lisansı ve eğitim pipeline’ı yer alıyor: https://github.com/soycaporal/ternlight
Cihaz içi embedding’in gerçekten yararlı olup olmadığını ve hangi kullanım senaryoları olduğunu merak ediyorum.
Kullanıcı "pancake" girdiğinde, açıkça "pancake = crêpe" sözlük girdisi yazmadan crêpe’i buldurmaya yardımcı olup olmayacağını merak ediyorum.
Doğru anladıysam kütüphane başta 5MB’ı bir kez indiriyor, sonrasında da şu anda Fuse.js’i kullandığım gibi kullanılan bir yapı mı, onu da merak ediyorum.
İngilizce dışındaki dilleri ne kadar iyi işlediğini ve OpenStreetMap etiket wiki’siyle eğitilip eğitilemeyeceğini de bilmek isterim.
Başka ultra küçük embedding modelleriyle bir karşılaştırma var mı merak ediyorum. MiniLM-L6’dan başlamanın nedeni aynı sınıfta özellikle iyi bir model olması mı, bunu anlamak zor; çünkü verilen metrik yalnızca "Retrieval (SciFact NDCG@10)".
Yine de iddia edilen performanstan epey farklı: i5-4570 üzerindeki Firefox’ta saniyede 400 değil, yalnızca saniyede 35 embedding alıyorum. SIMD olmayan yola düşen bir sorun olup olmadığından şüpheleniyorum; yerel Rust binary’sini de deneyeceğim.
Harika, ama landing page’e demoyu başlatan bir düğme koymak iyi olurdu. Web sayfasını açar açmaz fanın deliler gibi dönme sesi gelince epey irkildim.
Bunu Astro ya da genel amaçlı bir meta framework eklentisi haline getirip üretilen tüm HTML dosyalarını otomatik parse etse ve küçük bir embedding veritabanı oluştursa güzel olurdu.
Frontend tarafında bu lazy-load edilebilir; HNSW de chunk’lar halinde saklanıp arama sorgusu için gereken kısımlar yüklenebilir belki.
Örneğin https://pagefind.app/ benzeri, ama tamamen statik vektör araması sunan bir biçim.
Aradan aylar, yıllar geçtiği halde durum buysa, bu projeyi düzgün tamamlayacak kapasitenin eksik olduğuna dair bir işaret gibi görünüyor ve epey hayal kırıklığı yaratıyor. Hatta başvurduğum bir hibede o projeyi iyi adaylardan biri olarak önermiştim; onlar seçildi, ben elendim.
Bu alanda iyi bir çözüm bilen varsa ya da SQLite-vec konusunda yanılıyorsam, bana söylemesini isterim. Bizim SSG’de şimdilik birkaç ay başka altyapı üzerinde çalışıp, o zamana kadar tamamlanmamış olursa kendimiz yapmaya neredeyse karar verdik.
Daha önce burada gördüğüm DuckDB HNSW arama projesine oldukça güzel bir ek özellik olabilir: https://github.com/jasonjmcghee/portable-hnsw
Statik olarak barındırılan Parquet dosyaları üzerinde HTTP range request kullanarak arama yapılması gerçekten ilginç.
Bunların, büyük şirketlerin kontrol etmediği daha açık ve dağıtık bir arama ekosistemine dönüşebileceğini düşünüyorum.
https://news.ycombinator.com/item?id=27016630
Bu gerçekten harika ve eskiden yapmak istediğim şeyin eksik parçası olabilir.
https://github.com/npiesco/absurder-sql kullanarak kaynak corpus’un tamamını tarayıcı içinde IndexedDB/SQLite olarak kalıcı saklayabilirsiniz.
Ardından https://weaviate.io/blog/chunking-strategies-for-rag gibi her şeyi önceden indekslemek yerine, Ternlight ile gerektiğinde embedding üretip cache’leyebilirsiniz.
Böylece yerel SQLite’ın FTS5/BM25’i ile Ternlight’ın semantik aramasını birleştiren Reciprocal Rank Fusion, yani hibrit arama da mümkün olur.
İyi iş çıkarılmış.
7MB diye tanıtılıyor ama 5MB’lık mini sürümü de var.
mini, içeride 384 yerine 256 elemanlı vektör kullanarak alanı azaltıyor ve sonunda uyumluluk için 384’e projekte ediyor gibi görünüyor.
Boyut üçte bir azalıyor ama kayıp doğrusal değil; daha küçük bir veri yolu kullanılsa bile bilgi kaybı üçte birden az görünüyor.
Güzel proje.
Daha önce benzer bir şey denemiştim: http://sol.quipu-strands.com/
Tarayıcı içinde bir embedding modeli yükleyip metni semantik olarak sıralamak istiyordum.
HuggingFace’ten ONNX ağırlıklarını (MPNet, MiniLM) aldım, Transformers.js ile embedding ürettim, ardından sayfa içinde pyodide ile çalışan scikit-learn kümeleyicisini kullandım. Her şey istemci tarafında çalışıyordu ve bunun kusursuz çalışmasına şaşırmıştım.
Demo epey tuhaf davranıyor. Örneğin "how to use typescript with createContext" aratınca üst sonuçlar yalnızca typescript maddeleri oluyor; benzerlik araması başarısız olmuş gibi görünüyor.
Teşekkürler. Yerel modeller bir gün gizlilik getirecek ve bu tür küçük embedding modelleri için çok uygun, harika bir kullanım senaryosu da zaten biliyorum: ürün veritabanında ucuz ve hızlı arama.
Benim durumumda CPU’ya dayanması da bir avantaj.
30 saniye süren embedding üretimini önceden yapıp tarayıcıya gönderebilir miyiz?
Sonrasında çıkarım hızlı ve iyi.