Гайд · TNWS AI

Как создать tensor-поле embeddings в Vespa и проверить размерность

4 мин—

Схема Vespa для tensor<float>, размерность, индекс HNSW и воспроизводимая проверка совместимости embeddings с запросами.

Какую задачу решаем и где применимо

Русскоязычный поисковый запрос: «как создать tensor поле embedding Vespa». Материал проверен по официальной документации Vespa, актуальной на 19 сентября 2026 года. Подходит приложению Vespa с собственной схемой документов и заранее выбранной embedding-моделью. В примере размерность 3 нужна только для наглядного ручного теста; в боевом проекте берите действительную размерность модели, а не копируйте тройку.

Tensor tensor<float>(x[3]) задаёт фиксированную ось. attribute хранит поле для вычисления расстояния; добавление index включает HNSW-поиск по этому полю. distance-metric: angular выбирается на уровне attribute. В отличие от обычного текстового индекса, значение поля должно быть числовым вектором, созданным одной и той же моделью и предобработкой для документов и вопросов.

До начала эксперимента подготовьте маленький набор документов с известными source_id и один отрицательный пример. Сохраните версию schema, embedding-модели, набор входных вопросов и ожидаемые IDs: так результат можно воспроизвести после обновления системы, а не оценивать по одному удачному ответу. Все значения для маленького tensor в шаблоне — иллюстрация контрактов, не показатели качества модели.

Пошаговое выполнение

  1. Зафиксируйте версию модели, её реальную dimension и правило нормализации текста в manifest корпуса.
  2. Создайте схему article с документными полями source_id, text, embedding; текст и источник сохраняйте отдельно от вектора.
  3. Добавьте attribute | index для tensor и явно укажите distance metric. Разворачивайте изменение сначала в тестовом приложении.
  4. Загрузите два canary-документа длины 3, затем попробуйте документ длины 2 и запишите ошибку как отрицательный тест.
  5. Выполните nearestNeighbor-запрос с query tensor той же длины и проверьте source_id результата.

Эти шаги предполагают доступ к собственному тестовому приложению Vespa. Для Vespa Cloud и самостоятельной установки способы деплоя отличаются; не угадывайте имена кнопок консоли. Используйте показанный интерфейс schema, YQL или CLI, сверяя конкретное окружение и permissions с документацией. При деплое сохраняйте предыдущее определение, чтобы сопоставить результаты и откатить неудачное изменение без смешения двух причин.

Готовый шаблон

schema article {
  document article {
    field source_id type string { indexing: summary | attribute }
    field text type string { indexing: summary | index }
    field embedding type tensor<float>(x[3]) {
      indexing: attribute | index
      attribute { distance-metric: angular }
    }
  }
  rank-profile semantic {
    inputs { query(q) tensor<float>(x[3]) }
    first-phase { expression: closeness(field, embedding) }
  }
}

Шаблон адаптируйте к своей размерности и именам документов. Если он содержит ручной трёхмерный вектор, он полезен для smoke-теста схемы и синтаксиса, но не заменяет настоящий embedding вопроса. Секреты провайдера, токены Vespa и данные закрытых клиентов не вставляйте ни в публичный prompt, ни в статью, ни в логи запроса.

Конкретный вход и ожидаемый выход

Вход: refund:1 с embedding [0.1,0.2,0.3], shipping:1 с [0.7,0.0,0.2]; запрос также содержит три числа. Ожидается принимаемая схема, сохраняемые оба source_id и результат запроса без ошибки типа. Этот игрушечный вектор не обещает конкретного семантического порядка: он только проверяет контракт типов.

Если интерфейс поставщика embedding-модели возвращает иной размер, не меняйте ось ради одного документа. Спланируйте новое versioned поле либо отдельную схему, пересчитайте весь корпус, а переключение выполняйте только после сравнения качества. Нельзя смешивать русскоязычные и англоязычные кодировки текста с разными шаблонами query: и passage: у модели, если её инструкция различает эти режимы. Числовое совпадение dimension ещё не означает совместимости геометрии. Обязательный canary должен подтверждать и доступность поля, и ожидаемую релевантность на разметке. Следите отдельно за расходом памяти: сам tensor, HNSW-граф и сохранённый текст имеют разные профили использования ресурсов.

Проверка результата

  • Реальная размерность в manifest равна типу x[n] и длине каждой записи.
  • Неверная длина обнаруживается до загрузки всего датасета.
  • Query tensor определён в rank-profile с тем же типом.
  • Исходный текст и source_id доступны независимо от embedding.

Успех означает прохождение всех перечисленных пунктов на положительных и отрицательных кейсах. Снимите фактические IDs, число hits и latency до и после изменения; если есть LLM-ответ, проверьте цитаты вручную. Пустой результат из-за ошибки типов, времени ожидания, прав доступа или отсутствующей записи нельзя выдавать за низкую релевантность. Удобно хранить отдельный отчёт по каждым case_id, иначе невозможно обнаружить регрессию на редких формулировках.

Типичные ошибки: чего не делать

  • Подставлять размерность популярной чужой модели по памяти.
  • Смешивать старую и новую версии модели в одном поле.
  • Считать успешную загрузку доказательством правильного порядка выдачи.

Не исправляйте нерелевантную выдачу произвольным повышением top-k: сперва отделите ошибку модели, схемы, фильтра и ранжирования. Не отключайте проверку tenant ради красивого теста. Не делайте вывод о производительности на крошечном демонстрационном корпусе; проверяйте рабочий объём, конкурентную нагрузку и p95, а также расход памяти/скорость обновлений там, где они существенно меняются.

FAQ

Нужно ли поле index для HNSW?

Да, вместе с attribute для индексированного ANN-поиска.

Можно ли хранить только embedding?

Можно, но для RAG нужен проверяемый source_id и исходный текст.

Векторы разной длины допустимы?

Нет для одного поля с фиксированной осью x[n].

Официальные источники

Частые вопросы

Нужно ли поле `index` для HNSW?

Да, вместе с `attribute` для индексированного ANN-поиска.

Можно ли хранить только embedding?

Можно, но для RAG нужен проверяемый source_id и исходный текст.

Векторы разной длины допустимы?

Нет для одного поля с фиксированной осью `x[n]`.

Читайте также

Комментарии

Пока тихо. Скажите первое слово