maxcembalest commited on
Commit
c66a864
·
1 Parent(s): 5ed51c5

Upload 2 files

Browse files
arthur_vectorstore.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f48e27fbb868a6f6e54599797183284470462c53a47d5c5efdddcee7378bda8f
3
+ size 6836487
launch_ask_arthur_gradio.py ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import gradio as gr
3
+ import os
4
+ import pandas as pd
5
+ import pickle
6
+ from typing import List
7
+
8
+ from langchain.llms import OpenAIChat
9
+ from langchain.prompts import PromptTemplate
10
+ from langchain.chains.question_answering import load_qa_chain
11
+ from langchain.chains import LLMChain, ChatVectorDBChain
12
+ from langchain.callbacks.base import CallbackManager
13
+ from langchain.chains.chat_vector_db.prompts import CONDENSE_QUESTION_PROMPT as SYNTHESIS_PROMPT
14
+
15
+
16
+ response_prompt_template = """You are an AI assistant for the machine learning monitoring startup Arthur. You are
17
+ given the following extracted parts of a long document and a question. If the question
18
+ includes a request for code, provide a code block directly from the documentation. If you don't know the answer, just
19
+ say "Hmm, I'm not sure." Don't try to make up an answer. If the question is not about Arthur, politely inform them that
20
+ you are tuned to only answer questions about Arthur.
21
+
22
+ =========
23
+ Example 1:
24
+
25
+ Question: What data do I need to send to Arthur?
26
+ =========
27
+ **3. What if my data is proprietary? Can I still use Arthur?**
28
+
29
+ Yes! Arthur offers on-premises installation for customers with data security requirements. By integrating Arthur
30
+ into your business's on-premises stack, you can be confident that all security requirements are met while still
31
+ getting the benefits of the computation and analytics Arthur provides.
32
+ ***
33
+
34
+ **4. What if I don’t have ground truth labels for my data? Or what if I will have the ground truth labels in the future,
35
+ but they are not available yet?**
36
+
37
+ You don't need ground truth labels to log your model's inferences with Arthur.
38
+
39
+ If your ground truth labels become available after your model's inferences, whether seconds later or years later,
40
+ Arthur can link these new ground truth values to your model's past predictions, linking the new values by ID to
41
+ their corresponding inferences already in the Arthur system.
42
+
43
+ In the meantime, Arthur’s data drift metrics can offer leading indicators of model underperformance to keep you
44
+ covered if your ground truth labels are delayed or never become available.
45
+ ***
46
+ =========
47
+ Answer in Markdown:
48
+ The data you need to get into Arthur is only the inference data - no ground truth is needed, since it can be uploaded
49
+ at a later time. Also, if you have proprietary data, you can install Arthur on-premises to keep your own data security protocols.
50
+
51
+ =========
52
+ Now the real question:
53
+ Question: {question}
54
+ =========
55
+ {context}
56
+ =========
57
+ Answer in Markdown:"""
58
+ RESPONSE_PROMPT = PromptTemplate(
59
+ template=response_prompt_template, input_variables=["context", "question"]
60
+ )
61
+
62
+
63
+ # load vectorstore of embeddings
64
+ with open("files/vectorstores/arthur_vectorstore.pkl", "rb") as f:
65
+ global arthur_vectorstore
66
+ arthur_vectorstore = pickle.load(f)
67
+
68
+
69
+ def get_langchain_agent(api_key):
70
+ os.environ["OPENAI_API_KEY"] = api_key
71
+
72
+ manager = CallbackManager([])
73
+ question_manager = CallbackManager([])
74
+ stream_manager = CallbackManager([])
75
+
76
+ question_gen_llm = OpenAIChat(
77
+ temperature=0,
78
+ verbose=True,
79
+ callback_manager=question_manager,
80
+ )
81
+ streaming_llm = OpenAIChat(
82
+ streaming=True,
83
+ callback_manager=stream_manager,
84
+ verbose=True,
85
+ temperature=0,
86
+ )
87
+
88
+ question_generator = LLMChain(
89
+ llm=question_gen_llm, prompt=SYNTHESIS_PROMPT, callback_manager=manager
90
+ )
91
+ chat_response_generator = load_qa_chain(
92
+ streaming_llm, chain_type="stuff", prompt=RESPONSE_PROMPT, callback_manager=manager
93
+ )
94
+
95
+ agent = ChatVectorDBChain(
96
+ vectorstore=arthur_vectorstore,
97
+ combine_docs_chain=chat_response_generator,
98
+ question_generator=question_generator,
99
+ callback_manager=manager,
100
+ return_source_documents=True)
101
+
102
+ os.environ["OPENAI_API_KEY"] = ""
103
+ return agent
104
+
105
+
106
+ def get_source_doc(output):
107
+ sources = output["source_documents"]
108
+ assert len(sources) > 0
109
+ source_document = sources[0]
110
+ html_filename = source_document.metadata['source']
111
+ source_doc_link = html_filename.replace('files/', '')
112
+ source_doc_file = html_filename.replace('files/docs.arthur.ai/', '').replace('.html', '')
113
+ with open(f"files/arthur-docs-markdown/{source_doc_file}.md.txt", 'r') as f:
114
+ source_text = f.read()
115
+ return source_text, source_doc_link
116
+
117
+
118
+ def log_inference(chat_history: List[List[str]], llm_feedback: int) -> None:
119
+ reference_data = pd.read_csv("files/reference_data.csv", index_col=None)
120
+ chat_text = []
121
+ for user_text, bot_text in chat_history:
122
+ bot_text = bot_text.replace("\n", "").replace("<br>", "")
123
+ chat_text.append(f"input:<{user_text}>,output:<{bot_text}>,")
124
+ reference_data.loc[len(reference_data)] = {"chat": "".join(chat_text), "llm_feedback": llm_feedback}
125
+ reference_data.to_csv("files/reference_data.csv", index=False)
126
+
127
+
128
+ def chat(inp, history, agent):
129
+ history = history or []
130
+ result = agent({"question": inp, "chat_history": history})
131
+ chat_result = result["answer"]
132
+ source_doc, source_link = get_source_doc(result)
133
+ response = ""
134
+ for word in chat_result.split(" "):
135
+ response += word + " "
136
+ yield history + [(inp, response)], history + [(inp, response)], source_doc, source_link
137
+
138
+
139
+ def launch_ask_arthur(share=False):
140
+ with gr.Blocks() as demo:
141
+ with gr.Row():
142
+ gr.Markdown("<h1><center>Ask Arthur</center></h1><br><h7><center>"
143
+ "This is an experimental document-retrieval question-answering system. When you enter a message"
144
+ " into the chat, 1. we fetch a relevant page from the Arthur documentation (shown on the left) "
145
+ "and 2. we prompt the Arthur LLM (shown on the right) to answer your question using the page. "
146
+ "The LLM's answers are entirely unverified, but it can sometimes offer a helpful summary of a "
147
+ "lot of information, or integrate information from multiple sources for you.</center></h7>")
148
+ with gr.Column():
149
+ openai_api_key_textbox = gr.Textbox(
150
+ placeholder="Paste your OpenAI API key (sk-...)",
151
+ show_label=False,
152
+ lines=1,
153
+ type="password",
154
+ )
155
+ submit_api_key_button = gr.Button(value="Register API Key", variant="secondary").style(full_width=False)
156
+ with gr.Row().style():
157
+ with gr.Column():
158
+ chatbot = gr.Chatbot(
159
+ label="AskArthur chat history")
160
+ message = gr.Textbox(
161
+ label="In the AskArthur chat, you can ask follow up questions or ask for clarifications!"
162
+ "\nReload the demo to change the topic of conversation and refresh the language model.",
163
+ placeholder="Enter your question here...",
164
+ lines=1,
165
+ )
166
+ submit_message = gr.Button(value="Send", variant="secondary").style(full_width=False)
167
+ gr.Examples(label="Frequently asked questions about Arthur",
168
+ examples=[
169
+ "What default drift metrics does Arthur for deployed models?",
170
+ "How do I integrate Arthur with my existing ML stack?",
171
+ "How does Arthur monitor models without ground truth?",
172
+ "Can you explain the following error message: ",
173
+ ],
174
+ inputs=message,
175
+ )
176
+ # feedback radio button
177
+ llm_feedback = gr.Radio(
178
+ ["0","1","2"], value="0", label="How useful was this? (0 = bad, 1 = meh, 2 = good)"
179
+ )
180
+ submit_feedback_button = gr.Button("Submit feedback")
181
+ with gr.Column():
182
+ source_link = gr.Markdown()
183
+ source_page = gr.Markdown()
184
+
185
+ state = gr.State()
186
+ agent_state = gr.State()
187
+ submit_api_key_button.click(
188
+ get_langchain_agent,
189
+ inputs=[openai_api_key_textbox],
190
+ outputs=[agent_state],
191
+ )
192
+ submit_message.click(chat, inputs=[message, state, agent_state], outputs=[chatbot, state, source_page, source_link])
193
+ message.submit(chat, inputs=[message, state, agent_state], outputs=[chatbot, state, source_page, source_link])
194
+
195
+
196
+ submit_feedback_button.click(
197
+ log_inference,
198
+ [chatbot, llm_feedback],
199
+ )
200
+
201
+ demo.queue().launch(share=share)
202
+
203
+
204
+ if __name__ == "__main__":
205
+ parser = argparse.ArgumentParser()
206
+ parser.add_argument("--share", type=bool, required=False)
207
+ args = parser.parse_args()
208
+ launch_ask_arthur(share=args.share)