File size: 4,662 Bytes
06d3034
 
a3ed049
 
 
 
 
06d3034
 
 
408cf90
a3ed049
 
 
 
 
7371d1a
a3ed049
 
 
408cf90
a3ed049
 
 
 
 
 
 
 
 
408cf90
a3ed049
 
 
 
 
 
 
408cf90
a3ed049
 
 
 
 
 
 
06d3034
 
a3ed049
 
 
 
 
 
06d3034
7371d1a
06d3034
 
 
 
 
 
 
 
 
 
408cf90
a3ed049
 
 
06d3034
a3ed049
06d3034
 
408cf90
06d3034
408cf90
 
06d3034
 
 
 
 
a3ed049
06d3034
a3ed049
 
7371d1a
a3ed049
 
 
 
 
7371d1a
 
 
 
 
 
 
 
a3ed049
7371d1a
a3ed049
06d3034
 
408cf90
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
import gradio as gr
from huggingface_hub import InferenceClient
from typing import List, Tuple
import fitz  # PyMuPDF
from sentence_transformers import SentenceTransformer, util
import numpy as np
import faiss

client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")

# Placeholder for the app's state
class MyApp:
    def __init__(self) -> None:
        self.documents = []
        self.embeddings = None
        self.index = None
        self.load_pdf("ENGINEERING.pdf")
        self.build_vector_db()

    def load_pdf(self, file_path: str) -> None:
        """Extracts text from a PDF file and stores it in the app's documents."""
        doc = fitz.open(file_path)
        self.documents = []
        for page_num in range(len(doc)):
            page = doc[page_num]
            text = page.get_text()
            self.documents.append({"page": page_num + 1, "content": text})
        print("PDF processed successfully!")

    def build_vector_db(self) -> None:
        """Builds a vector database using the content of the PDF."""
        model = SentenceTransformer('all-MiniLM-L6-v2')
        self.embeddings = model.encode([doc["content"] for doc in self.documents])
        self.index = faiss.IndexFlatL2(self.embeddings.shape[1])
        self.index.add(np.array(self.embeddings))
        print("Vector database built successfully!")

    def search_documents(self, query: str, k: int = 3) -> List[str]:
        """Searches for relevant documents using vector similarity."""
        model = SentenceTransformer('all-MiniLM-L6-v2')
        query_embedding = model.encode([query])
        D, I = self.index.search(np.array(query_embedding), k)
        results = [self.documents[i]["content"] for i in I[0]]
        return results if results else ["No relevant documents found."]

app = MyApp()

def respond(
    message: str,
    history: List[Tuple[str, str]],
    system_message: str,
    max_tokens: int,
    temperature: float,
    top_p: float,
):
    system_message = "You are a knowledgeable and skilled electrical engineer. You provide clear, concise, and helpful information about electrical systems, circuits, and devices. You answer one question at a time, ensuring that your responses are easy to understand and informative. Remember to be respectful, patient, and thorough, considering that users may have varying levels of technical knowledge. You guide users through troubleshooting electrical issues, offer advice on electrical design and safety, and provide recommendations for common electrical problems. If a user mentions a potentially dangerous electrical situation, you advise them to turn off the power immediately and contact a professional electrician. Your goal is to help users understand and solve their electrical issues while promoting safety and best practices."
    messages = [{"role": "system", "content": system_message}]

    for val in history:
        if val[0]:
            messages.append({"role": "user", "content": val[0]})
        if val[1]:
            messages.append({"role": "assistant", "content": val[1]})

    messages.append({"role": "user", "content": message})

    # RAG - Retrieve relevant documents
    retrieved_docs = app.search_documents(message)
    context = "\n".join(retrieved_docs)
    messages.append({"role": "system", "content": "Relevant documents: " + context})

    response = ""
    for message in client.chat_completion(
        messages,
        max_tokens=100,
        stream=True,
        temperature=0.98,
        top_p=0.7,
    ):
        token = message.choices[0].delta.content
        response += token
        yield response

demo = gr.Blocks()

with demo:
    gr.Markdown(
        "‼️Disclaimer: This chatbot is based on a numerical modelling and design of machines book that is publicly available. and just to test RAG implementation.‼️"
    )
    
    chatbot = gr.ChatInterface(
        respond,
        examples=[
            ["How do I troubleshoot a circuit breaker that keeps tripping?"],
            ["Can you explain how to design a basic electrical circuit?"],
            ["What safety precautions should I take when working with electrical wiring?"],
            ["How can I calculate the voltage drop in a long electrical cable?"],
            ["Could you recommend energy-saving tips for home appliances?"],
            ["How does surge protection work, and why is it important?"],
            ["What are the current standards for electrical wiring in new construction?"],
            ["What are the key components of a residential electrical panel?"]
        ],
        title='Electrical Engineer'
    )

if __name__ == "__main__":
    demo.launch()