Методология + первые измеренные результаты · стенд раскрыт

Правила публикуются раньше,
чем цифры.

Telys — версия 0.1.0b4: это показатели, подтверждённые на прототипе на раскрытом стенде, а не продакшен-цифры. Результат засчитывается только тогда, когда он измерен при совпадающем recall на совпадающем железе, с исходными выборками и скриптом, который их получил. Правила ниже по-прежнему обязательны для каждого числа: что мы измеряем, с кем сравниваем и в чём обязаны проигрывать.

01 Операционная доктрина

Правила, закреплённые в стенде, — не оговорки в сносках.

Каждое из приведённых ниже правил закодировано как машинная проверка в бенчмарк-стенде. Прогон, нарушивший правило, не получает сноску — он помечается как недействительный и исключается из всех таблиц результатов.

Любой множитель остаётся гипотезой, пока не измерен при совпадающем recall и совпадающем железе — с исходными выборками и опубликованным скриптом воспроизведения.

Доктрина бенчмарков Telys
Обязательные проигрыши

Бенчмарк, в котором нельзя проиграть, ничего не стоит

Сгенерированная таблица результатов содержит обязательный раздел «Где мы проигрываем», заполняемый автоматически по каждой ячейке, которую выигрывает конкурент. Если раздел пуст, сборка отчёта завершается ошибкой — чистая победа трактуется как сломанный стенд, а не как триумф.

Честность транспорта

Embedded против embedded — честное сравнение

Мы никогда не выносим в заголовок вызов in-process против конкурента, отвечающего по TCP. Для встраиваемых библиотек честный транспорт — in-process против in-process. Для серверов транспорт сопоставляется один к одному, иначе цифра аннотируется и в заголовки не попадает.

Честность надёжности

Совпадающие уровни — или нет сравнения

Прогон in-memory никогда не сравнивается с конкурентом, выполняющим fsync при каждом коммите. Каждый результат декларирует свой уровень надёжности — in_mem, wal_async или wal_fsync — и стенд жёстко отклоняет любое сравнение между уровнями.

Правило FAISS

Мы никогда не намекаем, что обходим FAISS, когда сами вызываем FAISS

FAISS — это ANN-ядро, встроенное в Telys: фундамент, а не соперник. В каждой векторной таблице первой идёт ячейка с результатом чистого обхода FAISS; там, где результат совпадает, это явно указывается. Честные победы заявляются в другом: ядра переранжирования, фильтрованное планирование и движок вокруг индекса.

02 Набор сравниваемых систем

Каждый сравниваемый изолирует одно утверждение.

Единственная цифра в таблице лидеров смешивает алгоритм, транспорт, надёжность и формат хранения. Набор подобран так, чтобы каждое сравнение изолировало ровно одну переменную — с контрольным замером на том же узле под каждым заголовком.

СистемаТипЧто изолирует сравнение
FAISS (тот же узел)Контрольный базисНижняя граница, а не соперник. Telys встраивает FAISS, поэтому цифра чистого FAISS — это и есть наш базис; публикуемая дельта — то, что движок добавляет вокруг него при той же строке индекса и том же измеренном recall.
Postgres + pgvectorРеляционная + векторнаяФильтрованный гибридный запрос: выигрывает ли проталкивание скалярного предиката в путь кандидатов у индекса, вынужденного делать over-fetch или post-filter, при равном recall по разным селективностям фильтра.
LanceDB / ChromaВстраиваемая библиотекаБлижайшие конкуренты, in-process против in-process — единственный случай, когда цифра in-process честна в заголовке. Одинаковый ANN-базис; сравнение изолирует движок вокруг него: единое пространство row-id, cold-open, объём памяти.
Qdrant / MilvusСерверКачество алгоритма — recall при фиксированном k — отделённое от сетевых round-trip. Задержка публикуется с аннотацией о серверном хопе и никогда не выносится в заголовок рядом с вызовом in-process.
PineconeУправляемый сервисRecall при фиксированном k и пропускная способность на единицу вычислительных ресурсов. Сырая задержка относительно встроенного движка не используется как заголовочный показатель; вместо этого контрольный узел на том же хосте подтверждает качество.
DuckDB / ClickHouseАналитический движокСканирование и агрегация по одному физическому файлу Parquet — так преимущество формата хранения отделяется от преимущества движка. Векторизованные аналитические движки здесь превосходны; их победы публикуются.
03 Матрица нагрузок

Что измеряется.

Матрица определяет измерения, а не предполагаемые победы. Каждая ячейка задержки отражает полное распределение — никогда только среднее — при нагрузке в режиме открытого цикла. Каждая ячейка скорости привязана к порогу recall, вычисляемому стендом по эталонным данным; ячейка, не прошедшая порог, помечается недействительной и не попадает в итоговую таблицу.

НагрузкаКонфигурацияЧто измеряется
cold-openСброс page cache, запуск нового процессаВремя от запуска процесса до первого успешного запроса — mmap сегментов и подключение index-sidecar в сравнении с загрузкой сервера и восстановлением. Измеряется отдельно от установившегося режима, никогда не объединяется с ним.
exact FLATТочный поиск перебором, f32 и int8Нижняя граница ядра расстояний при recall 1.0 по построению, относительно точного базового уровня на том же узле и тех же буферах. Каждая ячейка int8 сообщает дельту recall относительно f32 — потери от квантования не скрываются.
фильтрованный гибридСкалярный предикат + top-k, перебор по трём уровням селективностиЗадержка при равном recall по мере сужения фильтра, а также выбранная планировщиком стратегия для каждой ячейки — pre-filter затем exact, pre-filter затем IVF или поиск с последующим post-filter — так адаптивное решение поддаётся аудиту.
full scanПолное сканирование столбца и агрегацияСырая колоночная пропускная способность по общему Parquet — движок против движка на идентичных байтах.
выборочное сканированиеСканирование по предикату при низкой доле совпаденийДействительно ли footer min-max и zone-map pruning пропускают лишнюю работу — отчёт в байтах прочитанных данных и затронутых строках, а не только в wall clock.
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"

Прогоны повторяются не менее пяти раз при каждом свежем запуске процесса, на зафиксированных аппаратных профилях, по одной системе за раз. Датасеты адресуются по содержимому; наборы запросов — замороженные файлы, не генерируются во время выполнения. Спецификация стенда зафиксирована сегодня; стенд публикуется вместе с результатами.

04 Первые измеренные результаты

Измерено, обусловлено, воспроизводимо.

Каждая строка — реальный прогон на указанном выше стенде при напечатанном рядом пороге recall. Источник выигрыша — физическая раскладка: на идентичном непрерывном подмножестве наш Mojo-скан не уступает сырому FAISS — дельта ниже показывает, что даёт раскладка с партиционированием по ключу, а не более быстрое ядро расстояний. Это показатели прототипа, которые переизмеряются в рамках полного контракта честности по мере развития стенда.

НагрузкаКонфигурация + порог recallИзмеренный результат (M4 Max, однопоточный, in-process)
Фильтрованный срез · сел. 0,1%N=1 000 000 D=128 K=10, прогрев, recall 1,000 (точный)partition-slice p50 0,013 мс — выигрыш раскладки vs полный скан ~373×, vs scatter-gather ~19×. FAISS Flat на идентичном подмножестве: 0,040 мс (ничья — доказывает, что выигрыш даёт раскладка, а не ядро).
Фильтрованный срез · сел. 0,4%N=1 000 000 D=128 K=10, прогрев, recall 1,000 (точный)p50 0,032 мс — ~128× vs полный скан, ~10,8× vs scatter-gather. Контроль FAISS Flat 0,035 мс (ничья).
Фильтрованный срез · сел. 1,6%N=1 000 000 D=128 K=10, прогрев, recall 1,000 (точный)p50 0,112 мс — ~42× vs полный скан, ~10,3× vs scatter-gather. Контроль FAISS Flat 0,120 мс (ничья).
Спасение гигантской партиции247k строк при N=400 000 D=128, nprobe откалиброван, recall 0,9915 (порог 0,98)IVF внутри партиции восстанавливает выигрыш раскладки там, где точный срез деградирует: точный срез 1,71 мс → IVF 0,033 мс. Без IVF одна гигантская партиция даёт лишь ~4–5×.
Управляемый auto-nprobeN=1 000 000 D=128 Q=500 nlist=1000, recall удерживается 0,998 (порог 0,98)FIND 0,28–0,31 мс при базовом nprobe=32 → 0,081–0,088 мс при управляемом auto-nprobe=8. Recall остаётся выше порога — без скрытого обмена recall на скорость.
FIND vs контроль FAISSIso-recall, одинаковый транспорт, оба in-process, N=1 000 000 D=128Telys 0,073–0,074 мс @0,998 vs сырой FAISS 0,080 мс @0,999 — паритет или незначительное преимущество. Зависит от масштаба: отставание (0,74×) при N=200k, до ~1,6× только при большом memory-bound N. Качество FAISS, ускоренное Mojo.
Конкурентность без GILN=200 000 D=128, 12 производительных ядер, in-process Mojo IVF kernelПропускная способность FIND масштабируется ×6,9 на 8 потоках (15 128 → 104 756 qps). Масштабирование пропускной способности, а не задержки на запрос; без сравнения с серверными движками.
Актуальность вставкиБазовый N=100 000, M=300 вставок, D=128, in-processТолько что вставленный вектор занимает top-1 уже на следующем запросе: recall@1-of-new = 1,000. Insert p50 0,3 мкс. Это проверка корректности, а не заголовок о пропускной способности.

Каждая ячейка выше прослеживается до именованного скрипта и сохранённого исходного вывода в bench/results/ (filtered_impact.txt, partitioned.txt, partition_acceptance.txt, opt.txt, telys.txt, concurrency.txt, freshness.txt). Показатель повторного открытия после персистентности удержан до получения нового измеренного исходного образца. Любой множитель — гипотеза за пределами условий, указанных в каждой строке.

05 Качество поиска по коду

Создан для кода — и оценён на кодовом бенчмарке.

Telys ищет по коду, поэтому планка качества — CoIR, а не набор для общего текста. LexicalCodeIndex обёрнут как mteb SearchProtocol и оценивается через mteb.evaluate по тому же пути, что и базовые линии bm25s, — никакого разрыва в методологии, никакой самооценки. Базовые линии — воспроизводимые запуски от 2026-07-21, а не опубликованные цифры из статьи CoIR (часть из них не воспроизводится). Метрика: nDCG@10.

Задача CoIRmultigrambm25-refbm25-codeкод-лексический · выпущенvs лучшего базового
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
Среднее0.1860.445 †0.4887/8

Семь побед из восьми; среднее 0.488 против 0.445 у сильнейшей базовой линии по каждой задаче († лучшее из bm25-ref / bm25-code, по задаче) — и в 2.6× выше среднего multigram. Единственное поражение, AppsRetrieval, близко к нулю для всех лексических методов: длинные условия задач против кода — это территория эмбеддингов.

Рычаг 01

Токены для кода + BM25

Идентификаторы разбиваются так, как пишется код — camelCase, snake_case, пути через точку — и подаются в обычный IDF/BM25. Одно это выигрывает большинство задач: CodeTransOceanContest вырастает с 0.478 до 0.600 без какой-либо настройки.

Рычаг 02

Стоп-слова убраны, лёгкий стемминг

Английские стоп-слова удалены, лёгкий суффиксный стеммер выравнивает запросы на естественном языке с токенами кода — рычаг, который превращает SyntheticText2SQL из поражения в 0.441.

Рычаг 03

k1 = 1,8 · b = 1,0

Значения по умолчанию в поставке, настроенные Algenta на CoIR: более сильное насыщение по частоте термина и полная нормализация длины — рычаг, который переворачивает StackOverflowQA.

Каждая ячейка воспроизводится из одного скрипта — bench/mteb_code_lexical.py — прогоняющего обе стороны через один вызов mteb.evaluate (запуски от 2026-07-21). code-lexical — это индекс, поставляемый Telys, с его значениями по умолчанию.

06 Публикация

Победы, ничьи и поражения — в открытом доступе.

Формат публикации фиксируется до появления первого числа — числа не могут его изменить.

Опубликованные поражения

Где мы проигрываем — в печати

Каждая итоговая таблица содержит раздел «Где мы проигрываем» и раздел «Где мы лишь сравниваемся с FAISS» — оба заполняются автоматически из ячеек. Отчёт не собирается, если хотя бы один из них пуст.

Режим рецензента

Воспроизведите результаты без нас

Стенд запускается без Telys, так что скептик может самостоятельно воспроизвести числа сравниваемых систем и контрольного узла и убедиться, что каждый конкурент настроен по собственному руководству — конфиги зафиксированы и сравнены с дефолтами вендора.

Сырые сэмплы

Каждая ячейка ведёт к сэмплам

Каждая опубликованная ячейка ссылается на сырые сэмплы по операциям и точный скрипт, их породивший. Результаты только дополняются — с привязкой к ревизии движка и версиям статически слинкованных зависимостей.

Поговорить с командой

Это показатели прототипа, каждый сопровождается своими условиями. Держите нас за этот контракт — и за цифры по мере того, как мы переизмеряем их в рамках полного стенда.