Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Примечание
Поиск с использованием ИИ Azure доступна через портал Azure, REST API и Azure SDKs. Он также лежит в основе Foundry IQ — управляемого слоя знаний, который преобразует корпоративный контент в многократно используемые базы знаний с учетом разрешений доступа для агентов на портале Microsoft Foundry.
Примечание
strictPostFilter в настоящее время находится в режиме предварительной версии. Эта предварительная версия предоставляется без соглашения об уровне обслуживания и не рекомендуется для рабочих задач в производственной среде. Некоторые функции могут не поддерживаться или могут иметь ограниченные возможности. Дополнительные сведения см. в разделе Supplemental Terms of Use for Microsoft Azure Previews.
prefilter и postfilter общедоступны в последней стабильной версии REST API.
В Поиск с использованием ИИ Azure можно использовать выражение filter для добавления условий включения или исключения в запрос vector. Можно также указать режим фильтрации, который применяет фильтр:
- Перед выполнением запроса, известное как префильтровка.
- После выполнения запроса, известного как postfiltering.
- После определения глобальных результатов, известных как строгая
постфильтрация (предварительный просмотр).
В этой статье используется REST для иллюстрации. Примеры кода на других языках и комплексные решения, включающие векторные запросы, см. в репозитории azure-search-vector-samples GitHub.
Вы также можете использовать Search Explorer на портале Azure для запроса векторного содержимого. В представлении JSON можно добавить фильтры и указать режим фильтра.
Принцип работы фильтрации в векторных запросах
Поиск с использованием ИИ Azure использует алгоритм иерархического навигационного небольшого мира (HNSW) для поиска приблизительного ближайшего соседа (ANN), сохраняя графы HNSW в нескольких сегментах. Каждый сегмент содержит часть всего индекса.
Фильтры применяются к filterableневекторным полям( строковым или числовым), чтобы включить или исключить документы поиска на основе критериев фильтра. Векторные поля сами по себе не фильтруются, но можно использовать фильтры для других полей в том же индексе, чтобы сузить документы, которые рассматриваются для поиска векторов. Если индекс не имеет подходящих текстовых или числовых полей, проверьте метаданные документа, которые могут помочь с фильтрацией, например LastModified или CreatedBy свойствами.
Параметр vectorFilterMode управляет применением операций фильтрации на этапах поиска, что влияет на то, как результаты фильтруются в подмножество элементов (например, по категориям, тегам или другим атрибутам) и влияют на задержку, отзыв и пропускную способность. Существует три режима:
preFilterПрименяет фильтр во время обхода HNSW на каждом сегменте. Этот режим максимально увеличивает полноту, но может задействовать больше графа, увеличивая нагрузку на процессор и задержку для высокоселективных фильтров.postFilterвыполняет обход HNSW и фильтрацию по каждому шарду независимо, пересекает результаты на уровне шарда, а затем агрегирует топkиз каждого шарда в глобальный топk. Этот режим может создавать ложные отрицательные значения для высокоизбирательных фильтров или небольшихkзначений.strictPostFilter(предварительная версия) находит нефильтрованную глобальную вершинуkперед применением фильтра. Этот режим имеет самый высокий риск возврата ложных отрицательных значений для высокоизбирательных фильтров и небольшихkзначений.
Дополнительные сведения об этих режимах см. в разделе "Настройка режима фильтра".
Определение фильтра
Фильтры определяют область векторных запросов и задаются с помощью Documents — Search Post (REST API). Если вы не хотите использовать функцию предварительной версии, используйте последнюю стабильную версию REST API службы поиска для формирования запроса.
Этот REST API предоставляет следующие возможности:
-
filterдля критериев. -
vectorFilterMode, чтобы указать, когда фильтр применяется во время векторного запроса. Поддерживаемые режимы см. в разделе "Настройка режима фильтра".
POST https://{search-endpoint}/indexes/{index-name}/docs/search?api-version={api-version}
Content-Type: application/json
api-key: {admin-api-key}
{
"count": true,
"select": "title, content, category",
"filter": "category eq 'Databases'",
"vectorFilterMode": "preFilter",
"vectorQueries": [
{
"kind": "vector",
"vector": [
-0.009154141,
0.018708462,
. . . // Trimmed for readability
-0.02178128,
-0.00086512347
],
"fields": "contentVector",
"k": 50
}
]
}
В этом примере векторное внедрение нацелено на поле contentVector, а критерии фильтрации применяются к текстовому полю category, поддерживающему фильтрацию. Поскольку используется режим preFilter, фильтр применяется перед тем, как поисковая система выполнит запрос, поэтому во время векторного поиска рассматриваются только документы категории Databases.
Настройка режима фильтра
Параметр vectorFilterMode определяет, когда и как фильтр применяется относительно выполнения векторного запроса. Можно использовать следующие режимы:
-
preFilter(рекомендуется) postFilter-
strictPostFilter(предварительная версия)
Примечание
preFilter — значение по умолчанию для индексов, созданных примерно после 15 октября 2023 г. Для индексов, созданных до этой даты, postFilter используется значение по умолчанию. Чтобы использовать preFilter и другие расширенные векторные функции, такие как сжатие векторов, необходимо повторно создать индекс.
Вы можете проверить совместимость, отправив векторный запрос с "vectorFilterMode": "preFilter"2023-10-01-preview версией REST API или более поздней. Ваш индекс не поддерживает preFilter, если запрос завершается ошибкой.
Префиксирование применяет фильтры перед выполнением запроса, что сокращает набор кандидатов для алгоритма векторного поиска. Затем из этого отфильтрованного набора выбираются лучшиеk результаты.
В векторном запросе используется режим по умолчанию, preFilter так как он предпочитает отзыв и качество по сравнению с задержкой.
Как работает этот режим
На каждом шарде примените предикат фильтра во время обхода HNSW, расширяя граф до тех пор, пока не будут найдены
kкандидаты.Произвести предфильтрованные локальные результаты для каждого шарда.
Агрегировать отфильтрованные результаты в глобальный топ-
kрезультирующий набор.
Эффект этого режима
Обход расширяет поверхность поиска, чтобы найти больше отфильтрованных кандидатов, особенно если фильтр выборочный. Это создает наиболее похожие top-k результаты во всех шардах. Каждый сегмент определяет k результаты, удовлетворяющие предикату фильтра.
Предварительная фильтрация гарантирует, что результаты возвращаются, если они существуют в индексе k. Для высоко избирательных фильтров это может привести к тому, что будет проанализирована значительная часть графа, что увеличивает затраты на вычисления и задержку, снижая пропускную способность. Если фильтр является очень выборочным (имеет очень мало совпадений), рассмотрите возможность exhaustive: true использования для выполнения исчерпывающего поиска.
Таблица сравнения
| Режим | Отзыв (отфильтрованные результаты) | Вычислительные затраты | Риск ложных отрицательных значений | Когда следует использовать |
|---|---|---|---|---|
preFilter |
Очень высокий | Выше (увеличивается с выбором селективности фильтра и возрастанием сложности) | Нет риска |
Рекомендуется по умолчанию для всех сценариев, особенно когда важен высокий уровень восстановления (чувствительные домены поиска), при использовании выборочных фильтров или при использовании небольших k. |
postFilter |
Средний и высокий (уменьшается при выборе фильтра) | Аналогично нефильтрованным, но увеличивается сложность фильтра | Умеренный (может пропустить совпадения на сегмент) | Вариант фильтров, которые не слишком строгие и для более сложныхk запросов. |
strictPostFilter |
Наименьший (уменьшается быстрее при выборе фильтра) | Аналогично нефильтрованным | Максимальное (может возвращать нулевой результат для выборочного фильтра или небольшого k) |
Вариант для фасетных приложений поиска, когда появление большего количества результатов после применения фильтров влияет на пользовательский опыт больше, чем риск ложных отрицательных результатов. Не используйте с небольшими k. |
Тестирование префильтрации и постфильтрации
Важно
Этот раздел относится к префильтрации и послефильтрации, а не строгой послефильтрации.
Чтобы понять условия, при которых один режим фильтрации работает лучше, чем другой, мы выполнили ряд тестов для оценки результатов запроса по небольшим, средним и большим индексам.
- Малый (100 000 документов, индекс 2,5 ГБ, 1 536 измерений)
- Средний (1 миллион документов, индекс 25 ГБ, 1 536 измерений)
- Большой объем (1 миллиард документов, индекс 1,9 ТБ, 96 измерений)
Для небольших и средних рабочих нагрузок мы использовали службу Standard 2 (S2) с одной секцией и одной репликой. Для большой рабочей нагрузки мы использовали службу Standard 3 (S3) с 12 секциями и одной репликой.
Индексы имели идентичное построение: одно ключевое поле, одно векторное поле, одно текстовое поле и одно числовое фильтруемое поле. Следующий индекс определяется с помощью синтаксиса 2023-11-01 .
def get_index_schema(self, index_name, dimensions):
return {
"name": index_name,
"fields": [
{"name": "id", "type": "Edm.String", "key": True, "searchable": True},
{"name": "content_vector", "type": "Collection(Edm.Single)", "dimensions": dimensions,
"searchable": True, "retrievable": True, "filterable": False, "facetable": False, "sortable": False,
"vectorSearchProfile": "defaulthnsw"},
{"name": "text", "type": "Edm.String", "searchable": True, "filterable": False, "retrievable": True,
"sortable": False, "facetable": False},
{"name": "score", "type": "Edm.Double", "searchable": False, "filterable": True,
"retrievable": True, "sortable": True, "facetable": True}
],
"vectorSearch": {
"algorithms": [
{
"name": "defaulthnsw",
"kind": "hnsw",
"hnswParameters": { "metric": "euclidean" }
}
],
"profiles": [
{
"name": "defaulthnsw",
"algorithm": "defaulthnsw"
}
]
}
}
В запросах мы использовали идентичный фильтр как для операций префильтра, так и для постфильтра. Мы использовали простой фильтр, чтобы гарантировать, что вариации производительности были вызваны режимом фильтрации, а не сложностью фильтрации.
Результаты измерялись в запросах в секунду (QPS).
Основные выводы
Префильтрация почти всегда медленнее, чем послефильтровка, за исключением небольших индексов, где производительность приблизительно равна.
При более крупных наборах данных префильтровка значительно медленнее.
Почему префильтр используется по умолчанию, если он почти всегда медленнее? Предфильтрация гарантирует, что
kрезультаты возвращаются, если они существуют в индексе, причем предпочтение отдается полноте и точности, а не скорости.Используйте постфильтрацию, если:
Отдайте предпочтение скорости, а не выбору (после фильтрации может вернуть меньше
kрезультатов).Используйте фильтры, которые не являются чрезмерно выборочными.
Имеют индексы достаточного размера, так что производительность префильтрации становится неприемлемой.
Детали
Учитывая набор данных с 100 000 векторами в 1536 измерениях:
При фильтрации более 30% набора данных предварительная и последующая фильтрация были сопоставимыми.
При фильтрации менее 0,1% набора данных предварительная фильтрация составила около 50% медленнее, чем послефильтровка.
Учитывая набор данных с 1 миллионами векторов с 1536 измерениями:
При фильтрации более 30% набора данных предварительная фильтрация была около 30% медленнее.
При фильтрации менее 2% набора данных предварительная фильтрация была примерно в семь раз медленнее.
Учитывая набор данных с 1 миллиардами векторов на 96 измерениях:
При фильтрации более 5% набора данных предварительная фильтрация составила около 50% медленнее.
При фильтрации менее 10% набора данных предварительная фильтрация была примерно в семь раз медленнее.
На следующем графике показано относительное значение QPS до фильтрации, вычисляемое как QPS до фильтра разделенное на QPS после фильтрации.
Вертикальная ось представляет относительную производительность префильтрации по сравнению с постфильтрированием, выраженным в виде соотношения QPS (запросов в секунду). Например:
- Значение
0.0означает, что префильтровка составляет 100% медленнее, чем послефильтровка. - Значение
0.5означает, что префильтровка на 50% медленнее. - Значение
1.0означает, что предварительная фильтрация и постфильтрация эквивалентны.
Горизонтальная ось представляет скорость фильтрации или процент кандидатных документов после применения фильтра. Например, показатель 1.00% означает, что выбранные критерии фильтра выбрали один процент от корпуса поиска.