Руководство. Выполнение поиска по сходству векторов в Azure OpenAI с помощью Кэш Azure для Redis

В этом руководстве описаны основные варианты использования поиска сходства векторов. Вы будете использовать внедрения, созданные службой Azure OpenAI, и встроенные возможности поиска векторов уровня Enterprise Кэш Azure для Redis для запроса набора данных фильмов для поиска наиболее релевантного соответствия.

В этом руководстве используется набор данных "Википедия фильм графиков", который содержит описания сюжетов более 35000 фильмов из Википедии, охватывающих годы 1901-2017. Набор данных содержит сводку по сюжету для каждого фильма, а также метаданные, такие как год выпуска фильма, режиссеры, основной актер и жанр. Вы следуйте инструкциям руководства по созданию внедрения на основе сводки графиков и использования других метаданных для выполнения гибридных запросов.

В этом руководстве описано следующее:

  • Создание экземпляра Кэш Azure для Redis, настроенного для векторного поиска
  • Установите Azure OpenAI и другие необходимые библиотеки Python.
  • Скачайте набор данных фильма и подготовьте его к анализу.
  • Используйте модель внедрения текста ada-002 (версия 2) для создания внедрения.
  • Создание векторного индекса в Кэш Azure для Redis
  • Используйте совместное сходство с результатами поиска ранжирования.
  • Используйте функции гибридного запроса через RediSearch , чтобы префильтровать данные и сделать векторный поиск еще более эффективным.

Внимание

В этом руководстве вы узнаете, как создать Jupyter Notebook. Вы можете следовать этому руководству с файлом кода Python (.py) и получить аналогичные результаты, но вам потребуется добавить все блоки кода в этом руководстве в .py файл и выполнить один раз, чтобы просмотреть результаты. Другими словами, Jupyter Notebook предоставляет промежуточные результаты при выполнении ячеек, но это не следует ожидать при работе в файле кода Python.

Внимание

Если вы хотите продолжить работу в завершенной записной книжке Jupyter, скачайте файл записной книжки Jupyter с именем tutorial.ipynb и сохраните его в новой папке redis-vector .

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

Создание экземпляра Кэш Azure для Redis

  1. Следуйте инструкциям из краткого руководства по созданию кэша Redis Enterprise. На странице "Дополнительно" убедитесь, что вы добавили модуль RediSearch и выбрали политику корпоративного кластера. Все остальные параметры могут соответствовать умолчанию, описанному в кратком руководстве.

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

Снимок экрана: вкладка

Настройка среды разработки

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

  2. Создайте файл Python (tutorial.py) или записную книжку Jupyter (tutorial.ipynb) в папке.

  3. Установите необходимые пакеты Python:

    pip install "openai==1.6.1" num2words matplotlib plotly scipy scikit-learn pandas tiktoken redis langchain
    

Скачивание набора данных

  1. Откройте браузер и перейдите по адресу https://www.kaggle.com/datasets/jrobischon/wikipedia-movie-plots.

  2. Войдите или зарегистрируйтесь в Kaggle. Для скачивания файла требуется регистрация.

  3. Выберите ссылку "Скачать " в Kaggle, чтобы скачать файл archive.zip .

  4. Извлеките файл archive.zip и переместите wiki_movie_plots_deduped.csv в папку redis-vector.

Импорт библиотек и настройка сведений о подключении

Чтобы успешно выполнить вызов к Azure OpenAI, вам потребуется конечная точка и ключ. Для подключения к Кэш Azure для Redis также требуется конечная точка и ключ.

  1. Перейдите к ресурсу Azure OpenAI в портал Azure.

  2. Найдите конечную точку и ключи в разделе "Управление ресурсами". Скопируйте конечную точку и ключ доступа, так как они потребуются для проверки подлинности вызовов API. Пример конечной точки: https://docs-test-001.openai.azure.com. Вы можете использовать KEY1 или KEY2.

  3. Перейдите на страницу обзора ресурса Кэш Azure для Redis в портал Azure. Скопируйте конечную точку.

  4. Найдите ключи Access в разделе "Параметры". Скопируйте ключ доступа. Вы можете использовать Primary или Secondary.

  5. Добавьте следующий код в новую ячейку кода:

    # Code cell 2
    
    import re
    from num2words import num2words
    import os
    import pandas as pd
    import tiktoken
    from typing import List
    from langchain.embeddings import AzureOpenAIEmbeddings
    from langchain.vectorstores.redis import Redis as RedisVectorStore
    from langchain.document_loaders import DataFrameLoader
    
    API_KEY = "<your-azure-openai-key>"
    RESOURCE_ENDPOINT = "<your-azure-openai-endpoint>"
    DEPLOYMENT_NAME = "<name-of-your-model-deployment>"
    MODEL_NAME = "text-embedding-ada-002"
    REDIS_ENDPOINT = "<your-azure-redis-endpoint>"
    REDIS_PASSWORD = "<your-azure-redis-password>"
    
  6. Обновите значение и значения ключей API_KEY RESOURCE_ENDPOINT и конечных точек из развертывания Azure OpenAI. DEPLOYMENT_NAME следует задать имя развертывания с помощью text-embedding-ada-002 (Version 2) модели внедрения и MODEL_NAME быть используемой конкретной моделью внедрения.

  7. Обновите REDIS_ENDPOINT и REDIS_PASSWORD используя значение конечной точки и ключа из экземпляра Кэш Azure для Redis.

    Внимание

    Настоятельно рекомендуется использовать переменные среды или диспетчер секретов, например Azure Key Vault , чтобы передать сведения о ключе API, конечной точке и имени развертывания. Эти переменные задаются в виде открытого текста в целях простоты.

  8. Выполните ячейку кода 2.

Импорт набора данных в pandas и обработка данных

Затем вы считываете CSV-файл в кадр данных Pandas.

  1. Добавьте следующий код в новую ячейку кода:

    # Code cell 3
    
    df=pd.read_csv(os.path.join(os.getcwd(),'wiki_movie_plots_deduped.csv'))
    df
    
  2. Выполните ячейку кода 3. Должен появиться следующий результат:

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

  3. Затем обработайте данные, добавив id индекс, удаляя пробелы из заголовков столбцов, и фильтрует фильмы, чтобы принимать только фильмы, сделанные после 1970 года и из англоязычных стран. Этот шаг фильтрации уменьшает количество фильмов в наборе данных, что снижает затраты и время, необходимые для создания внедрения. Вы можете изменить или удалить параметры фильтра на основе ваших предпочтений.

    Чтобы отфильтровать данные, добавьте следующий код в новую ячейку кода:

    # Code cell 4
    
    df.insert(0, 'id', range(0, len(df)))
    df['year'] = df['Release Year'].astype(int)
    df['origin'] = df['Origin/Ethnicity'].astype(str)
    del df['Release Year']
    del df['Origin/Ethnicity']
    df = df[df.year > 1970] # only movies made after 1970
    df = df[df.origin.isin(['American','British','Canadian'])] # only movies from English-speaking cinema
    df
    
  4. Выполните ячейку кода 4. Должны отобразиться следующие результаты:

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

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

    Добавьте следующий код в новую ячейку кода и выполните его:

    # Code cell 5
    
    pd.options.mode.chained_assignment = None
    
    # s is input text
    def normalize_text(s, sep_token = " \n "):
        s = re.sub(r'\s+',  ' ', s).strip()
        s = re.sub(r". ,","",s)
        # remove all instances of multiple spaces
        s = s.replace("..",".")
        s = s.replace(". .",".")
        s = s.replace("\n", "")
        s = s.strip()
    
        return s
    
    df['Plot']= df['Plot'].apply(lambda x : normalize_text(x))
    
  6. Наконец, удалите все записи, содержащие описания графиков, которые слишком длинны для модели внедрения. (Другими словами, для них требуется больше маркеров, чем ограничение на 8192 маркера.) затем вычислите количество маркеров, необходимых для создания внедрения. Это также влияет на цены на внедрение поколения.

    Добавьте следующий код в новую ячейку кода:

    # Code cell 6
    
    tokenizer = tiktoken.get_encoding("cl100k_base")
    df['n_tokens'] = df["Plot"].apply(lambda x: len(tokenizer.encode(x)))
    df = df[df.n_tokens<8192]
    print('Number of movies: ' + str(len(df)))
    print('Number of tokens required:' + str(df['n_tokens'].sum()))
    
  7. Выполните ячейку кода 6. Вы должны увидеть следующий результат:

    Number of movies: 11125
    Number of tokens required:7044844
    

    Внимание

    Ознакомьтесь с ценами на Службу Azure OpenAI, чтобы свести затраты на создание внедрения на основе количества необходимых маркеров.

Загрузка кадра данных в LangChain

Загрузите кадр данных в LangChain с помощью DataFrameLoader класса. После того как данные будут использоваться в документах LangChain, гораздо проще использовать библиотеки LangChain для создания внедрения и проведения поиска сходства. Задайте для этого столбца диаграмму таким page_content_column образом, чтобы внедрения создавались в этом столбце.

  1. Добавьте следующий код в новую ячейку кода и выполните его:

    # Code cell 7
    
    loader = DataFrameLoader(df, page_content_column="Plot" )
    movie_list = loader.load()
    

Создание внедрения и загрузка их в Redis

Теперь, когда данные были отфильтрованы и загружены в LangChain, вы создадите внедренные элементы, чтобы запросить график для каждого фильма. Следующий код настраивает Azure OpenAI, создает внедрения и загружает векторы внедрения в Кэш Azure для Redis.

  1. Добавьте следующий код в новую ячейку кода:

    # Code cell 8
    
    embedding = AzureOpenAIEmbeddings(
        deployment=DEPLOYMENT_NAME,
        model=MODEL_NAME,
        azure_endpoint=RESOURCE_ENDPOINT,
        openai_api_type="azure",
        openai_api_key=API_KEY,
        openai_api_version="2023-05-15",
        show_progress_bar=True,
        chunk_size=16 # current limit with Azure OpenAI service. This will likely increase in the future.
        )
    
    # name of the Redis search index to create
    index_name = "movieindex"
    
    # create a connection string for the Redis Vector Store. Uses Redis-py format: https://redis-py.readthedocs.io/en/stable/connections.html#redis.Redis.from_url
    # This example assumes TLS is enabled. If not, use "redis://" instead of "rediss://
    redis_url = "rediss://:" + REDIS_PASSWORD + "@"+ REDIS_ENDPOINT
    
    # create and load redis with documents
    vectorstore = RedisVectorStore.from_documents(
        documents=movie_list,
        embedding=embedding,
        index_name=index_name,
        redis_url=redis_url
    )
    
    # save index schema so you can reload in the future without re-generating embeddings
    vectorstore.write_schema("redis_schema.yaml")
    
  2. Выполните ячейку кода 8. Это может занять более 30 минут. Также redis_schema.yaml создается файл. Этот файл полезен, если вы хотите подключиться к индексу в Кэш Azure для Redis экземпляре без повторного создания внедрения.

Внимание

Скорость создания внедрения зависит от квоты, доступной модели Azure OpenAI. Квота 240k токенов в минуту займет около 30 минут для обработки маркеров 7M в наборе данных.

Выполнение запросов векторного поиска

Теперь, когда набор данных, API службы Azure OpenAI и экземпляр Redis настроены, можно выполнять поиск по векторам. В этом примере возвращаются первые 10 результатов для данного запроса.

  1. Добавьте следующий код в файл кода Python:

    # Code cell 9
    
    query = "Spaceships, aliens, and heroes saving America"
    results = vectorstore.similarity_search_with_score(query, k=10)
    
    for i, j in enumerate(results):
        movie_title = str(results[i][0].metadata['Title'])
        similarity_score = str(round((1 - results[i][1]),4))
        print(movie_title + ' (Score: ' + similarity_score + ')')
    
  2. Выполните ячейку кода 9. Должен появиться следующий результат:

    Independence Day (Score: 0.8348)
    The Flying Machine (Score: 0.8332)
    Remote Control (Score: 0.8301)
    Bravestarr: The Legend (Score: 0.83)
    Xenogenesis (Score: 0.8291)
    Invaders from Mars (Score: 0.8291)
    Apocalypse Earth (Score: 0.8287)
    Invasion from Inner Earth (Score: 0.8287)
    Thru the Moebius Strip (Score: 0.8283)
    Solar Crisis (Score: 0.828)
    

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

Гибридные поиски

  1. Так как RediSearch также предоставляет широкие возможности поиска поверх векторного поиска, можно фильтровать результаты по метаданным в наборе данных, таким как жанр фильма, приведение, год выпуска или директор. В этом случае фильтруйте на основе жанра comedy.

    Добавьте следующий код в новую ячейку кода:

    # Code cell 10
    
    from langchain.vectorstores.redis import RedisText
    
    query = "Spaceships, aliens, and heroes saving America"
    genre_filter = RedisText("Genre") == "comedy"
    results = vectorstore.similarity_search_with_score(query, filter=genre_filter, k=10)
    for i, j in enumerate(results):
        movie_title = str(results[i][0].metadata['Title'])
        similarity_score = str(round((1 - results[i][1]),4))
        print(movie_title + ' (Score: ' + similarity_score + ')')
    
  2. Выполните ячейку кода 10. Должен появиться следующий результат:

    Remote Control (Score: 0.8301)
    Meet Dave (Score: 0.8236)
    Elf-Man (Score: 0.8208)
    Fifty/Fifty (Score: 0.8167)
    Mars Attacks! (Score: 0.8165)
    Strange Invaders (Score: 0.8143)
    Amanda and the Alien (Score: 0.8136)
    Suburban Commando (Score: 0.8129)
    Coneheads (Score: 0.8129)
    Morons from Outer Space (Score: 0.8121)
    

С помощью Кэш Azure для Redis и Службы Azure OpenAI можно использовать внедрение и векторный поиск для добавления мощных возможностей поиска в приложение.

Очистка ресурсов

Если вы хотите продолжить использовать ресурсы, созданные в этой статье, сохраните группу ресурсов.

В противном случае, чтобы избежать расходов, связанных с ресурсами, при завершении использования ресурсов можно удалить созданную группу ресурсов Azure.

Предупреждение

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

Удаление группы ресурсов

  1. Войдите на портал Azure и щелкните Группы ресурсов.

  2. Выберите группу ресурсов для удаления.

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

    Снимок экрана: список групп ресурсов для удаления.

  3. Выберите команду Удалить группу ресурсов.

  4. В области "Удалить группу ресурсов" введите имя группы ресурсов, чтобы подтвердить, и нажмите кнопку "Удалить".

    Снимок экрана: поле, требующее ввода имени ресурса для подтверждения удаления.

В течение нескольких минут группа ресурсов и все его ресурсы удаляются.