Metodologia + primi risultati misurati · rig prototipo dichiarato

Le regole vengono pubblicate prima
dei numeri.

Telys è alla versione 0.1.0b4 — queste sono cifre validate su prototipo su un rig dichiarato, non numeri di produzione. Un risultato è valido solo se misurato con recall corrispondente su hardware corrispondente, con campioni grezzi e lo script che li ha prodotti. Le regole seguenti vincolano ogni numero: cosa misuriamo, contro chi, e i modi in cui siamo tenuti a perdere.

01 Dottrina operativa

Regole che l'harness impone, non avvertenze che aggiungiamo.

Ogni regola qui sotto è codificata come controllo automatico nell'harness di benchmark. Un'esecuzione che la viola non viene annotata a piè di pagina — viene marcata come non valida ed esclusa da ogni scorecard.

Ogni moltiplicatore è un'ipotesi finché non viene misurato con recall corrispondente e hardware corrispondente, con campioni grezzi e uno script di riproduzione pubblicato.

Dottrina benchmark di Telys
Sconfitte obbligatorie

Un benchmark che non possiamo perdere non vale nulla

La scorecard generata include una sezione obbligatoria Dove perdiamo, popolata automaticamente da ogni cella vinta da un comparatore. Se quella sezione è vuota, la build del report fallisce — una vittoria su tutti i fronti è trattata come un harness difettoso, non come un trionfo.

Onestà sul trasporto

Embedded vs embedded è il confronto corretto

Non mettiamo mai in evidenza una chiamata in-process contro un concorrente che risponde via TCP. Con le librerie embedded, il trasporto onesto è in-process vs in-process. Con i server, il trasporto viene abbinato in modo equivalente, altrimenti il numero viene annotato e tenuto fuori dai titoli.

Onestà sulla durabilità

Livelli equivalenti, o nessun confronto

Un'esecuzione in memoria non viene mai confrontata con un concorrente che esegue fsync a ogni commit. Ogni risultato dichiara il proprio livello di durabilità — in_mem, wal_async o wal_fsync — e l'harness rifiuta categoricamente qualsiasi confronto tra livelli diversi.

La regola FAISS

Non lasciamo mai intendere di battere FAISS quando stiamo chiamando FAISS

FAISS è il nucleo ANN che Telys incorpora — una fondamenta, non un avversario. Ogni scorecard vettoriale mostra per prima la cella di attraversamento FAISS grezzo; dove c'è un pareggio, il pareggio viene stampato. Le vittorie legittime vengono rivendicate altrove: kernel di rerank, pianificazione filtrata e il motore attorno all'indice.

02 Il set di comparatori

Ogni comparatore isola un'affermazione.

Un singolo numero in classifica confonde algoritmo, trasporto, durabilità e formato di archiviazione. Il set è scelto in modo che ogni confronto isoli esattamente una variabile — con un controllo sullo stesso nodo sotto ogni titolo.

SistemaFormaCosa isola il confronto
FAISS (stesso nodo)Baseline di controlloIl pavimento, non un avversario. Telys incorpora FAISS, quindi il numero FAISS grezzo è la baseline che siamo; il delta pubblicato è ciò che il motore aggiunge attorno ad esso — con la stessa stringa di indice e lo stesso recall misurato.
Postgres + pgvectorRelazionale + vettorialeLa query ibrida filtrata: se spingere un predicato scalare nel percorso dei candidati supera un indice che deve recuperare in eccesso o post-filtrare, a recall uguale tra diverse selettività di filtro.
LanceDB / ChromaLibreria embeddedI concorrenti più diretti, in-process vs in-process — l'unico caso in cui un numero in-process è un titolo corretto. Stesso pavimento ANN; il confronto isola il motore attorno ad esso: spazio row-id unificato, cold-open, footprint.
Qdrant / MilvusServerQualità dell'algoritmo — recall a k fisso — separata dai round-trip di rete. La latenza viene riportata con il salto server annotato e non viene mai messa in evidenza rispetto a una chiamata in-process.
PineconeServizio gestitoRecall a k fisso e throughput per unità di calcolo. La latenza grezza rispetto a un motore embedded è rifiutata come titolo principale; il controllo sullo stesso nodo porta invece la garanzia di qualità.
DuckDB / ClickHouseMotore analiticoScansione e aggregazione sullo stesso file Parquet fisico, così il vantaggio del formato di storage è separato da quello del motore. I motori analitici vettorizzati eccellono qui; le loro vittorie vengono pubblicate.
03 La matrice dei workload

Cosa viene misurato.

La matrice definisce misurazioni, non vittorie ipotizzate. Ogni cella di latenza riporta la distribuzione completa — mai solo la media — sotto carico offerto in open-loop. Ogni cella di velocità è vincolata a una soglia di recall calcolata dall'harness rispetto al ground truth rilasciato; una cella che non supera la soglia viene emessa come non valida e non può entrare in uno scorecard.

WorkloadSetupCosa misura
cold-openPage cache azzerata, avvio di processo frescoTempo dall'avvio del processo alla prima query riuscita — mmap dei segmenti e mapping dell'index-sidecar rispetto al boot del server e al recovery. Misurato separatamente dallo steady state, mai aggregato in esso.
exact FLATRicerca esatta brute-force, f32 e int8Il floor del kernel di distanza a recall 1.0 per costruzione, rispetto alla baseline esatta sullo stesso nodo sugli stessi buffer. Ogni cella int8 riporta il delta di recall rispetto a f32, così la perdita da quantizzazione non viene mai nascosta.
ibrido filtratoPredicato scalare + top-k, spazzato su tre selettivitàLatenza a recall uguale al restringersi del filtro, più la strategia scelta dal planner per ogni cella — pre-filter poi exact, pre-filter poi IVF, o search poi post-filter — così la decisione adattiva è verificabile.
full scanScansione e aggregazione sull'intera colonnaThroughput colonnare grezzo su Parquet condiviso, motore contro motore su byte identici.
scansione selettivaScansione con predicato a basso tasso di corrispondenzaSe il pruning footer min-max e zone-map salta effettivamente lavoro — riportato come byte letti e righe toccate, non solo come tempo di esecuzione.
reproduce
python -m bench.orchestrator.run \
    --suite vector --rig m-laptop
# one command: pinned comparators, content-addressed
# datasets, warmup, steady-state measurement
# reviewer mode: the same run with Telys excluded
result envelope
# every run emits a machine-checked ResultEnvelope;
# a run that cannot fill every field is invalid
index_string    = "IVF4096,PQ16"  # same for Telys and the FAISS control
omp_num_threads = 8               # FAISS threading pinned, disclosed
transport       = "in_process"    # headlined only vs in-process
durability_tier = "wal_fsync"     # cross-tier comparison hard-fails
recall_at_k     = 1.000           # harness-measured, never self-reported
samples_path    = "bench/results/filtered_impact.txt"

Le esecuzioni si ripetono almeno cinque volte su avvii di processo freschi, su profili hardware fissati, un sistema alla volta. I dataset sono content-addressed; i query set sono file congelati, non generati a runtime. La specifica dell'harness è consolidata oggi; l'harness pubblica insieme ai risultati.

04 Primi risultati misurati

Misurati, condizionati, riproducibili.

Ogni riga è un'esecuzione reale sul rig indicato sopra, alla soglia di recall riportata accanto. Il vantaggio è nel layout fisico: su un sottoinsieme contiguo identico la nostra scansione Mojo pareggia FAISS grezzo — il delta seguente è ciò che il layout partizionato per chiave apporta, non un kernel di distanza più veloce. Sono cifre prototipali, rieseguite sotto il contratto di equità completo man mano che l'harness matura.

Carico di lavoroSetup + soglia di recallRisultato misurato (M4 Max, single-thread, in-process)
Slice filtrato · sel 0,1%N=1.000.000 D=128 K=10, warm, recall 1,000 (esatto)partition-slice p50 0,013 ms — vantaggio di layout vs full-scan ~373×, vs scatter-gather ~19×. FAISS Flat stesso nodo sul sottoinsieme identico: 0,040 ms (pareggio — dimostra che il vantaggio è nel layout, non nel kernel).
Slice filtrato · sel 0,4%N=1.000.000 D=128 K=10, warm, recall 1,000 (esatto)p50 0,032 ms — ~128× vs full-scan, ~10,8× vs scatter-gather. Controllo FAISS Flat 0,035 ms (pareggio).
Slice filtrato · sel 1,6%N=1.000.000 D=128 K=10, warm, recall 1,000 (esatto)p50 0,112 ms — ~42× vs full-scan, ~10,3× vs scatter-gather. Controllo FAISS Flat 0,120 ms (pareggio).
Recupero partizione gigante247k righe su N=400.000 D=128, nprobe calibrato, recall 0,9915 (floor 0,98)IVF all'interno della partizione ripristina il vantaggio di layout dove uno slice esatto degrada: slice esatto 1,71 ms → IVF 0,033 ms. Senza IVF, una singola partizione gigante regge solo ~4–5×.
Auto-nprobe governatoN=1.000.000 D=128 Q=500 nlist=1000, recall mantenuto 0,998 (floor 0,98)FIND 0,28–0,31 ms a nprobe=32 baseline → 0,081–0,088 ms con auto-nprobe=8 governato. Il recall rimane sopra il floor — nessun trade silenzioso recall-per-velocità.
FIND vs controllo FAISSIso-recall, stesso trasporto, entrambi in-process, N=1.000.000 D=128Telys 0,073–0,074 ms @0,998 vs FAISS grezzo 0,080 ms @0,999 — parità o leggermente avanti. Dipendente dalla scala: indietro (0,74×) a N=200k, fino a ~1,6× solo a N grandi memory-bound. Qualità FAISS, accelerato da Mojo.
Concorrenza GIL-freeN=200.000 D=128, 12 core perf, kernel Mojo IVF in-processIl throughput di FIND scala ×6,9 su 8 thread (15.128 → 104.756 qps). Scaling del throughput, non latenza per query; non confrontato con engine server.
Freschezza insert-to-recallBase N=100.000, M=300 insert, D=128, in-processUn vettore appena inserito è top-1 alla query immediatamente successiva: recall@1-of-new = 1,000. Insert p50 0,3 µs. Gate di correttezza, non un titolo di throughput.

Ogni cella sopra è tracciabile a uno script nominato e a un output grezzo salvato in bench/results/ (filtered_impact.txt, partitioned.txt, partition_acceptance.txt, opt.txt, telys.txt, concurrency.txt, freshness.txt). La cifra di riapertura della persistenza è trattenuta in attesa di un campione grezzo ri-misurato. Ogni moltiplicatore è un'ipotesi al di fuori delle condizioni riportate in ciascuna riga.

05 Qualità del recupero del codice

Progettato per il codice — e valutato su un benchmark per il codice.

Telys recupera codice, quindi il riferimento qualitativo è CoIR, non una suite per testo generico. LexicalCodeIndex è esposto come mteb SearchProtocol e valutato da mteb.evaluate sullo stesso percorso delle baseline bm25s — nessun divario metodologico, nessuna autovalutazione. Le baseline sono esecuzioni riproducibili del 2026-07-21, non le cifre pubblicate nel paper CoIR (diverse di quelle non si riproducono). Metrica: nDCG@10.

Task CoIRmultigrambm25-refbm25-codecodice-lessicale · rilasciatovs baseline migliore
CodeTransOceanContest0.1600.4780.6000.718
CodeTransOceanDL0.3400.3440.3510.366
CosQA0.0480.1880.2130.218
SyntheticText2SQL0.2650.2490.3720.441
CodeFeedbackMT0.2880.5920.5910.674
CodeFeedbackST0.1620.6820.6820.722
StackOverflowQA0.2230.7030.6870.733
AppsRetrieval0.0010.0480.0140.034
Media0.1860.445 †0.4887/8

Sette vittorie su otto; media 0.488 contro 0.445 della baseline più forte per ciascun task († il migliore tra bm25-ref e bm25-code, per task) — e 2,6× la media multigram. L'unica sconfitta, AppsRetrieval, si attesta vicino allo zero per ogni metodo lessicale: enunciati lunghi contro codice è territorio degli embedding.

Leva 01

Token code-aware + BM25

Gli identificatori vengono suddivisi secondo la scrittura del codice — camelCase, snake_case, percorsi puntati — alimentando un semplice IDF/BM25. Questo da solo vince la maggior parte dei task: CodeTransOceanContest passa da 0.478 a 0.600 prima di qualsiasi ottimizzazione.

Leva 02

Stopword rimosse, stemming leggero

Stopword inglesi rimosse e uno stemmer suffissale leggero, così le query in linguaggio naturale si allineano ai token del codice — la leva che trasforma SyntheticText2SQL da una sconfitta a 0.441.

Leva 03

k1 = 1,8 · b = 1,0

I valori predefiniti shipped, ottimizzati da Algenta su CoIR: saturazione della frequenza dei termini più marcata e normalizzazione completa della lunghezza — la leva che ribalta StackOverflowQA.

Ogni cella si riproduce da un unico script — bench/mteb_code_lexical.py — che esegue entrambi i lati attraverso la stessa chiamata mteb.evaluate (esecuzioni del 2026-07-21). code-lexical è l'indice che Telys distribuisce, con i suoi valori predefiniti shipped.

06 Pubblicazione

Vittorie, pareggi e sconfitte — per iscritto.

Il formato di pubblicazione è fissato prima che esista il primo numero, così i numeri non possono piegarlo.

Sconfitte pubblicate

Dove perdiamo, nero su bianco

Ogni scorecard include una sezione Dove perdiamo e una sezione Dove pareggiano solo FAISS, entrambe popolate automaticamente dalle celle. Il report non compila se una delle due è vuota.

Modalità revisore

Riproduci i risultati senza di noi

L'harness gira con Telys escluso, così uno scettico può riprodurre da solo i numeri dei comparatori e del controllo e verificare che ogni competitor sia stato configurato secondo la propria guida — configurazioni committate e diffate rispetto ai default del vendor.

Campioni grezzi

Ogni cella rimanda ai campioni

Ogni cella pubblicata collega i propri campioni grezzi per operazione e lo script esatto che li ha prodotti. I risultati sono append-only, indicizzati per revisione del motore e versioni delle dipendenze collegate staticamente.

Parla con il team

Sono numeri prototipali, ciascuno accompagnato dalle proprie condizioni. Tienici a questo contratto — e alle cifre man mano che le rieseguiamo sotto l'harness completo.