- Ternlight, sunucu çağrısı olmadan tarayıcı içinde metin gömme ve benzerlik araması yaparak küçük istemci tarafı anlamsal aramayı hızlıca kurmayı sağlıyor
- Temel paket, motor ve ağırlıkları birleştirerek 7 MB, mini varyant ise 5 MB boyutunda ve GPU olmadan CPU üzerinde çalışıyor
@ternlight/base kurulduktan sonra embed ve similar içe aktarılıp 3 satır seviyesinde anlam tabanlı arama akışı kurulabiliyor
- Örnek çağrı, tarif listesindeki en iyi 3 sonucu sıralıyor; yaklaşık 5 ms ve ağ çağrısı olmaması özellikle vurgulanıyor
- React doküman arama demosunda kullanıcı soru girdiğinde arama tarayıcıda yapılıyor ve bunu 5 MB katmanındaki @ternlight/mini çalıştırıyor
Tarayıcı içinde tamamlanan gömme
- Ternlight, “7 MB’lık gömme modeli” söylemiyle metni milisaniyeler içinde gömüyor ve sunucu çağırmıyor
-
Çalışma özellikleri
- API çağrısı yok
- Motor + ağırlıklar: 7 MB
- mini varyant: 5 MB
- hızlı gömme: yaklaşık 5 ms
- yalnızca CPU, GPU yok
Kurulum ve kullanım örneği
- Tek bir npm paketi olarak sunuluyor; ayrı model indirme adımı veya sunucu olmadan kullanılabiliyor
- Kurulum komutu şöyle
npm install @ternlight/base
@ternlight/base içinden embed ve similar alınarak anlam tabanlı arama çalıştırılıyor
import { embed, similar } from '@ternlight/base';
similar('easy weeknight dinner ideas', recipes, { topK: 3 });
// → ranked matches · ~5 ms · zero network
- React doküman arama demosunda kullanıcı soru girdiğinde arama tarayıcıda yapılıyor ve @ternlight/mini 5 MB katmanı tarafından çalıştırılıyor
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.