|
|
from langchain.text_splitter import CharacterTextSplitter |
|
|
from langchain.vectorstores import FAISS |
|
|
from langchain.document_loaders import PyPDFLoader |
|
|
from langchain.embeddings import HuggingFaceEmbeddings |
|
|
import chainlit as cl |
|
|
import tempfile |
|
|
from huggingface_hub import AsyncInferenceClient |
|
|
|
|
|
|
|
|
API_TOKEN = "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" |
|
|
headers = {"Authorization": f"Bearer {API_TOKEN}","Content-Type": "application/json"} |
|
|
API_URL = "https://kfsb1xfskc2136wg.eu-west-1.aws.endpoints.huggingface.cloud" |
|
|
|
|
|
client = AsyncInferenceClient(model=API_URL,token=API_TOKEN) |
|
|
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2",model_kwargs = {'device': 'cpu'}) |
|
|
|
|
|
@cl.on_chat_start |
|
|
async def main(): |
|
|
|
|
|
|
|
|
|
|
|
files = None |
|
|
while files == None: |
|
|
files = await cl.AskFileMessage( |
|
|
content="Please upload a text file to begin!",max_size_mb=25, accept=["application/pdf"] |
|
|
).send() |
|
|
file = files[0] |
|
|
msg = cl.Message(content=f"Processing `{file.name}`...") |
|
|
cl.user_session.set("name", file.name) |
|
|
await msg.send() |
|
|
with tempfile.NamedTemporaryFile() as binary_file: |
|
|
binary_file.write(file.content) |
|
|
|
|
|
loader = PyPDFLoader(binary_file.name) |
|
|
text = loader.load() |
|
|
|
|
|
|
|
|
text_splitter = CharacterTextSplitter(separator="\n",chunk_size=1000, chunk_overlap=100) |
|
|
texts = text_splitter.split_documents(text) |
|
|
print(len(texts)) |
|
|
|
|
|
metadatas = [{"source": f"{i}"} for i in range(len(texts))] |
|
|
|
|
|
|
|
|
|
|
|
docsearch = FAISS.from_texts([t.page_content for t in texts], embeddings, metadatas=metadatas) |
|
|
retriever=docsearch.as_retriever(search_kwargs={"k": 4}) |
|
|
cl.user_session.set("metadatas", metadatas) |
|
|
cl.user_session.set("texts", texts) |
|
|
cl.user_session.set("retriever", retriever) |
|
|
await msg.update(content=f"`{file.name}` processed. You can now ask questions!") |
|
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
@cl.on_message |
|
|
async def main(message: str): |
|
|
|
|
|
docs = cl.user_session.get("retriever").get_relevant_documents(message) |
|
|
inp='\n'.join([x.page_content for x in docs]) |
|
|
|
|
|
|
|
|
templateger = f"<|prompter|>Verwenden Sie die folgenden Kontextinformationen, um die Frage am Ende zu beantworten. Seien Sie prägnant und antworten Sie in einem Satz. Wenn Sie die Frage mit den gegebenen Informationen nicht beantworten können, sagen Sie einfach 'Ich weiß es nicht', versuchen Sie nicht, eine Antwort zu erfinden.\n\n{inp}\n\nFrage: {message}\n<|endoftext|><|assistant|>" |
|
|
template = f"<|prompter|>Use the following pieces of context to answer the question at the end. Be concise and anwser in 1 sentence. If you can't anwser with the given information from the context just say that you don't know, don't try to make up an answer.\n\n{inp}\n\nQuestion: {message}\n<|endoftext|><|assistant|>" |
|
|
|
|
|
|
|
|
source_elements = [] |
|
|
found_sources = [] |
|
|
for source in docs: |
|
|
source_name = f"Part {source.metadata['source']} of {cl.user_session.get('name')}" |
|
|
text = source.page_content |
|
|
found_sources.append(source_name) |
|
|
source_elements.append(cl.Text(content=text, name=source_name)) |
|
|
msg = cl.Message(content="", elements=source_elements) |
|
|
generated_text = "" |
|
|
async for token in await client.text_generation(template, stream=True,max_new_tokens =250): |
|
|
if token!="<|endoftext|>": |
|
|
print(token, end="") |
|
|
generated_text += token |
|
|
await msg.stream_token(token) |
|
|
|
|
|
|
|
|
|
|
|
if found_sources: |
|
|
await msg.stream_token(f"\nSources: {', '.join(found_sources)}") |
|
|
else: |
|
|
await msg.stream_token("\nNo sources found") |
|
|
|
|
|
await msg.send() |