Geoeasy commited on
Commit
77f9f9d
·
verified ·
1 Parent(s): 6963f47

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +187 -187
app.py CHANGED
@@ -1,187 +1,187 @@
1
- import os
2
- import gradio as gr
3
- import numpy as np
4
- from sentence_transformers import SentenceTransformer
5
- import faiss
6
- from openai import OpenAI, OpenAIError
7
- from langchain_community.document_loaders import PyPDFLoader
8
- from langchain.text_splitter import RecursiveCharacterTextSplitter
9
-
10
- # Paths for files generated by build_index.py
11
- INDEX_FILE = "r_docs.index"
12
- CHUNKS_FILE = "r_chunks.npy"
13
-
14
- # Check index existence
15
- if not os.path.exists(INDEX_FILE) or not os.path.exists(CHUNKS_FILE):
16
- raise FileNotFoundError(
17
- "Index not found. Please run first:\n python build_index.py"
18
- )
19
-
20
- # Load FAISS index and chunks
21
- index = faiss.read_index(INDEX_FILE)
22
- chunks = np.load(CHUNKS_FILE, allow_pickle=True)
23
-
24
- # Embedding model for context retrieval
25
- embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
26
-
27
- def retrieve_context(query: str, k: int = 4) -> str:
28
- q_emb = embedding_model.encode([query], convert_to_numpy=True)
29
- _, I = index.search(q_emb, k)
30
- return "\n---\n".join(chunks[i] for i in I[0])
31
-
32
- # NVIDIA OpenAI-compatible client for chat
33
- NV_API_KEY = os.getenv(
34
- "NV_API_KEY",
35
- "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"
36
- )
37
- client = OpenAI(
38
- base_url="https://integrate.api.nvidia.com/v1",
39
- api_key=NV_API_KEY
40
- )
41
- CHAT_MODEL = "meta/llama3-8b-instruct"
42
-
43
- # Dialog history stored as list of (user, assistant) tuples
44
- dialog_history: list[tuple[str, str]] = []
45
-
46
- def chatbot(user_input, temperature, top_p, max_tokens):
47
- global dialog_history
48
- if not user_input:
49
- return dialog_history, ""
50
-
51
- # Retrieve context and build system message
52
- context = retrieve_context(user_input)
53
- system_msg = {
54
- "role": "system",
55
- "content": (
56
- "You are an assistant specialized in R packages. "
57
- "Use only the context below to answer. "
58
- "If you don't know, state that you don't know."
59
- f"\n\n=== Retrieved Context ===\n{context}\n\n"
60
- )
61
- }
62
-
63
- # Build message list for the API
64
- messages = [system_msg]
65
- for user_msg, assistant_msg in dialog_history:
66
- messages.append({"role": "user", "content": user_msg})
67
- messages.append({"role": "assistant", "content": assistant_msg})
68
- messages.append({"role": "user", "content": user_input})
69
-
70
- # Call NVIDIA streaming API
71
- assistant_reply = ""
72
- try:
73
- stream = client.chat.completions.create(
74
- model=CHAT_MODEL,
75
- messages=messages,
76
- temperature=temperature,
77
- top_p=top_p,
78
- max_tokens=max_tokens,
79
- stream=True
80
- )
81
- for chunk in stream:
82
- delta = chunk.choices[0].delta
83
- if hasattr(delta, "content") and delta.content:
84
- assistant_reply += delta.content
85
- except OpenAIError as e:
86
- assistant_reply = f"⚠️ API Error: {e.__class__.__name__}: {e}"
87
-
88
- dialog_history.append((user_input, assistant_reply))
89
- return dialog_history, ""
90
-
91
-
92
- def clear_history():
93
- global dialog_history
94
- dialog_history = []
95
- return [], ""
96
-
97
- # Custom CSS for modern, responsive layout
98
- custom_css = r"""
99
- :root {
100
- --primary: #4a90e2;
101
- --secondary: #50e3c2;
102
- --background-light: #f9f9f9;
103
- --background-dark: #1e1e1e;
104
- --text-light: #ffffff;
105
- --text-dark: #333333;
106
- --radius: 8px;
107
- --spacing: 1rem;
108
- }
109
-
110
- body {
111
- background-color: var(--background-light);
112
- color: var(--text-dark);
113
- font-family: 'Helvetica Neue', sans-serif;
114
- }
115
-
116
- #chat-window {
117
- height: 60vh;
118
- overflow-y: auto;
119
- padding: var(--spacing);
120
- border: 1px solid #dddddd;
121
- border-radius: var(--radius);
122
- background-color: #ffffff;
123
- }
124
-
125
- #input-area {
126
- margin-top: var(--spacing);
127
- }
128
-
129
- #user-input {
130
- flex: 1;
131
- padding: 0.5rem;
132
- border-radius: var(--radius) 0 0 var(--radius);
133
- border: 1px solid #cccccc;
134
- }
135
-
136
- #send-button {
137
- border-radius: 0 var(--radius) var(--radius) 0;
138
- }
139
-
140
- @media (prefers-color-scheme: dark) {
141
- body {
142
- background-color: var(--background-dark);
143
- color: var(--text-light);
144
- }
145
- #chat-window {
146
- background-color: #2a2a2a;
147
- border-color: #444444;
148
- }
149
- }
150
- """
151
-
152
- # Gradio interface
153
- title = "Search Curriculum Vitae"
154
- with gr.Blocks(title=title, css=custom_css, theme=gr.themes.Base()) as demo:
155
- gr.Markdown(f"## {title}")
156
- with gr.Row():
157
- # Main column: chat interface
158
- with gr.Column(scale=3):
159
- chatbot_ui = gr.Chatbot(label="Assistant")
160
- with gr.Row(elem_id="input-area"):
161
- txt = gr.Textbox(placeholder="Type your question...", lines=2, elem_id="user-input")
162
- btn = gr.Button("Send", elem_id="send-button")
163
- clr = gr.Button("Clear", elem_id="clear-button")
164
- # Sidebar column: advanced controls
165
- with gr.Column(scale=1):
166
- with gr.Accordion("Advanced Settings", open=False):
167
- temperature = gr.Slider(0, 1, value=0.6, label="Temperature")
168
- top_p = gr.Slider(0, 1, value=0.95, label="Top-p")
169
- max_tokens = gr.Slider(64, 2048, value=512, step=64, label="Max Tokens")
170
- # Explanation for advanced settings
171
- gr.Markdown(
172
- """
173
- **Temperature:** Adjusts the randomness of responses. Lower values make output more deterministic; higher values increase creativity.
174
-
175
- **Top-p (nucleus sampling):** Limits the next-token selection to the top p percentile of probability mass. Lower values make responses more focused.
176
-
177
- **Max Tokens:** Sets the maximum length of the assistant's reply.
178
- """
179
- )
180
-
181
- # Event bindings
182
- btn.click(chatbot, [txt, temperature, top_p, max_tokens], [chatbot_ui, txt])
183
- txt.submit(chatbot, [txt, temperature, top_p, max_tokens], [chatbot_ui, txt])
184
- clr.click(clear_history, [], [chatbot_ui, txt])
185
-
186
- if __name__ == "__main__":
187
- demo.launch(server_name="0.0.0.0", server_port=7861)
 
1
+ import os
2
+ import gradio as gr
3
+ import numpy as np
4
+ from sentence_transformers import SentenceTransformer
5
+ import faiss
6
+ from openai import OpenAI, OpenAIError
7
+ from langchain_community.document_loaders import PyPDFLoader
8
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
9
+
10
+ # Paths for files generated by build_index.py
11
+ INDEX_FILE = "r_docs.index"
12
+ CHUNKS_FILE = "r_chunks.npy"
13
+
14
+ # Check index existence
15
+ if not os.path.exists(INDEX_FILE) or not os.path.exists(CHUNKS_FILE):
16
+ raise FileNotFoundError(
17
+ "Index not found. Please run first:\n python build_index.py"
18
+ )
19
+
20
+ # Load FAISS index and chunks
21
+ index = faiss.read_index(INDEX_FILE)
22
+ chunks = np.load(CHUNKS_FILE, allow_pickle=True)
23
+
24
+ # Embedding model for context retrieval
25
+ embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
26
+
27
+ def retrieve_context(query: str, k: int = 4) -> str:
28
+ q_emb = embedding_model.encode([query], convert_to_numpy=True)
29
+ _, I = index.search(q_emb, k)
30
+ return "\n---\n".join(chunks[i] for i in I[0])
31
+
32
+ # NVIDIA OpenAI-compatible client for chat
33
+ NV_API_KEY = os.getenv(
34
+ "NV_API_KEY",
35
+ "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"
36
+ )
37
+ client = OpenAI(
38
+ base_url="https://integrate.api.nvidia.com/v1",
39
+ api_key=NV_API_KEY
40
+ )
41
+ CHAT_MODEL = "meta/llama3-8b-instruct"
42
+
43
+ # Dialog history stored as list of (user, assistant) tuples
44
+ dialog_history: list[tuple[str, str]] = []
45
+
46
+ def chatbot(user_input, temperature, top_p, max_tokens):
47
+ global dialog_history
48
+ if not user_input:
49
+ return dialog_history, ""
50
+
51
+ # Retrieve context and build system message
52
+ context = retrieve_context(user_input)
53
+ system_msg = {
54
+ "role": "system",
55
+ "content": (
56
+ "You are an assistant specialized in R packages. "
57
+ "Use only the context below to answer. "
58
+ "If you don't know, state that you don't know."
59
+ f"\n\n=== Retrieved Context ===\n{context}\n\n"
60
+ )
61
+ }
62
+
63
+ # Build message list for the API
64
+ messages = [system_msg]
65
+ for user_msg, assistant_msg in dialog_history:
66
+ messages.append({"role": "user", "content": user_msg})
67
+ messages.append({"role": "assistant", "content": assistant_msg})
68
+ messages.append({"role": "user", "content": user_input})
69
+
70
+ # Call NVIDIA streaming API
71
+ assistant_reply = ""
72
+ try:
73
+ stream = client.chat.completions.create(
74
+ model=CHAT_MODEL,
75
+ messages=messages,
76
+ temperature=temperature,
77
+ top_p=top_p,
78
+ max_tokens=max_tokens,
79
+ stream=True
80
+ )
81
+ for chunk in stream:
82
+ delta = chunk.choices[0].delta
83
+ if hasattr(delta, "content") and delta.content:
84
+ assistant_reply += delta.content
85
+ except OpenAIError as e:
86
+ assistant_reply = f"⚠️ API Error: {e.__class__.__name__}: {e}"
87
+
88
+ dialog_history.append((user_input, assistant_reply))
89
+ return dialog_history, ""
90
+
91
+
92
+ def clear_history():
93
+ global dialog_history
94
+ dialog_history = []
95
+ return [], ""
96
+
97
+ # Custom CSS for modern, responsive layout
98
+ custom_css = r"""
99
+ :root {
100
+ --primary: #4a90e2;
101
+ --secondary: #50e3c2;
102
+ --background-light: #f9f9f9;
103
+ --background-dark: #1e1e1e;
104
+ --text-light: #ffffff;
105
+ --text-dark: #333333;
106
+ --radius: 8px;
107
+ --spacing: 1rem;
108
+ }
109
+
110
+ body {
111
+ background-color: var(--background-light);
112
+ color: var(--text-dark);
113
+ font-family: 'Helvetica Neue', sans-serif;
114
+ }
115
+
116
+ #chat-window {
117
+ height: 60vh;
118
+ overflow-y: auto;
119
+ padding: var(--spacing);
120
+ border: 1px solid #dddddd;
121
+ border-radius: var(--radius);
122
+ background-color: #ffffff;
123
+ }
124
+
125
+ #input-area {
126
+ margin-top: var(--spacing);
127
+ }
128
+
129
+ #user-input {
130
+ flex: 1;
131
+ padding: 0.5rem;
132
+ border-radius: var(--radius) 0 0 var(--radius);
133
+ border: 1px solid #cccccc;
134
+ }
135
+
136
+ #send-button {
137
+ border-radius: 0 var(--radius) var(--radius) 0;
138
+ }
139
+
140
+ @media (prefers-color-scheme: dark) {
141
+ body {
142
+ background-color: var(--background-dark);
143
+ color: var(--text-light);
144
+ }
145
+ #chat-window {
146
+ background-color: #2a2a2a;
147
+ border-color: #444444;
148
+ }
149
+ }
150
+ """
151
+
152
+ # Gradio interface
153
+ title = "Search Curriculum Vitae"
154
+ with gr.Blocks(title=title, css=custom_css, theme=gr.themes.Base()) as demo:
155
+ gr.Markdown(f"## {title}")
156
+ with gr.Row():
157
+ # Main column: chat interface
158
+ with gr.Column(scale=3):
159
+ chatbot_ui = gr.Chatbot(label="Assistant")
160
+ with gr.Row(elem_id="input-area"):
161
+ txt = gr.Textbox(placeholder="Type your question...", lines=2, elem_id="user-input")
162
+ btn = gr.Button("Send", elem_id="send-button")
163
+ clr = gr.Button("Clear", elem_id="clear-button")
164
+ # Sidebar column: advanced controls
165
+ with gr.Column(scale=1):
166
+ with gr.Accordion("Advanced Settings", open=False):
167
+ temperature = gr.Slider(0, 1, value=0.6, label="Temperature")
168
+ top_p = gr.Slider(0, 1, value=0.95, label="Top-p")
169
+ max_tokens = gr.Slider(64, 2048, value=512, step=64, label="Max Tokens")
170
+ # Explanation for advanced settings
171
+ gr.Markdown(
172
+ """
173
+ **Temperature:** Adjusts the randomness of responses. Lower values make output more deterministic; higher values increase creativity.
174
+
175
+ **Top-p (nucleus sampling):** Limits the next-token selection to the top p percentile of probability mass. Lower values make responses more focused.
176
+
177
+ **Max Tokens:** Sets the maximum length of the assistant's reply.
178
+ """
179
+ )
180
+
181
+ # Event bindings
182
+ btn.click(chatbot, [txt, temperature, top_p, max_tokens], [chatbot_ui, txt])
183
+ txt.submit(chatbot, [txt, temperature, top_p, max_tokens], [chatbot_ui, txt])
184
+ clr.click(clear_history, [], [chatbot_ui, txt])
185
+
186
+ if __name__ == "__main__":
187
+ demo.launch(server_name="0.0.0.0", server_port=7860)