Implementação de pipelines RAG robustos: integração do Gemma 2 do Google (2B) técnicas de avaliação do MongoDB e LLM
Avalie esse Artigo
Durante os primeiros dias da era da AI generativa, um período definido pelo surgimento de modelos de linguagem grandes (LLMs) capazes de capacidades avançadas de Síntese de Resposta, Raciocício e Planejamento, a tendência observável foi um aumento no número de parâmetros dentro de modelos recém-lançados . O GPT-3 foi lançado com 175 bilhões de parâmetros em 2020, marcando um salto significativo em relação ao seu antecessor, GPT-2, que tinha 1.5 bilhões de parâmetros. Essa tendência continua com modelos ainda maiores, como o GPT-4, estimado em ter mais de um trilião de parâmetros, embora a OpenAI ainda não tenha revelado o número exato publicamente.
No entanto, um esforço de compensação também estava ocorrendo para reduzir os tamanhos desses modelos de idioma, mantendo as capacidades e qualidades de LLMs de tamanho semelhante. O Google é um ator em ambos os lados do esforço de dimensionamento do modelo de idioma. Gêmeos é o LLM multimodal do Google, lançado em dezembro de 2023. Várias versões foram lançadas depois de oferecer as capacidades potenciais de grandes modelos de linguagem que abrangem bilhões de parâmetros e têm amplas janelas de contexto para entradas no LLM.
No entanto, o foco principal deste tutorial é a Gemma 2, especialmente a variante com apenas dois bilhões de parâmetros.
Conforme descrito pelo Google, a Gemma "is a family of lightweight, state-of-the-art open models " foi construída com os mesmos blocos de construção usados para criar os modelos da Gemma. Linguagem pequena e modelos abertos têm seu lugar em vários casos de uso que exigem eficiência, redução de custos, privacidade e latência.
Abaixo estão alguns exemplos de casos de uso em que os modelos Gemma serão viáveis para os desenvolvedores.
Setor | Caso de uso | Descrição | Principal benefício |
Operações | Assistente de orçamento personalizado | Um recurso de aplicativo móvel que analisa padrões de gastos e oferece conselhos financeiros personalizados aos usuários | Um modelo menor como o Gemma 2B é ideal aqui — é leve o suficiente para ser executado em um telefone celular, respeita a privacidade do usuário ao processar dados localmente e pode fornecer respostas rápidas e contextuais sem enviar dados financeiros confidenciais para um servidor na nuvem. |
Saúde | Verificador de sincronia médica | Um aplicativo da web para a triagem inicial de pacientes, entendendo os sinais descritos pelo usuário e sugerindo possíveis causas ou níveis de urgência | O Gemma 2B pode ser ajustado em conjuntos de dados médicas para fornecer avaliações iniciais rápidas e precisas sem infraestrutura cara ou comprometer a privacidade dos dados do pai. |
Atendimento ao cliente | chatbot inteligente | Um chatbot avançado de serviço ao cliente para uma empresa SaaS que entende o contexto e responde mais naturalmente às consultas do cliente | As pequenas variantes do modelo (2B e 9B) facilitam a implantação e a atualização, permitindo iterações rápidas com base no feedback do usuário e nas novas funcionalidades do produto. |
Este tutorial aborda a criação de um assistente de analista de gerenciamento de ativos usando o Gemma 2. O assistente pode analisar relatórios de mercado armazenados em um banco de dados MongoDB com base em queries fornecidas pelo usuário, aumentando efetivamente algumas das responsabilidades de um analista.
O tutorial também introduz o tópico da avaliação LLM, concentrando-se especificamente na avaliação de componentes-chave em um pipeline típico de geração aumentada de recuperação (RAG).
O que é abordado neste tutorial
- Construindo um assistente de analista de gerenciamento de ativos com o Gemma 2
- Implementação de um pipeline RAG com MongoDB
- Vector Atlas Search e técnicas de recuperação semântica
- Gerando respostas usando o modelo Gemma 2 (2B)
- Avaliação LLM para componentes RAG
Todas as etapas de código e implementação neste tutorial podem ser encontradas no Github
A primeira etapa é instalar todas as bibliotecas necessárias para fornecer as funcionalidades para criar os componentes do pipeline RAG e realizar a avaliação LLM para os componentes de recuperação e geração do pipeline RAG.
- PyMongo: facilita a interação com bancos de dados MongoDB
- Pandas: fornece recursos avançados de manipulação e análise de dados
- Abraçando a Face (conjuntos de dados): Oferece acesso a uma ampla coleção de conjuntos de dados pré-processados
- Abraçando a face (transformadores de frases): fornece acesso a incorporações de frases, texto e imagens
- OpenEvals: fornece métricas para avaliar o desempenho do LLM em várias dimensões
Execute o seguinte comando para instalar e atualizar as bibliotecas necessárias:
1 !pip install --upgrade --quiet datasets pandas pymongo sentence_transformers deepevals
A configuração de variáveis de ambiente é crucial para garantir o acesso seguro a serviços externos. Essa prática aumenta a segurança mantendo informações confidenciais fora da sua base de código. Verifique se você tem um token de Face Abraçando(RF_TOKEN) em seu ambiente de desenvolvimento antes de executar o código abaixo.
1 import os 2 import getpass 3 # Make sure you have an Hugging Face token(HF_TOKEN) in your development environment before running the code below 4 # How to get a token: https://huggingface.co/docs/hub/en/security-tokens 5 os.environ["HF_TOKEN"] = getpass.getpass("Enter your Hugging Face token: ") 6 os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter your OpenAI API key: ") # Need this for the evaluation step
Esta etapa carrega um conjunto de dados financeiros do Abraçando Face no ambiente de desenvolvimento atual. O processo de preparação de dados então cria um novo atributo para cada ponto de dados combinando vários atributos existentes. Este atributo combinado é preparado para a etapa de geração de incorporação subsequente.
O carregamento e a preparação de dados são processos na maioria das tarefas relacionadas a dados e pipelines de processamento. O carregamento de dados refere-se à obtenção de dados de uma fonte externa e à sua importação para o ambiente de desenvolvimento atual para processamento posterior. A preparação de dados refere-se à organização do conteúdo de um conjunto de dados em um formato necessário para os processos downstream. Neste tutorial, os dados são carregados da organização MongoDB Abraçando Face.
O conjunto de dados é projetado para análise financeira e pesquisa de mercado no setor de tecnologia. Ele fornece uma visão abrangente de cada empresa, incluindo notícias, métricas financeiras e relatórios de analistas. Ele pode ser usado para tarefas como análise de confiança, análise de tendências de mercado ou como parte de um sistema de recomendações financeiros.
1 import pandas as pd 2 from datasets import load_dataset 3 4 # Make sure you have an Hugging Face token(HF_TOKEN) in your development environment before running the code below 5 # How to get a token: https://huggingface.co/docs/hub/en/security-tokens 6 # https://huggingface.co/datasets/MongoDB/fake_tech_companies_market_reports 7 dataset = load_dataset("MongoDB/fake_tech_companies_market_reports", split="train", streaming=True) 8 dataset_df = dataset.take(100) 9 10 # Convert the dataset to a pandas dataframe 11 dataset_df = pd.DataFrame(dataset_df) 12 dataset_df.head(5)
Aqui estão as etapas realizadas no trecho de código acima:
- A função
load_dataset
é usada para buscar o conjunto de dados"fake_tech_companies_market_reports"
da organização MongoDB no Abraço do Face. - A divisão "trem" é especificada e normalmente é usada para o conjunto de dados principal em tarefas de aprendizado de máquina.
- O parâmetro
streaming=True
é crucial aqui. Ele permite o carregamento lento de conjuntos de dados, permitindo-nos trabalhar com conjuntos de dados potencialmente muito grandes sem carregar tudo na memória de uma só vez. `dataset_df = - dataset.take(100)
uses the
método take' para extrair as primeiras 100 amostras do conjunto de dados. - Depois de extrair um subconjunto gerenciável dos dados, usamos o Pandas para criar um objeto DataFrame dos dados para visualização e manipulação eficientes dos dados.
- Usamos o método " head " do Pandas para entender a estrutura e o conteúdo do conjunto de dados.
As operações acima são etapas realizadas para carregar dados no ambiente de desenvolvimento e fornecer dados específicos do domínio para o problema que estamos tentando resolver. Especificamente, estamos criando um chatbot habilitado para RAG que fornece informações de mercado sobre empresas de base tecnologia para o caso de uso de gerenciamento de ativos. A segunda metade desta seção se concentra na preparação de dados.
Uma parte crucial do processo do pipeline RAG é a incorporação de dados, que cria uma representação semântica de cada ponto de dados que pode ser recuperado usando técnicas de recuperação de informações, como o Atlas Search vetorial. Entender quais atributos de dados capturam melhor a semântica ou, em termos mais simples, o significado de um único ponto de dados, é crucial para criar aplicativos RAG precisos e confiáveis. Portanto, os profissionais devem selecionar e pré-processar cuidadosamente as funcionalidades mais relevantes para incorporação.
Isso envolve:
- Realização de análise exploratória completa de dados para entender a estrutura e o conteúdo do conjunto de dados.
- Identificar os principais atributos que melhor representam a essência semântica de cada ponto de dados.
- Considerar o conhecimento específico do domínio para orientar a seleção de recursos e a engenharia.
- Avalie e ajuste o processo de incorporação regularmente para garantir que ele capture com precisão os significados e relacionamentos sucessivos dos dados.
Para nosso caso de uso e este tutorial, a combinação dos atributos de dados relatório, empresa e setor é suficiente para capturar os detalhes semântica de um ponto de dados. O trecho de código abaixo mostra a operação de selecionar os atributos e, em seguida, definir a função
combine_attributes
para retornar a string concatenada dos atributos selecionados.1 # Data Preparation 2 def combine_attributes(row): 3 combined = f"{row['company']} {row['sector']} " 4 5 # Add report information 6 for report in row['reports']: 7 combined += f"{report['year']} {report['title']} {report['author']} {report['content']} " 8 9 # Add recent news information 10 for news in row['recent_news']: 11 combined += f"{news['headline']} {news['summary']} " 12 13 return combined.strip()
O próximo processo aplica o
combine_attributes
a cada ponto de dados no conjunto de dados e armazena o resultado da operação em um novo atributo de ponto de dados: combined_attributes
. Este será o atributo que será passado para o modelo de incorporação.1 # Add the new column 'combined_attributes' 2 dataset_df['combined_attributes'] = dataset_df.apply(combine_attributes, axis=1)
Esteja ciente do tamanho da janela de contexto do modelo de incorporação que você usa. Esses modelos normalmente têm uma capacidade de entrada finita, geralmente medida em tokens ou caracteres. Quando a entrada excede esse limite, o modelo pode truncar o excesso, potencialmente resultando em perda significativa de informações. Esse truncamento pode afetar gravemente a qualidade e a relevância das incorporações geradas, comprometendo o desempenho geral do seu sistema RAG.
Se você tiver dados muitos para incorporar, vale a pena explorar várias estratégias de chunking. O conselhos padrão para os profissionais aqui é implementar algoritmos de chunking para documentos mais longos que dividem o texto em segmentos semanticamente coerentes, cada um se encaixando na janela de contexto do modelo e considerando chunks sobrepostos para manter a continuação contextual.
Para este caso de uso e tutorial, a estratégia de chunking aproveitada é chunking quaisquer dados que se estendam além do comprimento máximo do token de entrada do modelo de incorporação e anexar os mesmos metadados aos chunks inicial e secundário.
A série de modelos GTE (Geral Text Embeddings), desenvolvida pelo Instituto de Computação Inteligente do Alibaba Group, oferece desempenho de ponta em tecnologia de incorporação de texto. Para este tutorial, nos concentramos no uso do GTE-Large English V1.5, que oferece um equilíbrio ideal entre desempenho e eficiência computacional. Este modelo incorporado obtém a pontuação 65.39 no Massive Text Embedding Benchmark (MTEB) para inglês, indicando o desempenho geral de incorporação em um conjunto diversos de tarefas e conjuntos de dados de NLP. Para o caso de uso abordado neste tutorial que envolve tarefas de recuperação de informações, o que significa localizar documentos relevantes para uma query de entrada, o GTE-Large English V1. O modelo 5 demonstra um bom desempenho com uma pontuação média de recuperação de 57.91 com base em uma avaliação 15 conjuntos de dados.
1 from sentence_transformers import SentenceTransformer 2 from tqdm import tqdm 3 import numpy as np 4 5 6 # https://huggingface.co/thenlper/gte-large 7 # embedding_model = SentenceTransformer('thenlper/gte-large') 8 embedding_model = SentenceTransformer('Alibaba-NLP/gte-large-en-v1.5', trust_remote_code=True) 9 10 11 # Determine the maximum sequence length for the model 12 max_seq_length = embedding_model.max_seq_length 13 14 15 16 17 def chunk_text(text, tokenizer, max_length=8192, overlap=50): 18 """ 19 Split the text into overlapping chunks based on token length. 20 """ 21 tokens = tokenizer.tokenize(text) 22 chunks = [] 23 for i in range(0, len(tokens), max_length - overlap): 24 chunk_tokens = tokens[i:i + max_length] 25 chunk = tokenizer.convert_tokens_to_string(chunk_tokens) 26 chunks.append(chunk) 27 return chunks 28 29 30 def get_embedding(text: str) -> list[float]: 31 if not text.strip(): 32 print("Attempted to get embedding for empty text.") 33 return [] 34 35 36 # Get the tokenizer from the model 37 tokenizer = embedding_model.tokenizer 38 39 40 # Split text into chunks if it's too long 41 chunks = chunk_text(text, tokenizer, max_length=max_seq_length) 42 43 if len(chunks) == 1: 44 # If text fits in one chunk, embed as usual 45 embedding = embedding_model.encode(text) 46 else: 47 # If text was split, embed each chunk and average the results 48 chunk_embeddings = embedding_model.encode(chunks) 49 embedding = np.mean(chunk_embeddings, axis=0) 50 51 return embedding.tolist() 52 53 # Apply the embedding function with a progress bar 54 tqdm.pandas(desc="Generating embeddings") 55 dataset_df["embedding"] = dataset_df['combined_attributes'].progress_apply(get_embedding)
O trecho de código acima executa as seguintes operações: Chunk os dados de entrada que devem ser passados para o modelo de incorporação se excederem um determinado comprimento:
- Utilize a função
chunk_text
para tokenizar e dividir textos longos. - Verifique se a divisão do texto está dentro do
max_seq_length
do modelo (8192 tokens para GTE-Large English V1.5). - Implemente uma sobreposição de tokens 50 entre chunks para manter a sequência do contexto.
Passe o(s) chunk(s) para o modelo de incorporação:
- Para chunks únicos, codifique diretamente usando
embedding_model.encode(text)
. - Para vários blocos, codifique cada bloco separadamente.
- Manipule possíveis entradas vazias, retornando uma lista vazia se alguma entrada vazia estiver presente.
Armazene os dados de incorporação como um novo atributo
embedding
para cada ponto de dados:- Utilize tqdm para exibir uma barra de progresso para todos os pontos de dados durante o processo de incorporação.
- Adicione as incorporações resultantes como uma nova coluna "embedding" no DataFramedo
dataset_df
.
Neste tutorial e em muitos aplicativos RAG, o MongoDB atua como um banco de dados operacional e vetorial. O MongoDB Atlas fornece especificamente uma solução de banco de dados que armazena, consulta e recupera incorporações vetoriais de forma eficiente.
A criação de um banco de dados e de uma coleção no MongoDB é simplificada com o MongoDB Atlas.
- Primeiro, registre-se para obter uma conta do MongoDB Atlas. Usuários existentes podem entrar no MongoDB Atlas.
- Siga as instruções. Selecione Atlas UI como o procedimento para implantar seu primeiro cluster.
- Crie o banco de dados:
asset_management_use_case
. - No banco de dados
asset_management_use_case
, crie a collectionmarket_reports
. - Crie um índice vetorial do Atlas Search chamado vector_index para a coleção 'listings_reviews'. Esse índice permite que o aplicativo RAG recupere registros como contexto adicional para complementar as queries do usuário por meio do Atlas Search vetorial. Abaixo está a definição JSON do índice Atlas Search do vetor de coleta de dados.
Seu índice vetorial do Atlas Search criado no MongoDB Atlas deve ter a seguinte aparência:
1 { 2 "fields": [ 3 { 4 "numDimensions": 1024, 5 "path": "embedding", 6 "similarity": "cosine", 7 "type": "vector" 8 } 9 ] 10 }
Siga as etapas do MongoDB para obter a connection string a partir da UI do Atlas. Depois de configurar o banco de dados e obter o URI de conexão do Atlas cluster, armazene o URI com segurança em seu ambiente de desenvolvimento.
1 os.environ["MONGO_URI"] = getpass.getpass("Enter your MongoDB URI: ")
1 import pymongo 2 3 4 def get_mongo_client(mongo_uri): 5 """Establish and validate connection to the MongoDB.""" 6 7 8 client = pymongo.MongoClient(mongo_uri, appname="devrel.showcase.rag.cohere_mongodb.python") 9 10 11 # Validate the connection 12 ping_result = client.admin.command('ping') 13 if ping_result.get('ok') == 1.0: 14 # Connection successful 15 print("Connection to MongoDB successful") 16 return client 17 else: 18 print("Connection to MongoDB failed") 19 return None 20 21 22 MONGO_URI = os.environ["MONGO_URI"] 23 24 25 if not MONGO_URI: 26 print("MONGO_URI not set in environment variables") 27 28 29 mongo_client = get_mongo_client(MONGO_URI) 30 31 32 DB_NAME = "asset_management_use_case" 33 COLLECTION_NAME = "market_reports" 34 35 36 db = mongo_client.get_database(DB_NAME) 37 collection = db.get_collection(COLLECTION_NAME)
Neste tutorial, para garantir que estamos trabalhando com uma coleção limpa, você pode executar o código abaixo para limpar a coleção de quaisquer dados existentes.
1 # Delete any existing records in the collection 2 collection.delete_many({})
MongoDBO do document model e sua compatibilidade com Python dicionários oferecemMongoDB vários benefícios para a ingestão de Python dados. A estrutura orientada a documentos do oferece várias vantagens para armazenamento e manipulação de dados em aplicativos . O núcleo dessa estrutura é o uso de BSON (Binary JSON) para armazenamento de dados, que se alinha naturalmente ao Python tipo de dados de dicionário do . Esse emparelhamento facilita os dados representação usando pares chave-valor, tornando intuitivo para Python os desenvolvedores trabalhar com MongoDB.
Uma das principais funcionalidades do MongoDB é a flexibilidade de esquema. Ao contrário dos bancos de dados relacionais tradicionais, o MongoDB não tem esquema, permitindo que cada documento em uma collection tenha uma estrutura diferente. Essa flexibilidade é particularmente vantajoso em ambientes Python, pois completa a natureza dinâmica do Python. Os desenvolvedores podem consumir estruturas de dados diversas sem esquemas predefinidos, oferecendo maior manuseio de dados e adaptabilidade de armazenamento.
Outro benefício significativo de trabalhar com Python é a eficiência da ingestão de dados do MongoDB. A similaridade entre os dicionários do Python e os documentos do MongoDB permite a ingestão direta de dados sem transformações complexas. Esse processo simplificado resulta em inserção de dados mais rápida e sobrecarga de processamento reduzida, fazendo do MongoDB uma escolha ideal para aplicativos que exigem armazenamento e recuperação rápidos de dados em sistemas baseados em Python.
E é por isso que o processo de ingestão deste tutorial é concluído em uma ou duas linhas:
1 documents = dataset_df.to_dict('records') 2 collection.insert_many(documents) 3 print("Data ingestion into MongoDB completed")
A linguagem de query do MongoDB foi projetada para funcionar bem com estruturas de documentos, facilitando a query e a manipulação de dados ingeridos usando uma sintaxe familiar semelhante ao Python. A linguagem de query é executada usando o pipeline de agregação do MongoDB, um recurso poderoso que permite o processamento e a análise de dados complexos dentro do banco de dados.
Um pipeline de agregação pode ser analisado de forma semelhante aos pipelines da engenharia de dados ou do aprendizado de máquina, onde os processos operam sequencialmente. Cada estágio recebe uma entrada, executa operações e fornece uma saída para o próximo estágio.
Os estágios são os blocos de construção de um pipeline de agregação. Cada estágio representa uma operação de transformação ou análise de dados específica. Os estágios comuns incluem:
$match
: filtra documentos (semelhante a ONDE em SQL) $group
: agrupadocumentos por campos especificados $sort
: classifica os documentos $project
: remodela documentos (selecionar, renomear, campos de computação) $limit
: limita o número de documentos $unwind
: desconstrói campos de array $lookup
: Executa junções externas esquerdas com outras collections O trecho de código abaixo define uma função
vector search
demonstrando a implementação semântica do Atlas Search usando os recursos vetoriais do MongoDB. Em seu núcleo, a função aproveita incorporações de vetores densos para encontrar documentos semanticamente semelhantes à query de um usuário. Ele começa convertendo a query de entrada em uma incorporação vetorial e, em seguida, utiliza MongoDB operador$vectorSearch
do MongoDB para o Atlas Search por meio de uma coleção pré-indexada de incorporações de documentos de forma eficiente.1 def vector_search(user_query, collection): 2 """ 3 Perform a vector search in the MongoDB collection based on the user query. 4 5 6 Args: 7 user_query (str): The user's query string. 8 collection (MongoCollection): The MongoDB collection to search. 9 10 11 Returns: 12 list: A list of matching documents. 13 """ 14 15 16 # Generate embedding for the user query 17 query_embedding = get_embedding(user_query) 18 19 20 if query_embedding is None: 21 return "Invalid query or embedding generation failed." 22 23 24 # Define the vector search pipeline 25 vector_search_stage = { 26 "$vectorSearch": { 27 "index": "vector_index", 28 "queryVector": query_embedding, 29 "path": "embedding", 30 "numCandidates": 150, # Number of candidate matches to consider 31 "limit": 2 # Return top 4 matches 32 } 33 } 34 35 36 unset_stage = { 37 "$unset": "embedding" # Exclude the 'embedding' field from the results 38 } 39 40 41 project_stage = { 42 "$project": { 43 "_id": 0, # Exclude the _id field 44 "company": 1, # Include the plot field 45 "reports": 1, # Include the title field 46 "combined_attributes": 1, # Include the genres field 47 "score": { 48 "$meta": "vectorSearchScore" # Include the search score 49 } 50 } 51 } 52 53 54 pipeline = [vector_search_stage, unset_stage, project_stage] 55 56 57 # Execute the search 58 results = collection.aggregate(pipeline) 59 return list(results)
O trecho de código acima realiza as seguintes operações:
- Converte a query de texto do usuário em incorporação vetorial usando a função
get_embedding
, que aproveita as operações de incorporação anteriores definidas anteriormente - Utiliza o operador
$vectorSearch
do MongoDB para encontrar documentos semanticamente semelhantes - Pesquisa o
vector_index
utilizando a incorporação da query; garante que o índice do vetor Atlas Search tenha sido criado no MongoDB Atlas e seja referenciado na consulta usando o nome especificado na criação - Define
numCandidates
como 150 para correspondência inicial ampla - Limita os resultados finais às duas principais correspondências
- Utiliza um estágio
$unset
para remover o campo "incorporação" dos resultados, reduzindo a transferência de dados - Utiliza um estágio do
$project
para incluir seletivamente campos relevantes: "company", "reports" e "combined_attributes" - Adiciona uma pontuação de similaridade usando
$meta: "vectorSearchScore"
- Combina os estágios em um único pipeline de agregação
- Executa a Atlas Search usando
collection.aggregate()
- Retorna os resultados como uma lista de documentos
A próxima etapa após a criação do aspecto do componente de recuperação de informações do pipeline RAG é lidar com o resultado, o que significa essencialmente formatar os documentos recuperados de uma maneira que sejam consumidos pelo LLM na etapa de geração do pipeline RAG.
No trecho de código abaixo, a função
get_search_result
serve como um invólucro para a operação vetorial Atlas Search, transformando os resultados brutos do Atlas Search em um formato mais amigável. A função retorna uma string formatada contendo informações resumidas dos principais resultados do Atlas Search.1 def get_search_result(query, collection): 2 3 4 get_knowledge = vector_search(query, collection) 5 6 7 search_result = '' 8 for result in get_knowledge: 9 search_result += f"Company: {result.get('company', 'N/A')}, Combined Attributes: {result.get('combined_attributes', 'N/A')}\n" 10 11 12 return search_result
A próxima etapa é definir uma query de entrada para o pipeline RAG. Essa query de entrada é semelhante ao esperado para interfaces de chatbots que esperam prompts ou entradas dos usuários e fornecem uma resposta. Para o caso de uso neste tutorial, o trecho de código abaixo demonstra a aplicação prática da funcionalidade semântica do Atlas Search em um contexto de resposta a perguntas.
1 # Conduct query with the retrieval of sources 2 query = "What companies have negative market reports or negative sentiment that might deter from investment in the long term" 3 source_information = get_search_result(query, collection) 4 combined_information = f"Query: {query}\nContinue to answer the query by using the Search Results:\n{source_information}." 5 6 print(combined_information)
Esta seção do tutorial demonstra a inicialização do Gemma 2.0 (2B), um modelo de linguagem aberta de dois bilhões de parâmetros e seu tokenizador associado. Essa variante específica do modelo é ajustada por instruções, o que significa que ela foi especificamente ajustada em um conjunto de dados de instruções e respostas, aprimorando sua capacidade de entender e seguir as solicitações do usuário com precisão.
O trecho de código abaixo usa a biblioteca de transformação do Abraçando Face para carregar os tokenizadores e modelo para o Gemma-2.0-2b, usando os módulos
AutoTokenizer
e AutoModelForCausalLM
da biblioteca. O tokenizador converte texto em tokens que podem ser passados como entradas para serem processados pelo modelo.1 import torch 2 from transformers import AutoTokenizer, AutoModelForCausalLM 3 4 5 tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-2b-it") 6 model = AutoModelForCausalLM.from_pretrained("google/gemma-2-2b-it", torch_dtype=torch.bfloat16)
O trecho de código abaixo extrai a resposta do modelo Gemma 2 (2B).
1 def extract_model_response(response): 2 # Split the response at the start of the model's turn 3 parts = response.split("<start_of_turn>model") 4 # If there's a model response, it will be in the last part 5 if len(parts) > 1: 6 model_response = parts[-1].strip() 7 8 # Remove any potential end-of-turn markers 9 model_response = model_response.split("<end_of_turn>")[0].strip() 10 11 return model_response 12 else: 13 return "No model response found."
Depois de inicializar o modelo Gemma 2.0 (2B) e seu tokenizador associado, a próxima etapa é gerar uma resposta usando um formato de entrada no estilo de chat. Este tutorial aproveita a funcionalidade do modelo de chat do modelo para criar uma experiência de mais conversação. O método
apply_chat_template
do tokenizador de modelo Gemma é utilizado para formatar corretamente a entrada para o modelo ajustado por instruções.1 chat = [ 2 { "role": "user", "content": combined_information }, 3 ] 4 prompt = tokenizer.apply_chat_template(chat, tokenize=False, add_generation_prompt=True) 5 6 7 inputs = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt") 8 outputs = model.generate(input_ids=inputs.to(model.device), max_new_tokens=150, do_sample=True, temperature=0.7) 9 10 11 response = tokenizer.decode(outputs[0])
O trecho de código acima executa as seguintes operações:
- Criação de entrada no estilo de chat: Uma única mensagem de usuário contendo o
combined_information
é formatada como uma entrada no estilo de chat. - Aplicação do modelo de chat: O método
apply_chat_template
do tokenizador formata esta entrada de acordo com o modelo de chat específico da Gemma. Este processo inclui adicionar um prompt de geração para orientar a resposta do modelo. - Tokenização e codificação: a solicitação formatada é tokenizada e codificada, preparada para entrada no modelo.
- Geração de resposta: O modelo gera uma resposta utilizando parâmetros especificados, como
maximum_new_tokens
etemperature
. Esses parâmetros controlam o comprimento e aleatoriedade da saída. - Decodificação e extração: por fim, a saída gerada é decodificada e processada para extrair a resposta do modelo, deixando-a pronta para a extração de resposta e outros processos downstream.
1 model_output = extract_model_response(response) 2 print(model_output)
A avaliação de LLM, também chamada de avaliação de LLM, é o processo sistemático de formular um perfil de modelos de fundamento ou suas variantes ajustadas derivadas para entender e capturar seu desempenho em determinadas tarefas especializadas ou de uso geral, confiabilidade em determinadas condições, eficácia em casos de uso específicos e muitos outros critérios de métrica avaliativa que ajudam a obter uma visão geral da capacidade geral de um modelo.
A categoria específica de avaliação LLM realizada neste tutorial é Avaliação do sistema LLM, definida como a visão geral do desempenho de ponta a ponta de um sistema ou infraestrutura que incorpora um LLM; exemplos de tais sistemas são pipelines RAG e sistemas de agentes.
Embora o pipeline RAG tenha vários componentes, este tutorial avaliará apenas o componente de geração. O componente de geração envolve o uso das informações relevantes recuperadas do banco de dados para produzir uma resposta coerente e precisa à query do usuário. Especificamente, inclui:
- Integrando o contexto recuperado (
source_information
) com a query original (query
). - Solicitando o modelo de idioma com essas informações combinadas (
combined_information
). - Gerando uma resposta(
model_output
) que aborda a pergunta ou solicitação do usuário. - Garantir que o conteúdo gerado seja relevante, coerente e confiável às informações recuperadas. É o que estamos fazendo nesta seção.
Esse componente é crucial, pois determina a qualidade final da saída do sistema RAG, afetando diretamente a experiência do usuário e a eficácia geral do sistema. As métricas e fatores de avaliação para o componente de geração de um pipeline RAG são relevância, fidelidade, consistência e precisão.
A estrutura de avaliação LLM utilizada neste tutorial é o GeoEval. O GeoEval fornece as métricas de avaliação: relevância da resposta, fidelidade, impactação e outras, bem como a capacidade de definir métricas personalizadas. Este tutorial utilizará apenas duas métricas: relevância e fidelidade da resposta.
Fidelidade: a fidelidade quantidade a extensão em que as informações fáticas no texto gerado se alinham com os documentos recuperados ou o contexto fornecido. A fidelidade é medida na biblioteca OpenEval usando um LLM para extrair declarações feitas na resposta do modelo a uma query do usuário e o contexto fornecido e, em seguida, usando o mesmo LLM para determinar se as declarações extraídas da resposta do modelo são observadas no contexto recuperado . Portanto, a pontuação de fidelidade é determinada pelo número de declarações "backed " na resposta do modelo dividido pelo número total de declarações na resposta do modelo.
1 faithfulness = (Number of truthful claims) / (Total number of claims in response)
Para iniciar a etapa de avaliação, certifique-se de que a biblioteca deepeval Python esteja instalada em seu ambiente de desenvolvimento. Em seguida, importe os módulos
LLMTestCase
e FaithfulnessMetric
da biblioteca GeoEval.LLMTestCase
FaithfulnessMetric
1 from deepeval.test_case import LLMTestCase 2 from deepeval.metrics import FaithfulnessMetric
1 from deepeval.metrics import FaithfulnessMetric 2 3 4 actual_output = model_output 5 6 7 retrieval_context = [source_information] 8 9 10 metric = FaithfulnessMetric( 11 threshold=0.7, 12 model="gpt-4", 13 include_reason=True 14 ) 15 test_case = LLMTestCase( 16 input=query, 17 actual_output=actual_output, 18 retrieval_context=retrieval_context 19 ) 20 21 22 metric.measure(test_case) 23 print(metric.score) 24 print(metric.reason)
O trecho de código acima define as variáveis
actual_output
e retrieval_context
para armazenar a saída do modelo e as informações de origem para contexto. Um objetoFaithfulnessMetric
é instanciado com um limite de 0.7, correspondente ao limite de fidelidade, resultando em uma sinalização no resultado da avaliação para declarações que estejam abaixo do limite.O procedimento de avaliação usa "GPT-4" como modelo de avaliação e é configurado para incluir uma razão para sua avaliação, usando o LLM como uma abordagem de árbitro para avaliação. Um
LLMTestCase
é construído, englobando a query de entrada, a saída real do modelo e o contexto de recuperação. O trecho de código mostra a invocação do métodomeasure
da métrica, passando o caso de teste como um argumento. Finalmente, o trecho de código gera a pontuação de fidelidade calculada e a explicação que a acompanha para a avaliação.Abaixo está um exemplo da saída do processo de avaliação de fidelidade.
1 Event loop is already running. Applying nest_asyncio patch to allow async execution... 2 0.9333333333333333 3 The score is 0.93 because there is a minor discrepancy with the year of CDDY's strategic acquisitions. The actual output mistakenly indicates they occurred in 2023, while the context clearly states they happened in 2024.
A pontuação de fidelidade é 0.93, que pode ser interpretada como a resposta do Gemma 2B sendo 93% confiável ao contexto fornecido. A explicação anexa também fornece uma razão para a pontuação fornecida, uma resposta gerada pelo LLM usado para avaliação para fornecer uma explicação textual de seu resultado. Este componente da biblioteca deepeval introduz um recurso de explicação legível por humanos, que melhora a interpretabilidade dos resultados da avaliação. Ela fornece uma lógica lógica para a pontuação de fidelidade, destacando discrepâncias ou alinhamentos entre a saída do modelo e o contexto de origem.
Relevância da resposta: dimensiona quão bem a resposta gerada se alinha à query de entrada inicial. A relevância da resposta avalia a associação entre a resposta e a query sem avaliar a precisão fatura.
1 from deepeval.metrics import AnswerRelevancyMetric 2 3 4 actual_output = model_output 5 6 7 metric = AnswerRelevancyMetric( 8 threshold=0.7, 9 model="gpt-4", 10 include_reason=True 11 ) 12 13 14 test_case = LLMTestCase( 15 input=query, 16 actual_output=actual_output 17 ) 18 19 metric.measure(test_case) 20 print(metric.score) 21 print(metric.reason)
O resultado do processo avaliativo da relevância da resposta é o seguinte:
1 Event loop is already running. Applying nest_asyncio patch to allow async execution... 2 1.0 3 The score is 1.00 because the response accurately selected a company from the provided information and justified why it's a safe long-term investment, addressing all aspects of the input.
Nesta seção, você foi introduzido à avaliação LLM, com foco específico na avaliação do sistema LLM dentro do contexto de um pipeline RAG. Você implementou dois métodos de avaliação principais para o componente de geração de um pipeline de RAG: relevância da resposta e fidelidade, utilizando a poderosa biblioteca deepevals.
Ao aproveitar a biblioteca OpenEval, você pode especificar esses aspectos do desempenho do modelo e obter informações valiosas sobre seus pontos fortes e áreas a serem melhoradas. A capacidade da biblioteca de fornecer pontuações numéricas e explicações legíveis por humanos melhora a interpretabilidade dos resultados da avaliação.
Neste tutorial, você explorou a criação de um assistente de analista de gerenciamento de ativos usando o modelo aberto Gemma 2 (2B) do Google, um pipeline RAG com MongoDB e técnicas de avaliação LLM. Esta mostra demonstra o potencial dos modelos abertos na criação de soluções de AI eficientes e econômicas para casos de uso específicos.
A implementação do Gemma 2 (2B), um modelo leve de dois bilhões de parâmetros, destaca as capacidades crescentes dos modelos de código aberto em aplicativos e ambientes do mundo real com disponibilidade limitada de computação. Isso permite que os desenvolvedores criem soluções orientadas por IA que equilibrem o desempenho com a eficiência dos recursos.
A função de banco de dados operacional e vetorial do MongoDB destaca sua flexibilidade e escalabilidade em aplicativos e infraestrutura de AI modernos. Seus recursos vetoriais de pesquisa do Atlas e integração com o Python o tornam adequado para sistemas RAG , permitindo a recuperação eficiente de informações.
O foco na avaliação do LLM usando a biblioteca Geoeval enfatiza a importância de avaliar o desempenho do sistema de AI . Ao implementar métricas como fidelidade e relevância da resposta, você obteve insights sobre os pontos fortes do modelo e as áreas de melhoria.
No futuro, você poderá explorar mais abordagens de avaliação ou estratégias de agrupamento para otimizar o desempenho e a precisão dos pipelines RAG.
1. O que é o Gemma 2 e como ele difere de outros modelos de linguagem? Gemma 2 é uma família de modelos abertos leves e de última geração, desenvolvida pelo Google. Ele foi construído usando os mesmos blocos de construção que os modelos maiores do Gêmeos, mas foi projetado para ser mais eficiente e adequado para casos de uso que exigem recursos computacionais menores. A variante Gemma 2 (2B) tem dois bilhões de parâmetros e é particularmente útil para aplicativos que precisam de eficiência, economia de custos, privacidade e baixa latência.
2. Como o MongoDB contribui para o pipeline RAG?
O MongoDB serve como um banco de dados operacional e vetorial neste aplicativo RAG. Ele armazena, consulta e recupera com eficiência incorporações vetoriais. O tutorial demonstra como configurar um cluster MongoDB Atlas , criar um índice vetorial do Atlas Search e usar a aggregation pipeline do MongoDB para recursos semânticas do Atlas Search, que são cruciais para o componente de recuperação do sistema RAG .
3. O que é a avaliação LLM e quais métricas são usadas neste tutorial?
A avaliação do LLM, ou evals do LLM, é o processo sistemático de avaliar o desempenho dos modelos de linguagem em várias tarefas e casos de uso. Neste tutorial, o foco está na avaliação do sistema LLM, especificamente para um pipeline RAG. Duas métricas principais são usadas: fidelidade e relevância da resposta. A fidelidade mede quão bem a resposta gerada se alinha com o contexto fornecido, enquanto a relevância da resposta avalia quão bem a resposta aborda a query inicial.
4. Qual é o objetivo da biblioteca GeoEval neste tutorial?
A biblioteca OpenEval é usada para realizar avaliações de LLM. Ele fornece métricas como FidelidadeMetric e RespostaRelevancyMetric para avaliar a qualidade das respostas geradas. A biblioteca permite definir limites de avaliação e usar modelos como GPT-4. Ele inclui recursos para fornecer explicações legíveis por humanos dos resultados da avaliação, aprimorando a interpretabilidade do processo de avaliação.
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.