Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Este tutorial irá guiá-lo através do uso da API de incorporação do Azure OpenAI para executar a pesquisa de documentos, onde você consultará uma base de dados de conhecimento para encontrar o documento mais relevante.
Neste tutorial, aprenderás como:
- Faça o download de um conjunto de dados de exemplo e prepare-o para análise.
- Crie variáveis de ambiente para os seus recursos, endpoint e chave de API.
- Use um dos seguintes modelos: text-embedding-ada-002 (Versão 2), text-embedding-3-large, text-embedding-3-small.
- Utilize a semelhança do cosseno para classificar os resultados da pesquisa.
Pré-requisitos
- Uma assinatura do Azure - Crie uma gratuitamente
- Um recurso Microsoft Foundry ou Azure OpenAI com o modelo text-embedding-ada-002 (Versão 2) implementado. Atualmente, este modelo só está disponível em determinadas regiões.
- Python 3.10 ou versão posterior
- As seguintes bibliotecas Python:
openai,num2words,matplotlib,plotly,scipy,scikit-learn,pandas,tiktoken. - Cadernos Jupyter
Configurar
Bibliotecas Python
Se ainda não o fez, terá de instalar as seguintes bibliotecas:
pip install openai num2words matplotlib plotly scipy scikit-learn pandas tiktoken
Baixe o conjunto de dados BillSum
BillSum é um conjunto de dados de projetos de lei do Congresso dos Estados Unidos e do estado da Califórnia. Para fins de ilustração, vamos olhar apenas para as contas dos EUA. O corpus é composto por projetos de lei das 103ª a 115ª sessões (1993-2018) do Congresso. Os dados foram divididos em 18.949 contas de trens e 3.269 contas de testes. O corpus BillSum concentra-se na legislação de tamanho médio de 5.000 a 20.000 caracteres de comprimento. Mais informações sobre o projeto e o artigo acadêmico original de onde esse conjunto de dados é derivado podem ser encontradas no repositório GitHub do projeto BillSum.
Este tutorial usa o ficheiro bill_sum_data.csv que pode ser baixado do nosso repositório de dados de exemplo no GitHub.
Você também pode baixar os dados de exemplo executando o seguinte comando em sua máquina local:
curl "https://raw.githubusercontent.com/Azure-Samples/Azure-OpenAI-Docs-Samples/main/Samples/Tutorials/Embeddings/data/bill_sum_data.csv" --output bill_sum_data.csv
Observação
Atualmente, a autenticação baseada em ID Microsoft Entra não é suportada para embeddings com a API v1.
Recuperar a chave e o endpoint
Para efetuar uma chamada com êxito no Azure OpenAI, necessita de um endpoint e de uma chave.
| Nome da variável | Valor |
|---|---|
ENDPOINT |
O ponto de extremidade do serviço pode ser encontrado na seção Chaves & Ponto de Extremidade ao examinar seu recurso no portal do Azure. Alternativamente, pode encontrar o endpoint através da página de Implementações no portal Microsoft Foundry. Um exemplo de ponto de extremidade é: https://docs-test-001.openai.azure.com/. |
API-KEY |
Este valor pode ser encontrado na secção Chaves e Ponto Final ao examinar o recurso no portal do Azure. Pode utilizar KEY1 ou KEY2. |
Vá para o seu recurso no portal do Azure. A seção Chaves & Ponto Final pode ser encontrada na seção Gerenciamento de Recursos. Copie seu endpoint e sua chave de acesso, pois você precisará de ambos para autenticar suas chamadas de API. Pode utilizar KEY1 ou KEY2. Ter sempre duas chaves permite-lhe alternar e regenerar as suas chaves com segurança, sem causar uma interrupção do serviço.
Variáveis de ambiente
Crie e atribua variáveis de ambiente persistentes para sua chave de API.
Importante
Use chaves de API com cuidado. Não inclua a chave da API diretamente no seu código e nunca a publique publicamente. Se você usar uma chave de API, armazene-a com segurança no Cofre de Chaves do Azure. Para obter mais informações sobre como usar chaves de API com segurança em seus aplicativos, consulte Chaves de API com o Cofre de Chaves do Azure.
Para obter mais informações sobre segurança de serviços de IA, consulte Autenticar solicitações para serviços de IA do Azure.
setx AZURE_OPENAI_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
Depois de definir as variáveis de ambiente, talvez seja necessário fechar e reabrir os blocos de anotações Jupyter ou qualquer IDE que esteja usando para que as variáveis de ambiente sejam acessíveis. Embora seja altamente recomendável usar o Jupyter Notebooks, se por algum motivo você não puder, precisará modificar qualquer código que esteja retornando um dataframe pandas usando print(dataframe_name) em vez de apenas chamar o dataframe_name diretamente, como geralmente é feito no final de um bloco de código.
Execute o seguinte código no seu IDE Python preferido:
Importar bibliotecas
import os
import re
import requests
import sys
from num2words import num2words
import os
import pandas as pd
import numpy as np
import tiktoken
from openai import OpenAI
Agora precisamos ler o nosso arquivo csv e criar um DataFrame do pandas. Depois que o DataFrame inicial é criado, podemos exibir o conteúdo da tabela executando df.
df=pd.read_csv(os.path.join(os.getcwd(),'bill_sum_data.csv')) # This assumes that you have placed the bill_sum_data.csv in the same directory you are running Jupyter Notebooks
df
Saída:
A tabela inicial tem mais colunas do que precisamos, vamos criar um novo DataFrame menor chamado df_bills que conterá apenas as colunas para text, summarye title.
df_bills = df[['text', 'summary', 'title']]
df_bills
Saída:
Em seguida, realizaremos uma leve limpeza de dados, removendo espaços em branco redundantes e limpando a pontuação para preparar os dados para tokenização.
pd.options.mode.chained_assignment = None #https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#evaluation-order-matters
# 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_bills['text']= df_bills["text"].apply(lambda x : normalize_text(x))
Agora precisamos remover todas as contas que são muito longas para o limite de token (8.192 tokens).
tokenizer = tiktoken.get_encoding("cl100k_base")
df_bills['n_tokens'] = df_bills["text"].apply(lambda x: len(tokenizer.encode(x)))
df_bills = df_bills[df_bills.n_tokens<8192]
len(df_bills)
20
Observação
Nesse caso, todas as faturas estão abaixo do limite de token de entrada do modelo de incorporação, mas você pode usar a técnica acima para remover entradas que, de outra forma, causariam falha na incorporação. Quando confrontado com conteúdo que excede o limite de incorporação, você também pode dividir o conteúdo em partes menores e, em seguida, incorporar as partes uma de cada vez.
Examinaremos mais uma vez df_bills.
df_bills
Saída:
Para entender um pouco mais a coluna n_tokens, bem como como o texto é tokenizado, pode ser útil executar o seguinte código:
sample_encode = tokenizer.encode(df_bills.text[0])
decode = tokenizer.decode_tokens_bytes(sample_encode)
decode
Para nossos documentos, estamos intencionalmente truncando a saída, mas executar esse comando em seu ambiente retornará o texto completo do índice zero tokenizado em partes. Você pode ver que, em alguns casos, uma palavra inteira é representada com um único token, enquanto em outros partes das palavras são divididas em vários tokens.
[b'SECTION',
b' ',
b'1',
b'.',
b' SHORT',
b' TITLE',
b'.',
b' This',
b' Act',
b' may',
b' be',
b' cited',
b' as',
b' the',
b' ``',
b'National',
b' Science',
b' Education',
b' Tax',
b' In',
b'cent',
b'ive',
b' for',
b' Businesses',
b' Act',
b' of',
b' ',
b'200',
b'7',
b"''.",
b' SEC',
b'.',
b' ',
b'2',
b'.',
b' C',
b'RED',
b'ITS',
b' FOR',
b' CERT',
b'AIN',
b' CONTRIBUT',
b'IONS',
b' BEN',
b'EF',
b'IT',
b'ING',
b' SC',
Se você verificar o comprimento da decode variável, descobrirá que ela corresponde ao primeiro número na coluna n_tokens.
len(decode)
1466
Agora que entendemos mais sobre como a tokenização funciona, podemos passar para a incorporação. É importante notar que ainda não tokenizamos os documentos. A n_tokens coluna é simplesmente uma maneira de garantir que nenhum dos dados que passamos para o modelo para tokenização e incorporação exceda o limite de token de entrada de 8.192. Quando passamos os documentos para o modelo de incorporações, ele quebrará os documentos em tokens semelhantes (embora não necessariamente idênticos) aos exemplos acima e, em seguida, converterá os tokens em uma série de números de ponto flutuante que serão acessíveis por meio de pesquisa vetorial. Essas incorporações podem ser armazenadas localmente ou em um Banco de Dados do Azure para dar suporte à Pesquisa Vetorial. Como resultado, cada fatura terá seu próprio vetor de incorporação correspondente na nova ada_v2 coluna no lado direito do DataFrame.
No exemplo abaixo, estamos chamando o modelo de incorporação uma vez por cada item que queremos incorporar. Ao trabalhar com grandes projetos de incorporação, você pode, alternativamente, passar ao modelo uma matriz de entradas para incorporar, em vez de uma entrada de cada vez. Quando você passa o modelo para uma matriz de entradas, o número máximo de itens de entrada por chamada para o ponto de extremidade de incorporação é 2048.
client = OpenAI(
api_key = os.getenv("AZURE_OPENAI_API_KEY"),
base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/"
)
def generate_embeddings(text, model="text-embedding-ada-002"): # model = "deployment_name"
return client.embeddings.create(input = [text], model=model).data[0].embedding
df_bills['ada_v2'] = df_bills["text"].apply(lambda x : generate_embeddings (x, model = 'text-embedding-ada-002')) # model should be set to the deployment name you chose when you deployed the text-embedding-ada-002 (Version 2) model
df_bills
Saída:
À medida que executamos o bloco de código de pesquisa abaixo, incorporaremos a consulta de pesquisa "Posso obter informações sobre a receita fiscal da empresa de cabo?" com o mesmo modelo text-embedding-ada-002 (Versão 2). Em seguida, encontraremos o documento mais próximo ao recém-incorporado texto da nossa consulta, classificado por similaridade de cosseno.
def cosine_similarity(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
def get_embedding(text, model="text-embedding-ada-002"): # model = "deployment_name"
return client.embeddings.create(input = [text], model=model).data[0].embedding
def search_docs(df, user_query, top_n=4, to_print=True):
embedding = get_embedding(
user_query,
model="text-embedding-ada-002" # model should be set to the deployment name you chose when you deployed the text-embedding-ada-002 (Version 2) model
)
df["similarities"] = df.ada_v2.apply(lambda x: cosine_similarity(x, embedding))
res = (
df.sort_values("similarities", ascending=False)
.head(top_n)
)
if to_print:
display(res)
return res
res = search_docs(df_bills, "Can I get information on cable company tax revenue?", top_n=4)
Saída:
Finalmente, mostraremos o resultado superior da pesquisa de documentos com base na consulta do usuário em relação a toda a base de conhecimento. Isso retorna o principal resultado da "Lei do Direito do Contribuinte de Ver de 1993". Este documento tem uma pontuação de semelhança cosseno de 0,76 entre a consulta e o documento:
res["summary"][9]
"Taxpayer's Right to View Act of 1993 - Amends the Communications Act of 1934 to prohibit a cable operator from assessing separate charges for any video programming of a sporting, theatrical, or other entertainment event if that event is performed at a facility constructed, renovated, or maintained with tax revenues or by an organization that receives public financial support. Authorizes the Federal Communications Commission and local franchising authorities to make determinations concerning the applicability of such prohibition. Sets forth conditions under which a facility is considered to have been constructed, maintained, or renovated with tax revenues. Considers events performed by nonprofit or public organizations that receive tax subsidies to be subject to this Act if the event is sponsored by, or includes the participation of a team that is part of, a tax exempt organization."
Usando essa abordagem, você pode usar incorporações como um mecanismo de pesquisa em documentos em uma base de dados de conhecimento. O utilizador pode então pegar no melhor resultado da pesquisa e usá-lo para a sua tarefa subsequente, que originou a sua consulta inicial.
Limpeza de recursos
Se você criou um recurso do Azure OpenAI apenas para concluir este tutorial e deseja limpar e remover um recurso do Azure OpenAI, precisará excluir seus modelos implantados e, em seguida, excluir o recurso ou o grupo de recursos associado se ele for dedicado ao seu recurso de teste. A exclusão do grupo de recursos também exclui quaisquer outros recursos associados a ele.
Próximos passos
Saiba mais sobre os modelos do Azure OpenAI:
- Armazene suas incorporações e execute a pesquisa vetorial (semelhança) usando sua escolha de serviço do Azure: