Поделиться через


Создание векторного индекса

В службе "Поиск ИИ Azure" можно использовать создание или обновление индекса (REST API) для хранения векторов в индексе поиска. Индекс вектора определяется схемой индекса, которая содержит векторные поля, невекторные поля и раздел конфигурации вектора.

При создании векторного индекса неявно создается пространство внедрения , которое служит корпусом для векторных запросов. Пространство встраивания состоит из всех полей векторов, заполненных встраиваниями из одной и той же модели встраивания. Во время запроса система сравнивает векторный запрос с индексированными векторами, возвращая результаты на основе семантического сходства.

Чтобы индексировать векторы в Службе поиска ИИ Azure, выполните следующие действия.

  • Начните с базового определения схемы.
  • Добавьте векторные алгоритмы и необязательное сжатие.
  • Добавьте определения полей вектора.
  • Загрузите предварительно векторизованные данные как отдельную задачу или используйте интегрированную векторизацию для обработки и внедрения данных при индексировании.

В этой статье используется REST для иллюстрации. После понимания базового рабочего процесса перейдите к примерам кода пакета SDK Azure в репозитории azure-search-vector-samples , который содержит рекомендации по использованию векторов в тестовом и рабочем коде.

Совет

Вы также можете использовать портал Azure для создания векторного индекса и пробного анализа интегрированных блоков данных и векторизации.

Необходимые компоненты

  • Служба поиска ИИ Azure в любом регионе и на любом уровне. Если вы планируете использовать интегрированную векторизацию с навыками и векторизаторами ИИ Azure, поиск ИИ Azure должен находиться в том же регионе, что и модели внедрения, размещенные в Azure AI Vision.

  • Исходные документы должны иметь векторные внедрения для отправки в индекс. Для этого шага также можно использовать встроенную векторизацию .

  • Необходимо знать ограничение размеров модели, создающей встраивания, чтобы можно было установить это ограничение векторному полю. Для text-embedding-ada-002 размерность фиксирована на уровне 1536. Для внедрения текстового встраивания-3-small или внедрения текстового встраивания-3-large размерности варьируются от 1 до 1536 и от 1 до 3072 соответственно.

  • Вы должны знать, какую метрику сходства следует использовать. Для внедрения моделей в Azure OpenAI сходство вычисляется с помощью cosine.

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

Ограничения

Некоторые службы поиска, созданные до января 2019 года, не могут создать векторный индекс. Если это относится к вам, создайте новую службу для использования векторов.

Подготовка документов к индексации

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

Убедитесь, что исходные документы предоставляют следующее содержимое:

Содержимое Описание
Уникальный идентификатор Поле или свойство метаданных, однозначно идентифицирующее каждый документ. Для всех индексов поиска требуется ключ документа. Чтобы удовлетворить требования к ключу документа, исходный документ должен иметь одно поле или свойство, которое уникально идентифицирует его в индексе. Если вы индексируете большие двоичные объекты, это может быть metadata_storage_path, который однозначно идентифицирует каждый большой двоичный объект. Если индексация выполняется из базы данных, это может быть первичный ключ. Это исходное поле должно быть сопоставлено с полем индекса типа Edm.String и key=true в индексе поиска.
Содержимое, отличное от вектора Предоставьте другие поля с содержимым, доступным для чтения человеком. Доступное для чтения пользователем содержимое полезно для ответа запроса и для гибридных запросов , которые включают полнотекстовый поиск или семантический рейтинг в том же запросе. Если вы используете модель завершения чата, большинство моделей, таких как ChatGPT, ожидают читаемый пользователем текст и не принимают необработанные векторы в качестве входных данных.
Векторный контент Векторное представление не векторного содержимого для использования в момент выполнения запроса. Вектор — это массив чисел с плавающей запятой с одной точностью, создаваемых моделью внедрения. Каждое поле вектора содержит созданный моделью массив. Существует одно внедрение для каждого поля, где поле является полем верхнего уровня (не частью вложенного или сложного типа). Для простой интеграции рекомендуется внедрить модели в Azure OpenAI, например text-embedding-3 для текстовых документов или REST API извлечения изображений для изображений и многомодальных внедрения.

Если вы можете использовать индексаторы и наборы навыков, рассмотрите возможность интегрированной векторизации, которая кодирует изображения и текст во время индексирования. Определения полей предназначены для векторных полей, но входящие исходные данные могут быть текстом или изображениями, которые преобразуются в векторные массивы во время индексирования.

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

Краткий пример полезной нагрузки документов, включающей векторные и невекторные поля, см. в разделе загрузки векторных данных этой статьи.

Начните с базового индекса

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

Обратите внимание, что индекс имеет требуемое имя, обязательный ключ документа ("key": true) и поля для читаемого пользователем содержимого в виде обычного текста. Обычно есть читаемая для человека версия любого содержимого, который вы планируете векторизировать. Например, если у вас есть фрагмент текста из PDF-файла, схема индекса должна иметь поле для блоков обычного текста и второе поле для векторизованных блоков.

Ниже приведен базовый индекс с "name""fields" коллекцией и некоторыми другими конструкциями для дополнительной конфигурации:

POST https://[servicename].search.windows.net/indexes?api-version=[api-version] 
{
  "name": "example-index",
  "fields": [
    { "name": "documentId", "type": "Edm.String", "key": true, "retrievable": true, "searchable": true, "filterable": true },
    { "name": "myHumanReadableNameField", "type": "Edm.String", "retrievable": true, "searchable": true, "filterable": false, "sortable": true, "facetable": false },
    { "name": "myHumanReadableContentField", "type": "Edm.String", "retrievable": true, "searchable": true, "filterable": false, "sortable": false, "facetable": false, "analyzer": "en.microsoft" },
  ],
  "analyzers": [ ],
  "scoringProfiles": [ ],
  "suggesters": [ ],
  "vectorSearch": [ ]
}

Добавление конфигурации векторного поиска

Затем добавьте конфигурацию "vectorSearch" в вашу схему. Полезно указать конфигурацию перед определениями полей, так как профили, которые вы определяете здесь, становятся частью определения векторного поля. В схеме векторная конфигурация обычно вставляется после коллекции полей, возможно, после "analyzers""scoringProfiles"и"suggesters". Однако порядок не имеет значения.

Векторная конфигурация включает:

  • vectorSearch.algorithms используется во время индексирования для создания сведений о ближайших соседах между векторными узлами.
  • vectorSearch.compressions для скалярной или двоичной квантизации, пересэмплирования и повторной ранжировки с использованием исходных векторов.
  • vectorSearch.profiles для указания нескольких сочетаний конфигураций алгоритма и сжатия.

Общедоступна версия 2024-07-01 . Она поддерживает конфигурацию вектора, которая имеет следующие возможности:

  • Алгоритм Hierarchical Navigable Small World (HNSW).
  • Полный алгоритм K-ближайших соседей (KNN).
  • Скалярное сжатие.
  • Двоичное сжатие, доступное только в 2024-07-01 и более новых пакетах Пакета SDK Azure.
  • Передискретизация.
  • Перераспределение с использованием исходных векторов.

Если вы выберете HNSW в поле, вы можете выбрать исчерпывающий KNN во время запроса. Однако противоположность не работает. Если вы выберете исчерпывающий вариант для индексирования, вы не сможете позже запросить поиск HNSW, так как дополнительные структуры данных, обеспечивающие приблизительный поиск, не существуют.

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

  1. Используйте REST API создания или обновления индекса для создания индекса.

  2. vectorSearch Добавьте раздел в индекс, указывающий алгоритмы поиска, используемые для создания пространства внедрения.

     "vectorSearch": {
         "compressions": [
             {
                 "name": "scalar-quantization",
                 "kind": "scalarQuantization",
                 "rerankWithOriginalVectors": true,
                 "defaultOversampling": 10.0,
                     "scalarQuantizationParameters": {
                         "quantizedDataType": "int8"
                     }
             },
             {
                 "name": "binary-quantization",
                 "kind": "binaryQuantization",
                 "rerankWithOriginalVectors": true,
                 "defaultOversampling": 10.0
             }
         ],
         "algorithms": [
             {
                 "name": "hnsw-1",
                 "kind": "hnsw",
                 "hnswParameters": {
                     "m": 4,
                     "efConstruction": 400,
                     "efSearch": 500,
                     "metric": "cosine"
                 }
             },
             {
                 "name": "hnsw-2",
                 "kind": "hnsw",
                 "hnswParameters": {
                     "m": 8,
                     "efConstruction": 800,
                     "efSearch": 800,
                     "metric": "hamming"
                 }
             },
             {
                 "name": "eknn",
                 "kind": "exhaustiveKnn",
                 "exhaustiveKnnParameters": {
                     "metric": "euclidean"
                 }
             }
    
         ],
         "profiles": [
           {
             "name": "vector-profile-hnsw-scalar",
             "compression": "scalar-quantization",
             "algorithm": "hnsw-1"
           }
         ]
     }
    

    Ключевые моменты:

    • Имена для каждой конфигурации сжатия, алгоритма и профиля должны быть уникальными для его типа в индексе.

    • vectorSearch.compressions может иметь значение scalarQuantization или binaryQuantization. Скалярная квантизация сжимает значения с плавающей запятой в более узкие типы данных. Двоичная квантизация преобразует floats в двоичные 1-разрядные значения.

    • vectorSearch.compressions.rerankWithOriginalVectors использует исходные несжатые векторы для пересчета сходства и повторного вычисления верхних результатов, возвращаемых первоначальным поисковым запросом. Несжатые векторы существуют в индексе поиска, даже если stored значение false. Это необязательное свойство. Значение по умолчанию — "истина".

    • vectorSearch.compressions.defaultOversampling рассматривает более широкий набор потенциальных результатов для смещения сокращения информации от квантизации. Формула для потенциальных результатов состоит из k запроса с чрезмерным умножением. Например, если запрос указывает k значение 5, а перевыбор составляет 20, то запрос фактически требует 100 документов для повторного ранжирования, используя исходный несжатый вектор для этой цели. Возвращаются только самые лучшие k результаты. Это необязательное свойство. Значение по умолчанию — 4.

    • Для параметра vectorSearch.compressions.scalarQuantizationParameters.quantizedDataType нужно задать значение int8. Это единственный примитивный тип данных, поддерживаемый в настоящее время. Это необязательное свойство. По умолчанию — int8.

    • vectorSearch.algorithms имеет значение hnsw или exhaustiveKnn. Это алгоритмы приблизительных ближайших соседей (ANN), используемые для упорядочивания векторного содержимого во время индексирования.

    • vectorSearch.algorithms.m — это число двунаправленных ссылок. Значение по умолчанию — 4. Диапазон составляет от 4 до 10. Более низкие значения должны возвращать меньше шума в результатах.

    • vectorSearch.algorithms.efConstruction — это число ближайших соседей, используемых во время индексирования. Значение по умолчанию — 400. Диапазон составляет от 100 до 1000.

    • "vectorSearch.algorithms.efSearch — это число ближайших соседей, используемых во время поиска. Значение по умолчанию — 500. Диапазон составляет от 100 до 1000.

    • vectorSearch.algorithms.metric должно быть cosine, если вы используете Azure OpenAI, в противном случае используйте метрику сходства, связанную с моделью отображения, которую вы используете. Поддерживаемые значения: cosine, dotProducteuclideanи hamming (используется для индексирования двоичных данных).

    • vectorSearch.profiles добавьте слой абстракции для размещения более богатых определений. Профиль определён в vectorSearch и ссылка по имени делается в каждом векторном поле. Это сочетание конфигураций сжатия и алгоритмов. Это свойство назначается векторным полям и определяет алгоритм и сжатие полей.

Добавление векторного поля в коллекцию полей

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

Поля векторов характеризуются их типом данных, свойством на основе модели внедрения, dimensions используемой для вывода векторов, и профиля вектора, созданного на предыдущем шаге.

Общедоступна версия 2024-07-01 .

  1. Используйте REST API создания или обновления индекса , чтобы создать индекс и добавить поле вектора в коллекцию полей.

    {
      "name": "example-index",
      "fields": [
        {
            "name": "contentVector",
            "type": "Collection(Edm.Single)",
            "searchable": true,
            "retrievable": false,
            "stored": false,
            "dimensions": 1536,
            "vectorSearchProfile": "vector-profile-1"
        }
      ]
    }
    
  2. Укажите поле вектора со следующими атрибутами. Вы можете сохранить одно созданное внедрение на поле. Для каждого поля вектора:

    • type должен быть типом векторных данных. Collection(Edm.Single) является наиболее распространенным для внедрения моделей.
    • dimensions — это количество измерений, созданных моделью внедрения. Для преобразования текста в ada-002 исправлено значение 1536. Для ряда моделей внедрения текста-3 существует диапазон значений. Если вы используете встроенную векторизацию и навык внедрения для создания векторов, убедитесь, что это свойство имеет то же значение измерений , которое используется навыком внедрения.
    • vectorSearchProfile — это имя профиля, определенного в другом месте индекса.
    • searchable должно быть true.
    • retrievable может иметь значение true или false. True возвращает необработанные векторы (1536 из них) в виде обычного текста и потребляет место в хранилище. Задайте значение true, если вы передаете результат вектора в нижнее приложение.
    • stored может иметь значение true или false. Он определяет, хранится ли дополнительная копия векторов для извлечения. Дополнительные сведения см. в разделе "Уменьшение размера вектора".
    • filterable, facetableи sortable должен иметь значение false.
  3. Добавьте в коллекцию доступные для фильтрации поля, не являющиеся векторами, например, title, для которого filterable установлено в true, если вы хотите вызвать префильтрацию или постфильтрацию в векторном запросе.

  4. Добавьте другие поля, определяющие вещество и структуру индексированного содержимого. Как минимум, вам нужен ключ документа.

    Кроме того, следует добавить поля, полезные в запросе или в ответе. В следующем примере показаны векторные поля заголовка и содержимого (titleVector и contentVector), эквивалентные векторам. Он также предоставляет поля для эквивалентного текстового содержимого (title и content) которые полезны для сортировки, фильтрации и чтения в результатах поиска.

    В следующем примере показана коллекция полей:

    PUT https://my-search-service.search.windows.net/indexes/my-index?api-version=2024-07-01&allowIndexDowntime=true
    Content-Type: application/json
    api-key: {{admin-api-key}}
    {
        "name": "{{index-name}}",
        "fields": [
            {
                "name": "id",
                "type": "Edm.String",
                "key": true,
                "filterable": true
            },
            {
                "name": "title",
                "type": "Edm.String",
                "searchable": true,
                "filterable": true,
                "sortable": true,
                "retrievable": true
            },
            {
                "name": "titleVector",
                "type": "Collection(Edm.Single)",
                "searchable": true,
                "retrievable": true,
                "stored": true,
                "dimensions": 1536,
                "vectorSearchProfile": "vector-profile-1"
            },
            {
                "name": "content",
                "type": "Edm.String",
                "searchable": true,
                "retrievable": true
            },
            {
                "name": "contentVector",
                "type": "Collection(Edm.Single)",
                "searchable": true,
                "retrievable": false,
                "stored": false,
                "dimensions": 1536,
                "vectorSearchProfile": "vector-profile-1"
            }
        ],
        "vectorSearch": {
            "algorithms": [
                {
                    "name": "hnsw-1",
                    "kind": "hnsw",
                    "hnswParameters": {
                        "m": 4,
                        "efConstruction": 400,
                        "efSearch": 500,
                        "metric": "cosine"
                    }
                }
            ],
            "profiles": [
                {
                    "name": "vector-profile-1",
                    "algorithm": "hnsw-1"
                }
            ]
        }
    }
    

Загрузка векторных данных для индексирования

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

Для приема данных можно использовать методы push или pull.

Использование документов — индекс для загрузки векторных и невекторных данных в индекс. API push-уведомлений для индексирования идентичны во всех стабильных и предварительных версиях. Используйте любой из следующих API для загрузки документов:

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/index?api-version=2024-07-01

{
    "value": [
        {
            "id": "1",
            "title": "Azure App Service",
            "content": "Azure App Service is a fully managed platform for building, deploying, and scaling web apps. You can host web apps, mobile app backends, and RESTful APIs. It supports a variety of programming languages and frameworks, such as .NET, Java, Node.js, Python, and PHP. The service offers built-in auto-scaling and load balancing capabilities. It also provides integration with other Azure services, such as Azure DevOps, GitHub, and Bitbucket.",
            "category": "Web",
            "titleVector": [
                -0.02250031754374504,
                 . . . 
                        ],
            "contentVector": [
                -0.024740582332015038,
                 . . .
            ],
            "@search.action": "upload"
        },
        {
            "id": "2",
            "title": "Azure Functions",
            "content": "Azure Functions is a serverless compute service that enables you to run code on-demand without having to manage infrastructure. It allows you to build and deploy event-driven applications that automatically scale with your workload. Functions support various languages, including C#, F#, Node.js, Python, and Java. It offers a variety of triggers and bindings to integrate with other Azure services and external services. You only pay for the compute time you consume.",
            "category": "Compute",
            "titleVector": [
                -0.020159931853413582,
                . . .
            ],
            "contentVector": [
                -0.02780858241021633,
                 . . .
            ],
            "@search.action": "upload"
        }
        . . .
    ]
}

Выполните запрос в вашем индексе на векторное содержимое

Для проверки можно запросить индекс с помощью обозревателя поиска в портал Azure или вызове REST API. Так как поиск по искусственному интеллекту Azure не может преобразовать вектор в удобочитаемый пользователем текст, попробуйте вернуть поля из того же документа, который предоставляет доказательства соответствия. Например, если векторный запрос предназначен для поля titleVector, можно выбрать title для результатов поиска.

Чтобы поля были включены в результаты, они должны быть обозначены как retrievable.

  • Просмотрите индексы в управлении поиском>Индексы, чтобы увидеть размер индекса в целом и размер векторного индекса. Положительный размер индекса вектора указывает на наличие векторов.

  • Используйте обозреватель поиска для запроса индекса. Обозреватель поиска имеет два представления: представление запросов (по умолчанию) и представление JSON.

    • Задайте параметры> запросаСкрыть векторные значения в результатах поиска для получения более доступных для чтения результатов.

    • Используйте представление JSON для векторных запросов. Вы можете вставить определение JSON векторного запроса, который требуется выполнить. Если индекс имеет назначение векторизатора, можно также использовать встроенное преобразование текста в вектор или изображения в вектор. Дополнительные сведения о поиске изображений см. в кратком руководстве. Поиск изображений в обозревателе поиска.

    • Используйте представление запроса по умолчанию для быстрого подтверждения того, что индекс содержит векторы. Режим запроса предназначен для полнотекстового поиска. Хотя его нельзя использовать для векторных запросов, можно отправить пустой поиск (search=*) для проверки содержимого. Содержимое всех полей, включая векторные поля, возвращается в виде обычного текста.

Дополнительные сведения см. в разделе "Создание векторного запроса".

Обновление векторного индекса

Чтобы обновить векторный индекс, измените схему и перезагрузите документы, чтобы заполнить новые поля. API для обновлений схемы включают создание или обновление индекса (REST),CreateOrUpdateIndex в пакете SDK Azure для .NET, create_or_update_index в пакете SDK Azure для Python и аналогичных методах в других пакетах SDK Azure.

Стандартные рекомендации по обновлению индекса см. в разделе "Обновление или перестроение индекса".

Ключевые моменты:

  • Для обновлений и удаления существующих полей часто требуется удаление индексов и полное перестроение индексов.

  • Вы можете внести следующие изменения без необходимости перестроения:

    • Добавление новых полей в коллекцию полей.
    • Добавьте новые конфигурации векторов, назначенные новым полям, но не существующим полям, которые уже векторизированы.
    • Изменение retrievable (значения — true или false) в существующем поле. Поля векторов должны быть доступны для поиска и извлечения, но если вы хотите отключить доступ к полю вектора в ситуациях, когда удаление и перестроение невозможно, можно задать значение false.

Следующие шаги

На следующем шаге рекомендуется создать векторный запрос.

Примеры кода в репозитории azure-search-vector-samples демонстрируют комплексные рабочие процессы, включающие определение схемы, векторизацию, индексирование и запросы.

Существует демонстрационный код для Python, C# и JavaScript.