GoktugD commited on
Commit
6bf37b5
·
verified ·
1 Parent(s): 61fe966

Refresh DUSUNEN branding, releases and measured evidence

Browse files
Files changed (7) hide show
  1. README.md +21 -4
  2. corpus.json +122 -0
  3. embeddings-report.json +9 -0
  4. embeddings.json +0 -0
  5. index.html +44 -18
  6. validation.json +12 -0
  7. worker.js +36 -0
README.md CHANGED
@@ -1,10 +1,27 @@
1
  ---
2
  title: DUSUNEN Vector Lab
3
- emoji: 📈
4
- colorFrom: blue
5
- colorTo: gray
6
  sdk: static
 
7
  pinned: false
 
 
 
 
 
 
 
 
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
1
  ---
2
  title: DUSUNEN Vector Lab
3
+ emoji: 🧭
4
+ colorFrom: indigo
5
+ colorTo: blue
6
  sdk: static
7
+ app_file: index.html
8
  pinned: false
9
+ license: mit
10
+ short_description: Turkish Matryoshka retrieval from 384 to 32 dimensions
11
+ models:
12
+ - GoktugD/DUSUNEN-Pusula-118M-v1
13
+ tags:
14
+ - sentence-transformers
15
+ - semantic-search
16
+ - turkish
17
+ - matryoshka-embeddings
18
+ - onnx
19
  ---
20
 
21
+ # DUSUNEN Vector Lab
22
+
23
+ An in-browser, zero-server demonstration of DUSUNEN Pusula 118M v1. Run one
24
+ Turkish query, switch between six Matryoshka dimensions, and inspect how ranking
25
+ and vector-index size change. Query inference stays in the browser; no paid API
26
+ is used. The displayed quality figures come from the model's held-out dimension
27
+ sweep and are not universal application guarantees.
corpus.json ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "category": "Model Eğitimi",
4
+ "title": "Gradient accumulation ile etkili batch büyütme",
5
+ "text": "GPU belleği sınırlı olduğunda birkaç küçük batch'in gradyanları biriktirilerek daha büyük bir etkili batch taklit edilir. Bu yöntem bellek tüketimini düşürür; optimizasyon adımı sayısı ve öğrenme oranı seçimi birlikte değerlendirilmelidir."
6
+ },
7
+ {
8
+ "category": "Model Eğitimi",
9
+ "title": "Gradient checkpointing bellek ve hız dengesi",
10
+ "text": "Gradient checkpointing ara aktivasyonların tamamını saklamak yerine geri yayılım sırasında bir bölümünü yeniden hesaplar. Eğitim yavaşlar fakat özellikle uzun dizilerde GPU bellek ihtiyacı belirgin biçimde azalır."
11
+ },
12
+ {
13
+ "category": "Model Eğitimi",
14
+ "title": "BF16 karma hassasiyet",
15
+ "text": "BF16 eğitim, FP32'ye yakın dinamik aralığı daha düşük bellek tüketimiyle sunar. Uyumlu hızlandırıcılarda model ağırlıkları ve aktivasyonlar küçülürken sayısal kararlılık FP16'ya göre genellikle daha kolay korunur."
16
+ },
17
+ {
18
+ "category": "Model Eğitimi",
19
+ "title": "Hard negative seçiminin etkisi",
20
+ "text": "Dense retrieval eğitiminde sorguyla yüzeysel olarak benzer fakat yanlış olan pasajlar güçlü negatif örneklerdir. Aşırı kolay negatifler az sinyal üretirken yanlış negatifler model kalitesine zarar verebilir; filtreleme bu nedenle önemlidir."
21
+ },
22
+ {
23
+ "category": "Retrieval",
24
+ "title": "Dense retrieval nasıl çalışır?",
25
+ "text": "Dense retrieval, sorgu ve belgeleri aynı vektör uzayına kodlar. En yakın komşu aramasıyla cosine veya iç çarpım skoru yüksek belgeler getirilir; kelimeler birebir örtüşmese de anlamsal yakınlık yakalanabilir."
26
+ },
27
+ {
28
+ "category": "Retrieval",
29
+ "title": "MRR@10 metriği",
30
+ "text": "Mean Reciprocal Rank, ilk doğru sonucun sırasını ölçer. MRR@10 yalnızca ilk on sırayı dikkate alır ve doğru cevabın listenin üstünde bulunmasını özellikle ödüllendirir."
31
+ },
32
+ {
33
+ "category": "Retrieval",
34
+ "title": "nDCG@10 metriği",
35
+ "text": "Normalized Discounted Cumulative Gain, birden çok ilgili belgenin sırasını ve ilgililik derecesini hesaba katar. Üst sıralardaki doğru sonuçlara daha fazla ağırlık verir ve ideal sıralamaya göre normalize edilir."
36
+ },
37
+ {
38
+ "category": "Retrieval",
39
+ "title": "Recall@100 neyi anlatır?",
40
+ "text": "Recall@100, bilinen ilgili belgelerin ilk yüz sonuç içinde ne kadarının bulunduğunu ölçer. Reranker kullanılan iki aşamalı sistemlerde ilk getiricinin kapsayıcılığını izlemek için yararlıdır."
41
+ },
42
+ {
43
+ "category": "Retrieval",
44
+ "title": "FAISS ile vektör arama",
45
+ "text": "FAISS yüksek boyutlu vektörlerde benzerlik araması için optimize edilmiş bir kütüphanedir. Küçük koleksiyonlarda exact inner-product index, büyük koleksiyonlarda ise yaklaşık indeksler hız ve bellek avantajı sağlar."
46
+ },
47
+ {
48
+ "category": "Değerlendirme",
49
+ "title": "Veri sızıntısını önleyen benchmark",
50
+ "text": "Güvenilir değerlendirmede test sorguları ve belgeleri eğitim örneklerinden ayrılır. Kaynaklar, filtreler ve split yöntemi açıklanmalı; model seçimi test kümesine bakılarak yapılmamalıdır."
51
+ },
52
+ {
53
+ "category": "Değerlendirme",
54
+ "title": "Güçlü baseline karşılaştırması",
55
+ "text": "Yeni bir modeli yalnızca zayıf bir başlangıç noktasıyla kıyaslamak yanıltıcı olabilir. Aynı veri, aynı metrik uygulaması ve aynı retrieval derinliği altında güçlü açık modellerle karşılaştırma yapılmalıdır."
56
+ },
57
+ {
58
+ "category": "Değerlendirme",
59
+ "title": "Tekrarlanabilir deney kaydı",
60
+ "text": "Seed, veri sürümü, paket sürümleri, donanım, eğitim argümanları ve ham metrik dosyaları kaydedildiğinde sonuçlar denetlenebilir hale gelir. Model kartı yalnızca başarı skorunu değil sınırlamaları da göstermelidir."
61
+ },
62
+ {
63
+ "category": "MLOps",
64
+ "title": "Model kartı neden gereklidir?",
65
+ "text": "Model kartı kullanım amacı, eğitim verisi, lisans, ölçüm yöntemi, sınırlamalar ve örnek kodu tek yerde toplar. İyi dokümantasyon modelin güvenli ve doğru bağlamda kullanılmasını kolaylaştırır."
66
+ },
67
+ {
68
+ "category": "MLOps",
69
+ "title": "Veri seti soy ağacı",
70
+ "text": "Dataset provenance, verinin nereden geldiğini ve hangi dönüşümlerden geçtiğini açıklar. Lisans, dil, otomatik çeviri, kalite filtreleri ve checksum gibi ayrıntılar yeniden üretilebilirlik için kaydedilir."
71
+ },
72
+ {
73
+ "category": "MLOps",
74
+ "title": "Deneyleri küçük smoke test ile doğrulamak",
75
+ "text": "Uzun eğitimi başlatmadan önce birkaç yüz örnek ve birkaç adımlık smoke test çalıştırmak veri sütunu sırası, kayıp fonksiyonu, değerlendirme ve kayıt akışındaki hataları düşük maliyetle ortaya çıkarır."
76
+ },
77
+ {
78
+ "category": "Retrieval",
79
+ "title": "İki aşamalı retrieval ve reranking",
80
+ "text": "Dense retriever geniş bir belge havuzundan hızlıca ilk adayları getirir. Cross-encoder reranker sorgu ve her adayı birlikte okuyarak bu küçük listeyi daha hassas biçimde yeniden sıralar; kalite artışı ek gecikmeyle birlikte ölçülmelidir."
81
+ },
82
+ {
83
+ "category": "Retrieval",
84
+ "title": "Hard-negative mining hattı",
85
+ "text": "Eğitilmiş bir retriever sorgular için yüksek skorlu fakat etiket gereği yanlış pasajları bulabilir. Bu zor negatiflerle devam eğitimi yapmak karar sınırını keskinleştirebilir; yanlış negatif riski ve benchmark sızıntısı ayrıca denetlenmelidir."
86
+ },
87
+ {
88
+ "category": "Değerlendirme",
89
+ "title": "Çok alanlı Türkçe benchmark suite",
90
+ "text": "Tek bir tarih veri seti tüm Türkçe retrieval davranışını temsil etmez. Tarih, web FAQ, bilgi soruları ve okuduğunu anlama görevlerini sabit revision ve aynı evaluator ile ölçmek domain shift etkisini daha görünür kılar."
91
+ },
92
+ {
93
+ "category": "RAG",
94
+ "title": "Kaynaklı extractive RAG",
95
+ "text": "Retrieval ile bulunan pasajlardan seçilen cümleleri kaynak bağlantılarıyla sunmak, üretken model kullanmadan denetlenebilir bir yanıt deneyimi sağlar. Sistem extractive olduğunu açıkça belirtmeli ve retrieval skorlarını olasılık gibi göstermemelidir."
96
+ },
97
+ {
98
+ "category": "Sistem",
99
+ "title": "Büyük modellerde verimli inference",
100
+ "text": "Inference maliyeti batching, quantization, KV cache yönetimi ve uygun kernel seçimiyle azaltılabilir. Optimizasyon yapılırken yalnızca throughput değil ilk token gecikmesi, kuyruk süresi ve kalite kaybı birlikte ölçülür."
101
+ },
102
+ {
103
+ "category": "Sistem",
104
+ "title": "Quantization ile model küçültme",
105
+ "text": "Quantization ağırlıkları daha düşük bit genişliğinde temsil ederek bellek ihtiyacını ve kimi donanımlarda gecikmeyi azaltır. Kalibrasyon verisi ve hedef katman seçimi kalite kaybını belirleyen önemli etkenlerdir."
106
+ },
107
+ {
108
+ "category": "Sistem",
109
+ "title": "Vektör indeksinde ölçekleme",
110
+ "text": "Milyonlarca belgeye çıkıldığında tüm vektörleri taramak pahalı hale gelir. IVF, HNSW veya ürün nicemleme gibi yöntemler daha düşük gecikme sağlar; recall ve bellek maliyeti ölçülerek ayarlanır."
111
+ },
112
+ {
113
+ "category": "Güvenlik",
114
+ "title": "API anahtarlarını korumak",
115
+ "text": "Erişim anahtarları kaynak koda, model kartına veya terminal çıktısına gömülmemelidir. Ortam sırrı olarak tutulmalı, yalnızca gereken en dar yetki verilmeli ve yanlışlıkla paylaşıldığında hemen iptal edilip yenilenmelidir."
116
+ },
117
+ {
118
+ "category": "Güvenlik",
119
+ "title": "Yapay zekâ sistemlerinde tehdit modelleme",
120
+ "text": "Tehdit modelleme; varlıkları, güven sınırlarını, saldırgan kabiliyetlerini ve olası kötüye kullanım yollarını tanımlar. Prompt injection, veri sızıntısı ve tedarik zinciri riskleri tasarım aşamasında ele alınmalıdır."
121
+ }
122
+ ]
embeddings-report.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "outputs/DUSUNEN-Pusula-118M-v1/selected",
3
+ "documents": 24,
4
+ "embedding_dimension": 384,
5
+ "min_norm": 0.9999999403953552,
6
+ "max_norm": 1.0000001192092896,
7
+ "corpus_sha256": "09c7abe612b0f38be40eaf05757670aa618af8f02d9b93754f0faefc11c07f7e",
8
+ "embeddings_sha256": "9d939dd143467d38edc3113216d4d43d3e2b285fa8ca73f3021930e4fa24ff82"
9
+ }
embeddings.json ADDED
The diff for this file is too large to render. See raw diff
 
index.html CHANGED
@@ -1,19 +1,45 @@
1
  <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <!doctype html>
2
+ <html lang="tr">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <meta name="theme-color" content="#070a12">
7
+ <meta name="description" content="DUSUNEN Pusula ile 384'ten 32 boyuta canlı Matryoshka Türkçe arama laboratuvarı.">
8
+ <title>DUSUNEN Vector Lab</title>
9
+ <style>
10
+ :root{color-scheme:dark;--bg:#070a12;--panel:#101626;--line:#273047;--text:#f6f7ff;--muted:#99a6bd;--violet:#a78bfa;--cyan:#54d9e8;--lime:#b8f28d}
11
+ *{box-sizing:border-box}body{margin:0;min-height:100vh;background:radial-gradient(circle at 12% 0,rgba(118,80,230,.24),transparent 36rem),radial-gradient(circle at 100% 35%,rgba(38,211,232,.12),transparent 32rem),var(--bg);color:var(--text);font-family:Inter,ui-sans-serif,system-ui,sans-serif}body:before{content:"";position:fixed;inset:0;pointer-events:none;opacity:.15;background-image:linear-gradient(rgba(255,255,255,.07) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.07) 1px,transparent 1px);background-size:50px 50px;mask-image:linear-gradient(#000,transparent 76%)}
12
+ .shell{position:relative;width:min(1080px,calc(100% - 30px));margin:auto;padding:28px 0 66px}nav{display:flex;justify-content:space-between;align-items:center;padding-bottom:24px;border-bottom:1px solid var(--line)}.brand{font-weight:850}.brand b{display:inline-grid;place-items:center;width:34px;height:34px;margin-right:10px;border:1px solid rgba(167,139,250,.55);border-radius:11px;color:var(--violet);font:750 10px ui-monospace,monospace}nav a,footer a{color:var(--muted);font-size:12px;text-decoration:none}
13
+ header{padding:72px 0 34px}.kicker{color:var(--cyan);font:700 11px ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase}h1{max-width:880px;margin:17px 0;font-size:clamp(45px,8vw,78px);line-height:.98;letter-spacing:-.06em}.gradient{color:transparent;background:linear-gradient(100deg,#fff,var(--violet),var(--cyan));background-clip:text}.lead{max-width:790px;margin:0;color:var(--muted);font-size:18px;line-height:1.7}.lead strong{color:var(--text)}
14
+ .lab{padding:22px;border:1px solid var(--line);border-radius:21px;background:rgba(16,22,38,.94);box-shadow:0 28px 80px rgba(0,0,0,.28)}label{display:block;margin-bottom:9px;color:var(--muted);font:650 10px ui-monospace,monospace;letter-spacing:.1em;text-transform:uppercase}.controls{display:grid;grid-template-columns:1fr auto;gap:10px}input{height:54px;padding:0 17px;border:1px solid var(--line);border-radius:12px;outline:0;background:#090d17;color:var(--text);font:500 15px inherit}input:focus{border-color:var(--cyan);box-shadow:0 0 0 3px rgba(84,217,232,.1)}button{height:54px;padding:0 20px;border:0;border-radius:12px;background:var(--text);color:#080c15;font:800 13px inherit;cursor:pointer}button:disabled{opacity:.55;cursor:wait}.dims{display:flex;flex-wrap:wrap;gap:7px;margin-top:15px}.dim{height:36px;padding:0 13px;border:1px solid var(--line);background:transparent;color:var(--muted);font:700 11px ui-monospace,monospace}.dim.active{border-color:var(--cyan);background:rgba(84,217,232,.1);color:var(--cyan)}.status{display:flex;justify-content:space-between;gap:14px;margin-top:15px;color:var(--muted);font:600 10px ui-monospace,monospace}.bar{height:3px;margin-top:9px;background:#20283a;border-radius:3px;overflow:hidden}.bar span{display:block;width:0;height:100%;background:linear-gradient(90deg,var(--violet),var(--cyan));transition:width .25s}
15
+ .metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin:26px 0}.metric{padding:18px;border:1px solid var(--line);border-radius:15px;background:rgba(255,255,255,.025)}.metric strong{display:block;font-size:23px;letter-spacing:-.04em}.metric span{color:var(--muted);font:650 9px ui-monospace,monospace;text-transform:uppercase}.metric strong.accent{color:var(--lime)}
16
+ .result{display:grid;grid-template-columns:auto 1fr auto;gap:14px;align-items:start;margin:10px 0;padding:18px;border:1px solid var(--line);border-radius:16px;background:linear-gradient(145deg,rgba(17,23,39,.97),rgba(9,13,22,.97))}.rank{display:grid;place-items:center;width:34px;height:34px;border:1px solid rgba(167,139,250,.45);border-radius:10px;color:var(--violet);font:700 11px ui-monospace,monospace}.result h2{margin:1px 0 6px;font-size:17px}.result p{margin:0;color:#b9c3d4;font-size:13px;line-height:1.6}.score{color:var(--cyan);font:700 10px ui-monospace,monospace}.empty{padding:28px;border:1px dashed var(--line);border-radius:16px;color:var(--muted);text-align:center}footer{display:flex;justify-content:space-between;gap:20px;margin-top:44px;padding-top:23px;border-top:1px solid var(--line);color:#68758b;font-size:11px}
17
+ @media(max-width:700px){header{padding-top:52px}.controls{grid-template-columns:1fr}.controls button{width:100%}.metrics{grid-template-columns:repeat(2,1fr)}.status{flex-direction:column}.result{grid-template-columns:auto 1fr}.score{grid-column:2}footer{flex-direction:column}}
18
+ </style>
19
+ </head>
20
+ <body><div class="shell">
21
+ <nav><div class="brand"><b>VEC</b>DUSUNEN Vector Lab</div><a href="https://huggingface.co/GoktugD/DUSUNEN-Pusula-118M-v1" target="_blank" rel="noreferrer">Model card ↗</a></nav>
22
+ <header><div class="kicker">Matryoshka retrieval / 384 → 32 dimensions</div><h1>Aynı model.<br><span class="gradient">Altı vektör bütçesi.</span></h1><p class="lead">DUSUNEN Pusula sorguyu bir kez kodlar. Boyutu değiştirerek sıralamanın ve indeks maliyetinin nasıl hareket ettiğini canlı gör. <strong>Sorgu cihazından çıkmaz.</strong></p></header>
23
+ <main>
24
+ <section class="lab">
25
+ <label for="query">Türkçe sorgu</label><div class="controls"><input id="query" value="Hard negative örnekleri arama kalitesini nasıl geliştirir?" maxlength="300" autocomplete="off"><button id="search">Modeli yükle ve karşılaştır</button></div>
26
+ <div class="dims" aria-label="Embedding dimension"><button class="dim active" data-dim="384">384-D</button><button class="dim" data-dim="256">256-D</button><button class="dim" data-dim="192">192-D</button><button class="dim" data-dim="128">128-D</button><button class="dim" data-dim="64">64-D</button><button class="dim" data-dim="32">32-D</button></div>
27
+ <div class="status"><span id="status">Hazır · ilk sorgu q8 ONNX modelini önbelleğe alır</span><span id="latency">—</span></div><div class="bar"><span id="progress"></span></div>
28
+ </section>
29
+ <section class="metrics"><div class="metric"><strong id="dimension">384</strong><span>dimensions</span></div><div class="metric"><strong id="bytes">1,536 B</strong><span>float32 / vector</span></div><div class="metric"><strong class="accent" id="reduction">0.0%</strong><span>index reduction</span></div><div class="metric"><strong id="accuracy">91.95%</strong><span>held-out triplet accuracy</span></div></section>
30
+ <section id="results"><div class="empty">Bir sorgu çalıştır; sonra boyut düğmeleriyle aynı adayların sıralamasını karşılaştır.</div></section>
31
+ </main>
32
+ <footer><span>Scores are cosine similarities, not calibrated probabilities.</span><span><a href="https://huggingface.co/datasets/GoktugD/DUSUNEN-Turkish-Retrieval-Benchmark-v1">Benchmark</a> · <a href="https://huggingface.co/GoktugD">Göktuğ Düşünen</a></span></footer>
33
+ </div><script type="module">
34
+ const ACC={384:91.95,256:91.70,192:90.75,128:89.85,64:88.90,32:86.40};
35
+ const query=document.querySelector("#query"),search=document.querySelector("#search"),status=document.querySelector("#status"),latency=document.querySelector("#latency"),progress=document.querySelector("#progress"),results=document.querySelector("#results"),worker=new Worker("./worker.js",{type:"module"});
36
+ let documents=[],embeddings=[],queryVector=null,currentDim=384,requestId=0,ready=false;
37
+ const assets=Promise.all([fetch("./corpus.json").then(r=>r.json()),fetch("./embeddings.json").then(r=>r.json())]).then(([d,e])=>{documents=d;embeddings=e});
38
+ function truncate(vector,dim){const out=vector.slice(0,dim);let norm=Math.sqrt(out.reduce((s,x)=>s+x*x,0));return out.map(x=>x/norm)}
39
+ function dot(a,b){let sum=0;for(let i=0;i<a.length;i++)sum+=a[i]*b[i];return sum}
40
+ function updateMetrics(){document.querySelector("#dimension").textContent=currentDim;document.querySelector("#bytes").textContent=`${(currentDim*4).toLocaleString("en-US")} B`;document.querySelector("#reduction").textContent=`${((1-currentDim/384)*100).toFixed(1)}%`;document.querySelector("#accuracy").textContent=`${ACC[currentDim].toFixed(2)}%`}
41
+ function render(){if(!queryVector)return;const q=truncate(queryVector,currentDim),ranked=embeddings.map((v,index)=>({index,score:dot(q,truncate(v,currentDim))})).sort((a,b)=>b.score-a.score).slice(0,5);results.replaceChildren(...ranked.map(({index,score},rank)=>{const item=documents[index],card=document.createElement("article");card.className="result";const r=document.createElement("span");r.className="rank";r.textContent=`#${rank+1}`;const body=document.createElement("div"),h=document.createElement("h2"),p=document.createElement("p"),s=document.createElement("span");h.textContent=item.title;p.textContent=item.text;body.append(h,p);s.className="score";s.textContent=`cosine ${score.toFixed(4)}`;card.append(r,body,s);return card}));status.textContent=`${currentDim}-D sıralama hazır · boyutlar arasında anında geçiş yapabilirsin`;updateMetrics()}
42
+ async function run(){if(query.value.trim().length<3)return;await assets;search.disabled=true;search.textContent=ready?"Kodlanıyor…":"Model yükleniyor…";progress.style.width=ready?"65%":"4%";worker.postMessage({type:"encode",query:query.value,requestId:++requestId})}
43
+ document.querySelectorAll(".dim").forEach(button=>button.addEventListener("click",()=>{document.querySelector(".dim.active").classList.remove("active");button.classList.add("active");currentDim=Number(button.dataset.dim);updateMetrics();render()}));search.addEventListener("click",run);query.addEventListener("keydown",e=>{if(e.key==="Enter")run()});
44
+ worker.onmessage=({data})=>{if(data.type==="progress"){if(data.event?.progress!=null)progress.style.width=`${Math.max(4,Math.round(data.event.progress))}%`;if(data.event?.file)status.textContent=`Model yükleniyor · ${data.event.file.split("/").pop()}`}else if(data.type==="result"&&data.requestId===requestId){queryVector=data.embedding;latency.textContent=`${data.inferenceMs.toFixed(0)} ms · ${documents.length} belge`;progress.style.width="100%";search.disabled=false;search.textContent="Yeniden karşılaştır";ready=true;render()}else if(data.type==="error"){status.textContent=`Yükleme hatası: ${data.message}`;progress.style.width="0";search.disabled=false;search.textContent="Yeniden dene"}};
45
+ </script></body></html>
validation.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "space": "vector-lab",
3
+ "documents": 24,
4
+ "embedding_shape": [
5
+ 24,
6
+ 384
7
+ ],
8
+ "min_norm": 0.9999998807907104,
9
+ "max_norm": 1.0000001192092896,
10
+ "sources_required": false,
11
+ "status": "pass"
12
+ }
worker.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { env, pipeline } from "https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.2.0";
2
+
3
+ const MODEL_ID = "GoktugD/DUSUNEN-Pusula-118M-v1";
4
+
5
+ env.allowLocalModels = false;
6
+ env.useBrowserCache = true;
7
+
8
+ let extractorPromise;
9
+
10
+ function getExtractor() {
11
+ if (!extractorPromise) {
12
+ extractorPromise = pipeline("feature-extraction", MODEL_ID, {
13
+ dtype: "q8",
14
+ progress_callback: (event) => self.postMessage({ type: "progress", event }),
15
+ });
16
+ }
17
+ return extractorPromise;
18
+ }
19
+
20
+ self.onmessage = async ({ data }) => {
21
+ if (data.type !== "encode") return;
22
+ try {
23
+ const extractor = await getExtractor();
24
+ const started = performance.now();
25
+ const output = await extractor(data.query.trim(), { pooling: "mean", normalize: true });
26
+ self.postMessage({
27
+ type: "result",
28
+ requestId: data.requestId,
29
+ embedding: Array.from(output.data),
30
+ inferenceMs: performance.now() - started,
31
+ });
32
+ } catch (error) {
33
+ extractorPromise = undefined;
34
+ self.postMessage({ type: "error", message: error?.message || String(error) });
35
+ }
36
+ };