Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Visualización actual:Versión - Cambio a la versión del nuevo portal de Foundry
Nota
Los vínculos de este artículo pueden abrir contenido en la nueva documentación de Microsoft Foundry en lugar de la documentación de Foundry (clásico) que está viendo ahora.
Este tutorial le guiará por el uso de la API Azure OpenAI embeddings API para realizar document search donde consultará una base de conocimiento para encontrar el documento más relevante.
En este tutorial, aprenderá a:
- Descargue un conjunto de datos de ejemplo y prepárelo para su análisis.
- Cree variables de entorno para el punto de conexión de recursos y la clave de API.
- Use uno de los modelos siguientes: text-embedding-ada-002 (versión 2), text-embeding-3-large, text-embedding-3-small models.
- Use la similitud de coseno para clasificar los resultados de la búsqueda.
Requisitos previos
- Una suscripción Azure: Crear una gratuita
- Un recurso Microsoft Foundry o Azure OpenAI con el modelo text-embedding-ada-002 (versión 2). Este modelo solo está disponible actualmente en determinadas regiones.
- Python 3.10 o posterior
- Las siguientes bibliotecas de Python:
openai,num2words,matplotlib,plotly,scipy,scikit-learn,pandas,tiktoken. - Jupyter Notebooks
Configurar
bibliotecas de Python
Si aún no lo ha hecho, debe instalar las siguientes bibliotecas:
pip install openai num2words matplotlib plotly scipy scikit-learn pandas tiktoken
Descarga del conjunto de datos de BillSum
BillSum es un conjunto de datos de los proyectos de ley del Congreso de los Estados Unidos y del estado de California. Con fines ilustrativos, solo veremos las facturas estadounidenses. El corpus consta de proyectos de ley de las sesiones del 103 al 115 del Congreso de EE. UU. (1993-2018). Los datos se dividieron en 18.949 facturas de tren y 3.269 facturas de prueba. El corpus de BillSum se centra en la legislación de longitud media de 5000 a 20 000 caracteres de longitud. Puede encontrar más información sobre el proyecto y el documento académico original del que se deriva este conjunto de datos en el repositorio GitHub del proyecto BillSum
En este tutorial se usa el archivo bill_sum_data.csv que se puede descargar de nuestros datos de ejemplo de GitHub.
También puede descargar los datos de ejemplo ejecutando el siguiente comando en el equipo 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
Nota
actualmente no se admite la autenticación basada en Microsoft Entra ID para incrustaciones con la API v1.
Recuperación de la clave y el punto de conexión
Para realizar correctamente una llamada en Azure OpenAI, necesita un endpoint y un key.
| Nombre de variable | Valor |
|---|---|
ENDPOINT |
El punto de conexión de servicio se puede encontrar en la sección de Claves y punto de conexión al examinar el recurso desde el portal de Azure. Como alternativa, puede encontrar el punto de conexión a través de la página Deployments en el portal de Microsoft Foundry. Un punto de conexión de ejemplo es: https://docs-test-001.openai.azure.com/. |
API-KEY |
Este valor se puede encontrar en la sección Claves y puntos de conexión al examinar su recurso desde el portal de Azure. Puede usar KEY1 o KEY2. |
Acceda a su recurso en el portal de Azure. La sección Claves y punto de conexión se puede encontrar en la sección Administración de recursos . Copie el punto de conexión y la clave de acceso, ya que necesitará ambos para autenticar las llamadas API. Puede usar KEY1 o KEY2. Tener siempre dos claves le permite rotar y regenerar las claves de forma segura sin provocar una interrupción del servicio.
Variables de entorno
Cree y asigne variables de entorno persistentes para la clave de API.
Importante
Use las claves de API con precaución. No incluya la clave de API directamente en el código y nunca la publique públicamente. Si usa una clave de API, almacénela de forma segura en Azure Key Vault. Para obtener más información sobre el uso de claves de API de forma segura en las aplicaciones, consulte CLAVESAPI con Azure Key Vault.
Para obtener más información sobre la seguridad de los servicios de inteligencia artificial, consulte
setx AZURE_OPENAI_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
Después de establecer las variables de entorno, es posible que tenga que cerrar y volver a abrir cuadernos de Jupyter Notebook o cualquier IDE que use para que las variables de entorno sean accesibles. Aunque se recomienda encarecidamente usar Jupyter Notebooks, si por algún motivo no puedes, tendrás que modificar cualquier código que devuelva un dataframe de pandas usando print(dataframe_name) en lugar de llamar directamente a dataframe_name, como se hace a menudo al final de un bloque de código.
Ejecute el código siguiente en el IDE de 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
Ahora es necesario leer el archivo CSV y crear un dataframe de Pandas. Después de crear el dataframe inicial, podemos ver el contenido de la tabla ejecutando 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
Salida:
La tabla inicial tiene más columnas de las que necesitamos crearemos un nuevo DataFrame más pequeño denominado df_bills que contendrá solo las columnas de text, summaryy title.
df_bills = df[['text', 'summary', 'title']]
df_bills
Salida:
A continuación, se realizará una limpieza de datos ligeros mediante la eliminación de espacios en blanco redundantes y la limpieza de los signos de puntuación para preparar los datos para la tokenización.
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))
Ahora es necesario quitar las facturas que sean demasiado largas para el límite de tokens (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
Nota
En este caso, todas las facturas están por debajo del límite de tokens de entrada del modelo de inserción, pero puede usar la técnica anterior para quitar entradas que, de lo contrario, provocarían un error en la inserción. Al enfrentarse a contenido que supera el límite de incrustación, también puede fragmentar el contenido en partes más pequeñas y luego incrustar las partes una a una.
Volveremos a examinar df_bills.
df_bills
Salida:
Para comprender el n_tokens columna un poco más, así como cómo se tokeniza el texto en última instancia, puede resultar útil ejecutar el código siguiente:
sample_encode = tokenizer.encode(df_bills.text[0])
decode = tokenizer.decode_tokens_bytes(sample_encode)
decode
Para nuestros documentos, truncamos intencionadamente la salida, pero la ejecución de este comando en el entorno devolverá el texto completo del índice cero tokenizado en fragmentos. Puede ver que, en algunos casos, se representa una palabra completa con un solo token, mientras que en otras partes de palabras se dividen entre varios 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',
Si, a continuación, comprueba la longitud de la decode variable, encontrará que coincide con el primer número de la columna n_tokens.
len(decode)
1466
Ahora que entendemos más sobre cómo funciona la tokenización, podemos pasar a la inserción. Es importante tener en cuenta que aún no hemos tokenizado los documentos. La n_tokens columna es simplemente una manera de asegurarse de que ninguno de los datos que pasamos al modelo para la tokenización e incrustación supera el límite de token de entrada de 8192. Cuando pasamos los documentos al modelo de incrustaciones, dividirá los documentos en tokens similares (aunque no necesariamente idénticos) a los ejemplos anteriores y, a continuación, convertirá los tokens en una serie de números de punto flotante que serán accesibles a través de la búsqueda vectorial. Estas inserciones se pueden almacenar localmente o en una base de datos Azure para admitir la búsqueda de vectores. Como resultado, cada factura tendrá su propio vector de inserción correspondiente en la nueva ada_v2 columna del lado derecho del DataFrame.
En el ejemplo siguiente, llamamos al modelo de inserción una vez por cada elemento que queremos insertar. Al trabajar con proyectos de inserción de gran tamaño, también puede pasar al modelo una matriz de entradas para insertar en lugar de una entrada a la vez. Al pasar una matriz de entradas al modelo, el número máximo de elementos de entrada por llamada al punto de incrustación es 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
Salida:
A medida que ejecutamos el bloque de código de búsqueda siguiente, insertaremos la consulta de búsqueda "¿Puedo obtener información sobre los ingresos fiscales de la compañía de cable?" con el mismo modelo text-embeding-ada-002 (versión 2). A continuación, veremos la inserción de factura más cercana al texto recién insertado de la consulta clasificada por similitud de coseno.
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)
Salida:
Por último, mostraremos el resultado superior de la búsqueda de documentos en función de la consulta de usuario en toda la base de conocimiento. Esto devuelve el mejor resultado de la "Ley del Derecho a la Vista del Contribuyente de 1993". Este documento tiene una puntuación de similitud de coseno de 0,76 entre la consulta y el 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."
Con este enfoque, puede usar incrustaciones como un mecanismo de búsqueda entre documentos de una base de conocimiento. Después, el usuario puede tomar el primer resultado de búsqueda y usarlo para su tarea posterior, que motivó su consulta inicial.
Solución de problemas
-
401/403: Verifique que
AZURE_OPENAI_API_KEYesté establecido y sea igual a su clave de recurso. -
404: Compruebe que
AZURE_OPENAI_EMBEDDINGS_DEPLOYMENTcoincide con el nombre de la implementación. -
Dirección URL no válida: compruebe
AZURE_OPENAI_ENDPOINTque es el punto de conexión del recurso, por ejemplohttps://<resource-name>.openai.azure.com.
Limpieza de recursos
Si creó un recurso de Azure OpenAI únicamente para completar este tutorial y desea limpiar y quitar un recurso de OpenAI de Azure, deberá eliminar los modelos implementados y, a continuación, eliminar el recurso o el grupo de recursos asociado si está dedicado al recurso de prueba. Al eliminar el grupo de recursos también se eliminan los demás recursos asociados.
Pasos siguientes
Obtenga más información sobre los modelos de Azure OpenAI:
modelos Azure OpenAI
- Almacene las incrustaciones y realice la búsqueda de vectores (similitud) mediante su elección de Azure servicio: