Spaces:
Runtime error
Runtime error
File size: 7,712 Bytes
3ec9224 5be8df6 5db4902 5be8df6 5db4902 5be8df6 a0d7f95 80f4c28 a0d7f95 1ef8d7c aa98840 9bf736d 5be8df6 1bfd20b 336c110 1bfd20b a0d7f95 b1ec9ac 5be8df6 1bfd20b 5be8df6 1bfd20b 80f4c28 1bfd20b 5be8df6 a0d7f95 1bfd20b 5be8df6 1bfd20b 5be8df6 1bfd20b 5be8df6 1bfd20b a0d7f95 1bfd20b ca17588 00bd139 5be8df6 a0d7f95 9bf736d 1bfd20b 9bf736d 1bfd20b 9bf736d ca17588 9bf736d 1bfd20b ca17588 1bfd20b 5be8df6 00bd139 1bfd20b 5be8df6 1bfd20b 00bd139 1bfd20b 5be8df6 1bfd20b 9733941 1bfd20b 80f4c28 1bfd20b 80f4c28 1bfd20b 80f4c28 1bfd20b 5be8df6 302b740 1bfd20b 302b740 1bfd20b 302b740 1bfd20b 302b740 1bfd20b 80f4c28 302b740 80f4c28 1bfd20b 302b740 17c064a 1bfd20b 17c064a 1bfd20b 302b740 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
import gradio as gr
import os
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain.chains import ConversationalRetrievalChain
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.llms import HuggingFaceEndpoint
from langchain.memory import ConversationBufferMemory
from pathlib import Path
import chromadb
from unidecode import unidecode
import re
# Modelos LLM disponíveis
list_llm = [
"mistralai/Mistral-7B-Instruct-v0.2", "mistralai/Mixtral-8x7B-Instruct-v0.1", "mistralai/Mistral-7B-Instruct-v0.1",
"google/gemma-7b-it", "google/gemma-2b-it", "HuggingFaceH4/zephyr-7b-beta", "HuggingFaceH4/zephyr-7b-gemma-v0.1",
"meta-llama/Llama-2-7b-chat-hf", "microsoft/phi-2", "TinyLlama/TinyLlama-1.1B-Chat-v1.0", "mosaicml/mpt-7b-instruct",
"tiiuae/falcon-7b-instruct", "google/flan-t5-xxl"
]
list_llm_simple = [os.path.basename(llm) for llm in list_llm]
# Função de carregamento e divisão de documentos
def load_and_split_documents(list_file_path, chunk_size, chunk_overlap):
loaders = [PyPDFLoader(x) for x in list_file_path]
pages = []
for loader in loaders:
pages.extend(loader.load())
text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
return text_splitter.split_documents(pages)
# Função para criar banco de dados vetorial com ChromaDB
def create_vector_db(splits, collection_name):
embedding = HuggingFaceEmbeddings()
new_client = chromadb.PersistentClient(path="./chroma_db")
return Chroma.from_documents(documents=splits, embedding=embedding, client=new_client, collection_name=collection_name)
# Função para inicializar a cadeia de QA
def initialize_llmchain(llm_model, temperature, max_tokens, top_k, vector_db, progress=gr.Progress()):
progress(0.1, desc="Inicializando tokenizer e Hub...")
llm = HuggingFaceEndpoint(
repo_id=llm_model, temperature=temperature, max_new_tokens=max_tokens, top_k=top_k, load_in_8bit=True
)
progress(0.5, desc="Definindo memória de buffer e cadeia de recuperação...")
memory = ConversationBufferMemory(memory_key="chat_history", output_key='answer', return_messages=True)
retriever = vector_db.as_retriever()
qa_chain = ConversationalRetrievalChain.from_llm(llm, retriever=retriever, chain_type="stuff", memory=memory, return_source_documents=True)
progress(0.9, desc="Concluído!")
return qa_chain
# Função para gerar um nome de coleção válido
def create_collection_name(filepath):
collection_name = Path(filepath).stem
collection_name = unidecode(collection_name.replace(" ", "-"))
return re.sub('[^A-Za-z0-9]+', '-', collection_name)[:50]
# Função para inicializar o banco de dados e o modelo LLM
def initialize_database_and_llm(list_file_obj, chunk_size, chunk_overlap, llm_option, llm_temperature, max_tokens, top_k, progress=gr.Progress()):
list_file_path = [x.name for x in list_file_obj if x is not None]
progress(0.1, desc="Criando nome da coleção...")
collection_name = create_collection_name(list_file_path[0])
progress(0.25, desc="Carregando e dividindo documentos...")
doc_splits = load_and_split_documents(list_file_path, chunk_size, chunk_overlap)
progress(0.5, desc="Gerando banco de dados vetorial...")
vector_db = create_vector_db(doc_splits, collection_name)
progress(0.75, desc="Inicializando modelo LLM...")
llm_name = list_llm[llm_option]
qa_chain = initialize_llmchain(llm_name, llm_temperature, max_tokens, top_k, vector_db, progress)
progress(0.9, desc="Concluído!")
return vector_db, collection_name, qa_chain
# Função de interação com o chatbot
def conversation(qa_chain, message, history):
formatted_chat_history = [f"Usuário: {user_message}\nAssistente: {bot_message}" for user_message, bot_message in history]
response = qa_chain({"question": message, "chat_history": formatted_chat_history})
response_answer = response["answer"].split("Resposta útil:")[-1]
response_sources = [doc.page_content.strip() for doc in response["source_documents"]]
response_pages = [doc.metadata["page"] + 1 for doc in response["source_documents"]]
new_history = history + [(message, response_answer)]
return qa_chain, gr.update(value=""), new_history, *response_sources, *response_pages
# Função de carregamento de arquivos
def upload_file(file_obj):
return [file_obj.name for file_obj in file_obj if file_obj is not None]
# Interface Gradio
def demo():
with gr.Blocks(theme="base") as demo:
vector_db, qa_chain, collection_name = gr.State(), gr.State(), gr.State()
gr.Markdown("<center><h2>Chatbot baseado em PDF</center></h2><h3>Faça qualquer pergunta sobre seus documentos PDF</h3>")
with gr.Tab("Etapa 1 - Carregar PDF"):
document = gr.Files(height=100, file_count="multiple", file_types=["pdf"])
with gr.Tab("Etapa 2 - Processar documento"):
db_btn = gr.Button("Gerar banco de dados vetorial")
slider_chunk_size = gr.Slider(minimum=100, maximum=1000, value=600, step=20, label="Tamanho do bloco")
slider_chunk_overlap = gr.Slider(minimum=10, maximum=200, value=40, step=10, label="Sobreposição do bloco")
db_progress = gr.Textbox(label="Inicialização do banco de dados vetorial")
with gr.Tab("Etapa 3 - Inicializar cadeia de QA"):
llm_btn = gr.Radio(list_llm_simple, label="Modelos LLM")
slider_temperature = gr.Slider(minimum=0.01, maximum=1.0, value=0.7, step=0.1, label="Temperatura")
slider_maxtokens = gr.Slider(minimum=224, maximum=4096, value=1024, step=32, label="Máximo de Tokens")
slider_topk = gr.Slider(minimum=1, maximum=10, value=3, step=1, label="Amostras top-k")
llm_progress = gr.Textbox(value="Nenhum", label="Inicialização da cadeia QA")
qachain_btn = gr.Button("Inicializar cadeia de Pergunta e Resposta")
with gr.Tab("Etapa 4 - Chatbot"):
chatbot = gr.Chatbot(height=300)
doc_source1, doc_source2, doc_source3 = gr.Textbox(label="Referência 1"), gr.Textbox(label="Referência 2"), gr.Textbox(label="Referência 3")
source1_page, source2_page, source3_page = gr.Number(label="Página 1"), gr.Number(label="Página 2"), gr.Number(label="Página 3")
# Campo de texto para enviar mensagens
user_input = gr.Textbox(label="Sua mensagem")
# Implementação de lógica de interação de conversa
def send_message(message, history, qa_chain):
formatted_chat_history = [f"Usuário: {user_message}\nAssistente: {bot_message}" for user_message, bot_message in history]
response = qa_chain({"question": message, "chat_history": formatted_chat_history})
response_answer = response["answer"].split("Resposta útil:")[-1]
response_sources = [doc.page_content.strip() for doc in response["source_documents"]]
response_pages = [doc.metadata["page"] + 1 for doc in response["source_documents"]]
new_history = history + [(message, response_answer)]
return qa_chain, gr.update(value=""), new_history, *response_sources, *response_pages
user_input.submit(send_message, inputs=[user_input, chatbot.history, qa_chain], outputs=[qa_chain, gr.update(value=""), chatbot.history, doc_source1, source1_page, doc_source2, source2_page, doc_source3, source3_page])
demo.launch()
|