Logotipo de Zephyrnet

Mitigar las alucinaciones mediante la recuperación de generación aumentada utilizando la base de datos de vectores Pinecone y Llama-2 de Amazon SageMaker JumpStart | Servicios web de Amazon

Fecha:

A pesar de la adopción aparentemente imparable de los LLM en todas las industrias, son un componente de un ecosistema tecnológico más amplio que está impulsando la nueva ola de IA. Muchos casos de uso de IA conversacional requieren LLM como Llama 2, Flan T5 y Bloom para responder a las consultas de los usuarios. Estos modelos se basan en conocimientos paramétricos para responder preguntas. El modelo aprende este conocimiento durante el entrenamiento y lo codifica en los parámetros del modelo. Para actualizar este conocimiento, debemos volver a capacitar al LLM, lo que requiere mucho tiempo y dinero.

Afortunadamente, también podemos utilizar el conocimiento fuente para informar a nuestros LLM. El conocimiento fuente es información que se introduce en el LLM a través de un mensaje de entrada. Un enfoque popular para proporcionar conocimiento fuente es la generación aumentada de recuperación (RAG). Al utilizar RAG, recuperamos información relevante de una fuente de datos externa y la introducimos en el LLM.

En esta publicación de blog, exploraremos cómo implementar LLM como Llama-2 usando Amazon Sagemaker JumpStart y mantener nuestros LLM actualizados con información relevante a través de Retrieval Augmented Generation (RAG) usando la base de datos vectorial Pinecone para prevenir las alucinaciones por IA. .

Recuperación de generación aumentada (RAG) en Amazon SageMaker

Pinecone manejará el componente de recuperación de RAG, pero necesita dos componentes críticos más: algún lugar para ejecutar la inferencia LLM y algún lugar para ejecutar el modelo de incrustación.

Amazon SageMaker Studio es un entorno de desarrollo integrado (IDE) que proporciona una única interfaz visual basada en web donde puede acceder a herramientas diseñadas específicamente para realizar todo el desarrollo de aprendizaje automático (ML). Proporciona SageMaker JumpStart, que es un centro de modelos donde los usuarios pueden ubicar, obtener una vista previa e iniciar un modelo en particular en su propia cuenta de SageMaker. Proporciona modelos propietarios, previamente entrenados y disponibles públicamente para una amplia gama de tipos de problemas, incluidos los modelos básicos.

Amazon SageMaker Studio proporciona el entorno ideal para desarrollar canalizaciones de LLM habilitadas para RAG. Primero, usando la consola de AWS, vaya a Amazon SageMaker, cree un dominio de SageMaker Studio y abra una libreta de Jupyter Studio.

Requisitos previos

Complete los siguientes pasos de requisitos previos:

  1. Configure Amazon SageMaker Studio.
  2. Incorporación a un dominio de Amazon SageMaker.
  3. Regístrese para obtener una base de datos de vectores de piña de nivel gratuito.
  4. Bibliotecas de requisitos previos: SageMaker Python SDK, Pinecone Client

Tutorial de la solución

Al utilizar el cuaderno SageMaker Studio, primero necesitamos instalar las bibliotecas de requisitos previos:

!pip install -qU sagemaker pinecone-client==2.2.1 ipywidgets==7.0.0 

Implementación de un LLM

En esta publicación, analizamos dos enfoques para implementar un LLM. La primera es a través del HuggingFaceModel objeto. Puede usar esto al implementar LLM (e incorporar modelos) directamente desde el centro de modelos de Hugging Face.

Por ejemplo, puede crear una configuración implementable para el google/flan-t5-xl modelo como se muestra en la siguiente captura de pantalla:

import sagemaker
from sagemaker.huggingface import (
HuggingFaceModel, 
get_huggingface_llm_image_uri
)
role = sagemaker.get_execution_role()
hub_config = {'HF_MODEL_ID':'google/flan-t5-xl', # model_id from hf.co/models
'HF_TASK':'text-generation' # NLP task you want to use for predictions

# retrieve the llm image uri
llm_image = get_huggingface_llm_image_uri("huggingface", version="0.8.2"&)
huggingface_model = HuggingFaceModel(env=hub_config, role=role, # iam role with permissions to create an Endpoint 
image_uri=llm_image
)

Al implementar modelos directamente desde Hugging Face, inicialice el my_model_configuration con lo siguiente:

  • An env config nos dice qué modelo queremos usar y para qué tarea.
  • Nuestra ejecución de SageMaker role nos da permisos para implementar nuestro modelo.
  • An image_uri es una configuración de imagen específica para implementar LLM de Hugging Face.

Alternativamente, SageMaker tiene un conjunto de modelos directamente compatibles con un sistema más simple. JumpStartModel objeto. Este modelo admite muchos LLM populares como Llama 2, que se puede inicializar como se muestra en la siguiente captura de pantalla:

import sagemaker 
from sagemaker.jumpstart.model import JumpStartModel 

role = sagemaker.get_execution_role() 

my_model = JumpStartModel(model_id = "meta-textgeneration-llama-2-7b-f")

Para ambas versiones de my_model, impleméntelos como se muestra en la siguiente captura de pantalla:

predictor = my_model.deploy(
    initial_instance_count=1, instance_type="ml.g5.4xlarge", endpoint_name="llama-2-generator")

Consultar el LLM previamente capacitado

Con nuestro punto final LLM inicializado, puede comenzar a realizar consultas. El formato de nuestras consultas puede variar (particularmente entre LLM conversacionales y no conversacionales), pero el proceso es generalmente el mismo. Para el modelo Hugging Face, haga lo siguiente:

# https://aws.amazon.com/blogs/machine-learning/llama-2-foundation-models-from-meta-are-now-available-in-amazon-sagemaker-jumpstart/

prompt = """Answer the following QUESTION based on the CONTEXT
given. If you do not know the answer and the CONTEXT doesn't
contain the answer truthfully say "I don't know

ANSWER:

"""

payload = {
    "inputs":  
      [
        [
         {"role": "system", "content": prompt},
         {"role": "user", "content": question},
        ]   
      ],
   "parameters":{"max_new_tokens": 64, "top_p": 0.9, "temperature": 0.6, "return_full_text": False}
}

out = predictor.predict(payload, custom_attributes='accept_eula=true')
out[0]['generation']['content']

Puedes encontrar la solución en el Repositorio GitHub.

La respuesta generada que estamos recibiendo aquí no tiene mucho sentido: es una alucinación.

Proporcionar contexto adicional al LLM

Llama 2 intenta responder a nuestra pregunta basándose únicamente en el conocimiento paramétrico interno. Claramente, los parámetros del modelo no almacenan conocimiento de qué instancias podemos con el entrenamiento puntual administrado en SageMaker.

Para responder correctamente a esta pregunta, debemos utilizar el conocimiento fuente. Es decir, brindamos información adicional al LLM a través del mensaje. Agreguemos esa información directamente como contexto adicional para el modelo.

context = """Managed Spot Training can be used with all instances
supported in Amazon SageMaker. Managed Spot Training is supported
in all AWS Regions where Amazon SageMaker is currently available."""

prompt_template = """Answer the following QUESTION based on the CONTEXT
given. If you do not know the answer and the CONTEXT doesn't
contain the answer truthfully say "I don't know".

CONTEXT:
{context}

ANSWER:
"""

text_input = prompt_template.replace("{context}", context).replace("{question}", question)

payload = {
    "inputs":  
      [
        [
         {"role": "system", "content": text_input},
         {"role": "user", "content": question},
        ]   
      ],
   "parameters":{"max_new_tokens": 64, "top_p": 0.9, "temperature": 0.6, "return_full_text": False}
}

out = predictor.predict(payload, custom_attributes='accept_eula=true')
generated_text = out[0]['generation']['content']
print(f"[Input]: {question}n[Output]: {generated_text}")

[Input]: Which instances can I use with Managed Spot Training in SageMaker?

[Output]:  Based on the given context, you can use Managed Spot Training with all instances supported in Amazon SageMaker. Therefore, the answer is:

All instances supported in Amazon SageMaker.

Ahora vemos la respuesta correcta a la pregunta; ¡eso fue fácil! Sin embargo, es poco probable que un usuario inserte contextos en sus indicaciones; ya sabría la respuesta a su pregunta.

En lugar de insertar manualmente un único contexto, identifique automáticamente la información relevante de una base de datos de información más extensa. Para eso, necesitará recuperación de generación aumentada.

Recuperación Generación Aumentada

Con Retrieval Augmented Generation, puede codificar una base de datos de información en un espacio vectorial donde la proximidad entre vectores representa su relevancia/similitud semántica. Con este espacio vectorial como base de conocimiento, puede convertir una nueva consulta de usuario, codificarla en el mismo espacio vectorial y recuperar los registros más relevantes previamente indexados.

Después de recuperar estos registros relevantes, seleccione algunos de ellos e inclúyalos en el mensaje del LLM como contexto adicional, proporcionando al LLM conocimientos fuente muy relevantes. Este es un proceso de dos pasos donde:

  • La indexación completa el índice vectorial con información de un conjunto de datos.
  • La recuperación ocurre durante una consulta y es donde recuperamos información relevante del índice del vector.

Ambos pasos requieren un modelo de incrustación para traducir nuestro texto plano legible por humanos al espacio vectorial semántico. Utilice el transformador de oraciones MiniLM altamente eficiente de Hugging Face como se muestra en la siguiente captura de pantalla. Este modelo no es un LLM y por lo tanto no se inicializa de la misma manera que nuestro modelo Llama 2.

hub_config = {
    "HF_MODEL_ID": "sentence-transformers/all-MiniLM-L6-v2",  # model_id from hf.co/models
    "HF_TASK": "feature-extraction",
}

huggingface_model = HuggingFaceModel(
    env=hub_config,
    role=role,
    transformers_version="4.6",  # transformers version used
    pytorch_version="1.7",  # pytorch version used
    py_version="py36",  # python version of the DLC
)

En hub_config, especifique la ID del modelo como se muestra en la captura de pantalla anterior, pero para la tarea, use la extracción de características porque estamos generando incrustaciones de vectores, no texto como nuestro LLM. Después de esto, inicialice la configuración del modelo con HuggingFaceModel como antes, pero esta vez sin la imagen LLM y con algunos parámetros de versión.

encoder = huggingface_model.deploy(
    initial_instance_count=1, instance_type="ml.t2.large", endpoint_name="minilm-embedding"
)

Puede implementar el modelo nuevamente con deploy, utilizando la instancia más pequeña (solo CPU) de ml.t2.large. El modelo MiniLM es pequeño, por lo que no requiere mucha memoria y no necesita una GPU porque puede crear incrustaciones rápidamente incluso en una CPU. Si lo prefiere, puede ejecutar el modelo más rápido en la GPU.

Para crear incrustaciones, utilice el predict método y pasar una lista de contextos para codificar a través del inputs clave como se muestra:

out = encoder.predict({"inputs": ["some text here", "some more text goes here too"]})

Se pasan dos contextos de entrada y se devuelven dos incrustaciones de vectores de contexto como se muestra:

len(out)

2

La dimensionalidad de incrustación del modelo MiniLM es 384 lo que significa que cada vector que incorpora salidas MiniLM debe tener una dimensionalidad de 384. Sin embargo, si observa la longitud de nuestras incrustaciones, verá lo siguiente:

len(out[0]), len(out[1])

(8, 8)

Dos listas contienen ocho elementos cada una. MiniLM primero procesa el texto en un paso de tokenización. Esta tokenización transforma nuestro texto sin formato legible por humanos en una lista de ID de token legibles por modelos. En las características de salida del modelo, puede ver las incorporaciones a nivel de token. una de estas incrustaciones muestra la dimensionalidad esperada de 384 como se muestra:

len(out[0][0])

384

Transforme estas incrustaciones a nivel de token en incrustaciones a nivel de documento utilizando los valores medios en cada dimensión vectorial, como se muestra en la siguiente ilustración.

Operación de agrupación media para obtener un único vector de 384 dimensiones.

import numpy as np embeddings = np.mean(np.array(out), axis=1)embeddings.shape(2, 384)

Con dos incrustaciones de vectores de 384 dimensiones, una para cada texto de entrada. Para hacernos la vida más fácil, envuelva el proceso de codificación en una sola función como se muestra en la siguiente captura de pantalla:

from typing import List

def embed_docs(docs: List[str]) -> List[List[float]]:
    out = encoder.predict({"inputs": docs})
    embeddings = np.mean(np.array(out), axis=1)
    return embeddings.tolist()

Descargando el conjunto de datos

Descargue las preguntas frecuentes de Amazon SageMaker como base de conocimientos para obtener los datos que contienen columnas de preguntas y respuestas.

Descargue las preguntas frecuentes de Amazon SageMaker

Al realizar la búsqueda, busque solo Respuestas, para poder soltar la columna Pregunta. Ver cuaderno para más detalles..

Nuestro conjunto de datos y el proceso de incorporación están listos. Ahora todo lo que necesitamos es un lugar donde almacenar esas incrustaciones.

Indexación

La base de datos de vectores de Pinecone almacena incrustaciones de vectores y las busca de manera eficiente a escala. Para crear una base de datos, necesitará una clave API gratuita de Pinecone.

import pinecone
import os

# add Pinecone API key from app.pinecone.io
api_key = os.environ.get("PINECONE_API_KEY") or "YOUR_API_KEY"
# set Pinecone environment - find next to API key in console
env = os.environ.get("PINECONE_ENVIRONMENT") or "YOUR_ENV"

pinecone.init(api_key=api_key, environment=env)

Después de conectarse a la base de datos de vectores de Pinecone, cree un índice de vector único (similar a una tabla en las bases de datos tradicionales). Nombra el índice retrieval-augmentation-aws y alinear el índice dimension y metric parámetros con los requeridos por el modelo de incrustación (MiniLM en este caso).

import time

index_name = "retrieval-augmentation-aws"

if index_name in pinecone.list_indexes():
    pinecone.delete_index(index_name)

pinecone.create_index(name=index_name, dimension=embeddings.shape[1], metric="cosine")
# wait for index to finish initialization
while not pinecone.describe_index(index_name).status["ready"]:
    time.sleep(1)

Para comenzar a insertar datos, ejecute lo siguiente:

from tqdm.auto import tqdm

batch_size = 2  # can increase but needs larger instance size otherwise instance runs out of memory
vector_limit = 1000

answers = df_knowledge[:vector_limit]
index = pinecone.Index(index_name)

for i in tqdm(range(0, len(answers), batch_size)):
    # find end of batch
    i_end = min(i + batch_size, len(answers))
    # create IDs batch
    ids = [str(x) for x in range(i, i_end)]
    # create metadata batch
    metadatas = [{"text": text} for text in answers["Answer"][i:i_end]]
    # create embeddings
    texts = answers["Answer"][i:i_end].tolist()
    embeddings = embed_docs(texts)
    # create records list for upsert
    records = zip(ids, embeddings, metadatas)
    # upsert to Pinecone
    index.upsert(vectors=records)

Puede comenzar a consultar el índice con la pregunta anterior en esta publicación.

# extract embeddings for the questions
query_vec = embed_docs(question)[0]

# query pinecone
res = index.query(query_vec, top_k=1, include_metadata=True)

# show the results
res
{'matches': [{'id': '90',
'metadata': {'text': 'Managed Spot Training can be used with all '
'instances supported in Amazon '
'SageMaker.rn'},
'score': 0.881181657,
'values': []}],
'namespace': ''}

El resultado anterior muestra que estamos devolviendo contextos relevantes para ayudarnos a responder nuestra pregunta. Desde que nosotros top_k = 1, index.query devolvió el resultado superior junto con los metadatos que leen Managed Spot Training can be used with all instances supported in Amazon.

Aumentar el aviso

Utilice los contextos recuperados para aumentar el mensaje y decidir la cantidad máxima de contexto para incluir en el LLM. Utilizar el 1000 Límite de caracteres para agregar de forma iterativa cada contexto devuelto al mensaje hasta que exceda la longitud del contenido.

Aumentar el aviso

Aumentar el aviso

Alimentar el context_str en el mensaje LLM como se muestra en la siguiente captura de pantalla:

payload = create_payload(question, context_str)
out = predictor.predict(payload, custom_attributes='accept_eula=true')
generated_text = out[0]['generation']['content']
print(f"[Input]: {question}n[Output]: {generated_text}")

[Entrada]: ¿Qué instancias puedo usar con Managed Spot Training en SageMaker? [Salida]: Según el contexto proporcionado, puede utilizar Managed Spot Training con todas las instancias admitidas en Amazon SageMaker. Por tanto, la respuesta es: Todas las instancias admitidas en Amazon SageMaker.

La lógica funciona, así que envuélvela en una sola función para mantener todo limpio.

def rag_query(question: str) -> str:
    # create query vec
    query_vec = embed_docs(question)[0]
    # query pinecone
    res = index.query(query_vec, top_k=5, include_metadata=True)
    # get contexts
    contexts = [match.metadata["text"] for match in res.matches]
    # build the multiple contexts string
    context_str = construct_context(contexts=contexts)
    # create our retrieval augmented prompt
    payload = create_payload(question, context_str)
    # make prediction
    out = predictor.predict(payload, custom_attributes='accept_eula=true')
    return out[0]["generation"]["content"]

Ahora puede hacer preguntas como las que se muestran a continuación:

rag_query("Does SageMaker support spot instances?")

' Yes, Amazon SageMaker supports spot instances for managed spot training. According to the provided context, Managed Spot Training can be used with all instances supported in Amazon SageMaker, and Managed Spot Training is supported in all AWS Regions where Amazon SageMaker is currently available.nnTherefore, the answer to your question is:nnYes, SageMaker supports spot instances in all regions where Amazon SageMaker is available.'

Limpiar

Para dejar de incurrir en cargos no deseados, elimine el modelo y el punto final.

encoder.delete_model()

encoder.delete_endpoint()

Conclusión

En esta publicación, le presentamos RAG con LLM de acceso abierto en SageMaker. También mostramos cómo implementar modelos Jumpstart de Amazon SageMaker con Llama 2, LLM de Hugging Face con Flan T5 y modelos integrados con MiniLM.

Implementamos una canalización RAG completa de extremo a extremo utilizando nuestros modelos de acceso abierto y un índice vectorial Pinecone. Con esto, mostramos cómo minimizar las alucinaciones, mantener actualizado el conocimiento de LLM y, en última instancia, mejorar la experiencia del usuario y la confianza en nuestros sistemas.

Para ejecutar este ejemplo por su cuenta, clone este repositorio de GitHub y siga los pasos anteriores utilizando el Cuaderno de respuesta a preguntas en GitHub.


Sobre los autores

Foto de perfil de Vedant Jainjainista vedante es un especialista senior en IA/ML que trabaja en iniciativas estratégicas de IA generativa. Antes de unirse a AWS, Vedant ocupó puestos de especialidad en ciencia de datos y aprendizaje automático en varias empresas, como Databricks, Hortonworks (ahora Cloudera) y JP Morgan Chase. Fuera de su trabajo, a Vedant le apasiona hacer música, escalar rocas, utilizar la ciencia para llevar una vida significativa y explorar cocinas de todo el mundo.

james briggs es un defensor del personal desarrollador en Pinecone, y se especializa en búsqueda de vectores e IA/ML. Guía a desarrolladores y empresas en el desarrollo de sus propias soluciones GenAI a través de la educación en línea. Antes de Pinecone, James trabajó en inteligencia artificial para pequeñas empresas emergentes de tecnología y corporaciones financieras establecidas. Fuera del trabajo, a James le apasiona viajar y emprender nuevas aventuras, desde surf y buceo hasta muay thai y BJJ.

XinHuangXinHuang es un científico senior aplicado para los algoritmos integrados de Amazon SageMaker JumpStart y Amazon SageMaker. Se centra en el desarrollo de algoritmos escalables de aprendizaje automático. Sus intereses de investigación se encuentran en el área del procesamiento del lenguaje natural, el aprendizaje profundo explicable en datos tabulares y el análisis sólido de la agrupación de espacio-tiempo no paramétrica. Ha publicado muchos artículos en conferencias ACL, ICDM, KDD y Royal Statistical Society: Serie A.

punto_img

Información más reciente

punto_img