Tutorial: realizar a pesquisa de similaridade de vetor em embeddings do OpenAI do Azure usando o Cache do Azure para Redis
Neste tutorial, você percorrerá um caso de uso de pesquisa de similaridade de vetor básico. Você usará as inserções geradas pelo Serviço OpenAI do Azure e os recursos internos de pesquisa de vetor da camada Enterprise de Cache do Azure para Redis para consultar um conjunto de dados de filmes para encontrar a correspondência mais relevante.
O tutorial usa o Conjunto de dados Gráficos de Filmes da Wikipédia que apresenta descrições de plotagem de mais de 35.000 filmes da Wikipédia abrangendo os anos de 1901 a 2017. O conjunto de dados inclui um resumo de enredo de cada filme, além de metadados, como o ano em que o filme foi lançado, os diretores, elenco principal e gênero. Você seguirá as etapas do tutorial para gerar inserções com base no resumo do gráfico e usar os outros metadados para executar consultas híbridas.
Neste tutorial, você aprenderá a:
- Criar uma instância de Cache do Azure para Redis configurada para pesquisa de vetor
- Instalar o OpenAI do Azure e outras bibliotecas obrigatórias do Python.
- Baixar o conjunto de dados de filmes e prepará-lo para análise.
- Use o modelo text-embedding-ada-002 (Versão 2) para gerar inserções.
- Criar um índice de vetor no Cache do Azure para Redis
- Use a similaridade cosseno para classificar os resultados da pesquisa.
- Usar a funcionalidade de consulta híbrida pelo RediSearch para pré-filtrar os dados e deixar a pesquisa de vetor ainda mais eficiente.
Importante
Este tutorial o orientará na criação de um Jupyter Notebook. Você pode seguir este tutorial com um arquivo de código Python (.py) e obter resultados semelhantes, mas precisará adicionar todos os blocos de código neste tutorial ao arquivo .py
e executar uma vez para ver os resultados. Em outras palavras, o Jupyter Notebooks fornece resultados intermediários à medida que você executa células, mas esse não é o comportamento que você deve esperar ao trabalhar em um arquivo de código Python.
Importante
Se você quiser acompanhar em um notebook do Jupyter concluído, baixe o arquivo do notebook do Jupyter chamado tutorial.ipynb e salve-o na nova pasta redis-vector.
Pré-requisitos
- Uma assinatura do Azure – crie uma gratuitamente
- Acesso concedido ao Azure OpenAI na assinatura desejada do Azure Atualmente, você deve solicitar acesso ao Azure OpenAI. Você pode solicitar acesso ao Serviço OpenAI do Azure preenchendo o formulário em https://aka.ms/oai/access.
- Python versão 3.7.1 ou posteriores
- Jupyter Notebooks (opcional)
- Um recurso do Azure OpenAI com o modelo text-embedding-ada-002 (Versão 2) implantado. Este modelo está atualmente disponível apenas em determinadas regiões. Consulte o guia de implantação de recursos para obter instruções sobre como implantar o modelo.
Criar uma instância de Cache do Azure para Redis
Siga o guia Início Rápido: criar um cache Redis Enterprise. Na página Avançado, verifique se você adicionou o módulo RediSearch e escolheu a Política de Cluster Empresarial. Todas as outras configurações podem corresponder ao padrão descrito no início rápido.
O cache leva alguns minutos para ser criado. Você pode passar para a próxima etapa enquanto isso.
Configurar seu ambiente de desenvolvimento
Crie uma pasta no computador local chamada redis-vector no local em que você normalmente salva seus projetos.
Crie um novo arquivo Python (tutorial.py) ou notebook do Jupyter (tutorial.ipynb) na pasta.
Instale os pacotes necessários do Python:
pip install "openai==1.6.1" num2words matplotlib plotly scipy scikit-learn pandas tiktoken redis langchain
Carregar o conjunto de dados
Em um navegador da Web, acesse https://www.kaggle.com/datasets/jrobischon/wikipedia-movie-plots.
Entre ou registre-se com o Kaggle. O registro é necessário para baixar o arquivo.
Selecione o link Baixar no Kaggle para baixar o arquivo archive.zip.
Extraia o arquivo archive.zip e mova o wiki_movie_plots_deduped.csv para a pasta redis-vector.
Importar as bibliotecas e configurar as informações de conexão
Para efetuar uma chamada com êxito no Serviço OpenAI do Azure, um ponto de extremidade e uma chave serão necessários. Você também precisa de um ponto de extremidade e uma chave para se conectar ao Cache do Azure para Redis.
Acesse o recurso do Azure OpenAI no portal do Azure.
O Ponto de extremidade e as Chaves podem ser encontrados na seção Gerenciamento de Recursos. Copie o ponto de extremidade e as chave de acesso, pois você precisará de ambos para autenticar suas chamadas à API. Um ponto de extremidade de exemplo é:
https://docs-test-001.openai.azure.com
. Você pode usarKEY1
ouKEY2
.Acesse a página Visão geral do recurso Cache do Azure para Redis no portal do Azure. Consultar seu ponto de extremidade.
Clique em Chaves de acesso na seção Configurações. Copie sua chave de acesso. Você pode usar
Primary
ouSecondary
.Adicione o seguinte código a uma nova célula de código:
# 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>"
Atualize o valor de
API_KEY
eRESOURCE_ENDPOINT
com os valores de chave e ponto de extremidade da implantação do Azure OpenAI.DEPLOYMENT_NAME
deve ser definido como o nome da sua implantação usando otext-embedding-ada-002 (Version 2)
modelo de inserções eMODEL_NAME
deve ser o modelo de inserções específico usado.Atualize
REDIS_ENDPOINT
eREDIS_PASSWORD
com o ponto de extremidade e o valor da chave da sua instância de Cache do Azure para Redis.Importante
É altamente recomendável usar variáveis ambientais ou um gerente de segredos como o Azure Key Vault para passar as informações de chave de API, ponto de extremidade e nome de implantação. Essas variáveis são definidas em texto sem formatação aqui para simplificar.
Execute a célula de código 2.
Importar o conjunto de dados no Pandas e processar os dados
Em seguida, você lerá o arquivo csv em um DataFrame do Pandas.
Adicione o seguinte código a uma nova célula de código:
# Code cell 3 df=pd.read_csv(os.path.join(os.getcwd(),'wiki_movie_plots_deduped.csv')) df
Execute a célula de código 3. Você deve ver o seguinte resultado:
Em seguida, processe os dados adicionando um índice de
id
, removendo espaços dos títulos das colunas e filtrando os filmes para incluir apenas filmes feitos depois de 1970 e de países ou regiões que falam inglês. Essa etapa de filtragem reduz o número de filmes no conjunto de dados, o que reduz o custo e o tempo necessários para gerar inserções. Você está livre para alterar ou remover os parâmetros de filtro com base nas suas preferências.Para filtrar os dados, adicione o seguinte código a uma nova célula de código:
# 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
Execute a célula de código 4. Você verá os seguintes resultados:
Crie uma função para limpar os dados removendo o espaço em branco e a pontuação e, use-os no dataframe que contém o gráfico.
Adicione o seguinte código a uma nova célula de código:
# 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))
Por fim, remova todas as entradas que contenham descrições de plotagem que sejam muito longas para o modelo de inserções. (Em outras palavras, eles exigem mais tokens do que o limite de token 8192.) e calcule os números de tokens necessários para gerar as inserções. Isso também afeta os preços da geração de inserção.
Adicione o seguinte código a uma nova célula de código:
# 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()))
Execute a célula de código 6. Você deverá ver este resultado:
Number of movies: 11125 Number of tokens required:7044844
Importante
Consulte Preços do Serviço OpenAI do Azure para calcular o custo de geração de inserções com base no número de tokens necessários.
Carregue o DataFrame no LangChain
Carregue o DataFrame no LangChain usando a classe DataFrameLoader
. Depois que os dados estiverem nos documentos LangChain, é muito mais fácil usar as bibliotecas LangChain para gerar inserções e realizar pesquisas de similaridade. Defina Plotar como o page_content_column
para que as inserções sejam geradas nesta coluna.
Adicione o seguinte código a uma nova célula de código:
# Code cell 7 loader = DataFrameLoader(df, page_content_column="Plot" ) movie_list = loader.load()
Gere inserções e carregue-as no Redis
Agora que os dados foram filtrados e carregados no LangChain, você criará inserções para poder consultar no gráfico para cada filme. O código a seguir configura o OpenAI do Azure, gera inserções e carrega os vetores de inserção em Cache do Azure para Redis.
Adicione o seguinte código a uma nova célula de código:
# 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")
Execute a célula de código 8. Isso pode demorar mais de 30 minutos para ser concluído. Um arquivo
redis_schema.yaml
também é gerado. Este arquivo é útil se você quiser se conectar ao seu índice na instância do Cache do Azure para Redis sem gerar novamente incorporações.
Importante
A velocidade com que as inserções são geradas depende da cota disponível para o modelo do Azure OpenAI. Com uma cota de 240 mil tokens por minuto, levará cerca de 30 minutos para processar os 7 milhões de tokens no conjunto de dados.
Execute as consultas de pesquisa de vetor
Agora que o conjunto de dados, a API do serviço OpenAI do Azure e a instância do Redis estão configurados, você pode pesquisar usando os vetores. Neste exemplo, os 10 principais resultados de uma determinada consulta são retornados.
Adicione o código a seguir ao arquivo do 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 + ')')
Execute a célula de código 9. Você deve ver o seguinte resultado:
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)
A pontuação de similaridade é retornada junto com a classificação ordinal de filmes por similaridade. Observe que as consultas mais específicas têm pontuações de similaridade que diminuem mais rapidamente na lista.
Pesquisas híbridas
Como o RediSearch também apresenta funcionalidade de pesquisa avançada sobre a pesquisa de vetor, é possível filtrar os resultados pelos metadados no conjunto de dados, como gênero de filme, elenco, ano de lançamento ou diretor. Nesse caso, filtre com base no gênero
comedy
.Adicione o seguinte código a uma nova célula de código:
# 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 + ')')
Execute a célula de código 10. Você deve ver o seguinte resultado:
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)
Com Cache do Azure para Redis e o Serviço OpenAI do Azure, você pode usar inserções e pesquisa de vetor para adicionar recursos de pesquisa avançados ao seu aplicativo.
Limpar os recursos
Se quiser continuar a usar os recursos que você criou neste artigo, conserve o grupo de recursos.
Caso contrário, se não pretende mais usar os recursos, você poderá excluir o grupo de recursos criado no Azure para evitar a cobrança.
Importante
A exclusão de um grupo de recursos é irreversível. Ao excluir o grupo de recursos, todos os recursos nele são excluídos permanentemente. Não exclua acidentalmente o grupo de recursos ou os recursos incorretos. Se você criou os recursos dentro de um grupo de recursos existente que contém recursos que você quer manter, você pode excluir cada recurso individualmente em vez de excluir o grupo de recursos.
Para excluir um grupo de recursos
Entre no portal do Azure e selecione Grupos de recursos.
Selecione o grupo de recursos que você quer excluir.
Se existirem muitos grupos de recursos, use a caixa Filtrar para qualquer campo... e digite o nome do seu grupo de recursos que você criou para este artigo. Selecione o grupo de recursos na lista de resultados.
Selecione Excluir grupo de recursos.
Você receberá uma solicitação para confirmar a exclusão do grupo de recursos. Digite o nome do grupo de recursos para confirmar e selecione Excluir.
Após alguns instantes, o grupo de recursos, e todos os recursos nele são excluídos.
Conteúdo relacionado
- Saiba mais sobre o Cache do Azure para Redis
- Saiba mais sobre os recursos de pesquisa de vetor do Cache do Azure para Redis
- Saiba mais sobre Inserções geradas pelo Serviço OpenAI do Azure
- Saiba mais sobre a similaridade do cosseno
- Leia sobre como criar um aplicativo de IA com OpenAI e Redis
- Criar um aplicativo do Q&A com respostas semânticas