File size: 2,702 Bytes
35bbb5d
 
 
6d58266
3754ac4
a738a52
35bbb5d
 
0a49502
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50393a6
 
0a49502
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3754ac4
50393a6
 
9fede0e
 
35bbb5d
3754ac4
0a49502
3754ac4
 
 
 
35bbb5d
 
 
 
 
 
 
 
 
 
3754ac4
 
 
35bbb5d
3754ac4
 
 
a738a52
fb59308
 
0a49502
fb59308
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
import torch
from sentence_transformers import SentenceTransformer

import gradio as gr
from huggingface_hub import InferenceClient

client = InferenceClient("Qwen/Qwen2.5-7B-Instruct")

with open("knowledgebase.txt", "r", encoding="utf-8") as file:
    knowledgebase_text = file.read()

def preprocess_text(text):

    cleaned_text = text.strip()

    chunks = cleaned_text.split("\n")

    # empty list where cleaned chunks will be stored
    cleaned_chunks = []

    # cleans chunks and adds to our list of cleaned chunks
    for chunk in chunks:
        strip_chunk = chunk.strip()
        if strip_chunk:
            cleaned_chunks.append(strip_chunk)

    return cleaned_chunks

cleaned_chunks = preprocess_text(knowledgebase_text)
    
model = SentenceTransformer('all-MiniLM-L6-v2')

# converts text chunks into vector embedding and stores as tensor for calculations
def create_embeddings(cleaned_chunks):
    
    chunk_embeddings = model.encode(cleaned_chunks, convert_to_tensor=True)

    return chunk_embeddings

chunk_embeddings = create_embeddings(cleaned_chunks)

def get_top_chunks (query, chunk_embeddings, cleaned_chunks):

    # converts query text into vector embedding
    query_embedding = model.encode(query, convert_to_tensor=True)

    query_embedding_normalized = query_embedding/query_embedding.norm()

    chunk_embeddings_normalized = chunk_embeddings/chunk_embeddings.norm(dim=1, keepdim=True)

    similarities = torch.matmul(chunk_embeddings_normalized, query_embedding_normalized)

    top_indices = torch.topk(similarities, k=3).indices

    top_chunks = []
    
    for i in top_indices:
        chunk = cleaned_chunks[i]
        top_chunks.append(chunk)

    return top_chunks

def respond(message, history):

    top_results = get_top_chunks(message, chunk_embeddings, cleaned_chunks)

    # allows LLM to interpret information better; without it would yield a Python list for the LLM to interpret which isn't as clean
    context = "\n".join(top_results)
    
    messages = [{"role": "system", "content": "You are a clairvoyant chatbot with vast knowledge on zodiac signs, but you also give the information very clearly so users can understand the message you're conveying."}]
    
    if history:
        messages.extend(history)
        
    messages.append({
    "role": "user",
    "content": f"""Context from the knowledge base:
{context}

User question:
{message}

Answer using the context above."""
})
    
    response = client.chat_completion(
        messages,
        max_tokens=300
    )
    
    return response.choices[0].message.content.strip()

with gr.Blocks(theme=gr.themes.Soft()) as demo:
    chatbot = gr.ChatInterface(respond)

demo.launch()