Вся база знаний в одном файле
.jpg


Island
Forest
Mountain
Папка и несколько строк TOML превращаются в один .urna: чанки, векторы, индекс, медиа и manifest, каждая секция подписана.
Сканы карт попадают в файл в AV1, а векторы переходят на пресет поменьше. Файл сжимается, цитата остаётся той же.
Гейт model_hash проверяет модель, HNSW проходит по графу, BM25 находит слово, а точный косинус задаёт порядок.
Ответ несёт цитату обратно к источнику, а urna validate проверяет каждый слой до первого запроса, офлайн.
От папки с документами
к файлу, который отвечает
Что помещается в .urna
00100000 01010011 01111001 01110011 01110100 01100101 01101101 00111010 00100000 01000011 01100001 01110010 01100100 01110011
Публичный бенчмарк, одна линейка
Бенчмарк от 2026-09-10 на arm64, один поток. Чего Urna не умеет: обновление и удаление на месте, фильтры по метаданным, конкурентная запись. Открыть полную таблицу.
Бенчмарки urna
Сжатие против поиска по названию
файлов: 7 · запросов на файл: 1 000во столько раз меньше, чем 3,98 GB исходных JPEG. Файл с crf50 весит 533 MB и находит карту по названию так же часто, как lossless-файл на 3,61 GB: разница по txt@1 составляет +0,001, в пределах стандартной ошибки.
Что измеряет эта метрика
txt@1 означает долю запросов (всего 1 000), в которых нужная карта оказалась первой. Запросом служит название карты в виде текста ("artwork of the card {name}"), по нему ищут в пространстве изображений clip. Модель видит только иллюстрацию, поэтому уровень низкий во всех файлах; важно, где он начинает падать.
drift здесь означает косинус между вектором сжатого изображения и вектором оригинала: 1,00 значит идентичны, и чем ниже значение, тем сильнее кодек изменил то, что видит модель. Худший дециль (p10) соответствует карте на границе 10 % самых изменившихся, медиана (p50) соответствует карте посередине.
Как читать этот график
Каждый столбец соответствует файлу с тем же набором из 38 627 карт, от lossless (3,61 GB) до AV1 на crf60 (230 MB), по возрастанию сжатия.
Вверху обе линии drift падают на всём протяжении и пересекают gate floor уже на втором файле. Внизу поиск остаётся ровным до crf50: зелёные столбцы лежат в пределах одной стандартной ошибки от lossless; пунктир отмечает, где поиск проседает, а красные столбцы соответствуют файлам после него.
| файл | размер | drift p10 | txt@1 | ±1 стандартная ошибка | z vs lossless |
|---|---|---|---|---|---|
| lossless | 3,61 GB | 0,9968 | 0,092 | 0,0091 | 0,00 |
| neardup | 1,37 GB | 0,9666 | 0,096 | 0,0093 | 0,31 |
| avif q48 | 1,2 GB | 0,9680 | 0,096 | 0,0093 | 0,31 |
| crf40 | 981 MB | 0,9594 | 0,089 | 0,0090 | -0,23 |
| crf50 | 533 MB | 0,9389 | 0,093 | 0,0092 | 0,08 |
| crf55 | 370 MB | 0,9211 | 0,074 | 0,0083 | -1,46 |
| crf60 | 230 MB | 0,8866 | 0,069 | 0,0080 | -1,89 |
запросов на файл: 1 000, во всех файлах одни и те же карты; стандартная ошибка биномиальная; z показывает, на сколько объединённых стандартных ошибок txt@1 каждого файла отличается от lossless: до crf50 включительно ни один не превышает 1.
измерено 2026-09-12 · benchmark/experiments/14-utility-ladder/results.json
curl -sSf https://raw.githubusercontent.com/hoffresearch/urna/main/scripts/install.sh | sh
urna setupurna build --spec corpus.tomlurna ask corpus.urna "работает офлайн?" -k 3urna retrieve corpus.urna "работает офлайн?" -k 5 --format jsonlimport urna
from urna.embed_potion import potion_embedder
emb, db = potion_embedder(), urna.open("corpus.urna")
qvec = emb.embed_texts(["работает офлайн?"])[0]
hits = db.retrieve(qvec, 5, expected_model_hash=emb.model_hash())urna validate corpus.urnaurna cite corpus.urna "urna://content_hash/chunk_id"urna benchmark corpus.urna -q 100 -k 10 --ann 100Один релиз, любой пакетный менеджер
npx @urna/cli validate corpus.urnauvx --from urna urna validate corpus.urnacargo binstall urnaТри группы команд и экран для работы


На входе файл и вектор, на выходе результаты. Без Python.
- inspect
- validate
- stats
- media
- search
- search-ann
- search-graph
- search-space
- search-text
- benchmark
- cite
- doctor
На входе текст или спецификация, на выходе ответы с цитатами, через офлайн-embedder на Python.
- ask
- retrieve
- build
Установщик, которым заканчивается любой канал, и обозреватель в терминале.
- setup
- tui