|
import os |
|
import uuid |
|
import json |
|
import chromadb |
|
|
|
import gradio as gr |
|
|
|
from dotenv import load_dotenv |
|
from openai import OpenAI |
|
|
|
from langchain_community.embeddings.sentence_transformer import SentenceTransformerEmbeddings |
|
|
|
from langchain_community.vectorstores import Chroma |
|
|
|
from huggingface_hub import CommitScheduler |
|
from pathlib import Path |
|
|
|
embedding_model = SentenceTransformerEmbeddings(model_name='thenlper/gte-small') |
|
|
|
load_dotenv() |
|
|
|
tesla_10k_collection = 'tesla-10k-2019-to-2023' |
|
|
|
anyscale_api_key = os.environ['ANYSCALE_API_KEY'] |
|
|
|
client = OpenAI( |
|
base_url="https://api.endpoints.anyscale.com/v1", |
|
api_key=anyscale_api_key |
|
) |
|
|
|
qna_model = 'meta-llama/Meta-Llama-3-8B-Instruct' |
|
|
|
chromadb_client = chromadb.PersistentClient(path='./tesla_db') |
|
|
|
vectorstore_persisted = Chroma( |
|
client=chromadb_client, |
|
collection_name=tesla_10k_collection, |
|
embedding_function=embedding_model |
|
) |
|
|
|
retriever = vectorstore_persisted.as_retriever( |
|
search_type='similarity', |
|
search_kwargs={'k': 5} |
|
) |
|
|
|
|
|
|
|
log_file = Path("logs/") / f"data_{uuid.uuid4()}.json" |
|
log_folder = log_file.parent |
|
|
|
scheduler = CommitScheduler( |
|
repo_id="document-qna-chroma-anyscale-logs", |
|
repo_type="dataset", |
|
folder_path=log_folder, |
|
path_in_repo="data", |
|
every=2 |
|
) |
|
|
|
qna_system_message = """ |
|
You are an assistant to a financial services firm who answers user queries on annual reports. |
|
Users will ask questions delimited by triple backticks, that is, ```. |
|
User input will have the context required by you to answer user questions. |
|
This context will begin with the token: ###Context. |
|
The context contains references to specific portions of a document relevant to the user query. |
|
Please answer only using the context provided in the input. However, do not mention anything about the context in your answer. |
|
If the answer is not found in the context, respond "I don't know". |
|
""" |
|
|
|
qna_user_message_template = """ |
|
###Context |
|
Here are some documents that are relevant to the question. |
|
{context} |
|
``` |
|
{question} |
|
``` |
|
""" |
|
|
|
def predict(input: str, history): |
|
|
|
""" |
|
Predict the response of the chatbot and complete a running list of chat history. |
|
""" |
|
|
|
relevant_document_chunks = retriever.invoke(input) |
|
context_list = [d.page_content for d in relevant_document_chunks] |
|
context_for_query = "\n".join(context_list) |
|
|
|
user_message = [{ |
|
'role': 'user', |
|
'content': qna_user_message_template.format( |
|
context=context_for_query, |
|
question=input |
|
) |
|
}] |
|
|
|
prompt = [{'role':'system', 'content': qna_system_message}] |
|
|
|
for entry in history: |
|
prompt += ( |
|
[{'role': 'user', 'content': entry[0]}] + |
|
[{'role': 'assistant', 'content': entry[1]}] |
|
) |
|
|
|
final_prompt = prompt + user_message |
|
|
|
try: |
|
|
|
response = client.chat.completions.create( |
|
model=qna_model, |
|
messages=final_prompt, |
|
temperature=0 |
|
) |
|
|
|
prediction = response.choices[0].message.content.strip() |
|
except Exception as e: |
|
prediction = f"Sorry, I cannot answer your question at this point. {e}" |
|
|
|
|
|
|
|
|
|
|
|
with scheduler.lock: |
|
with log_file.open("a") as f: |
|
f.write(json.dumps( |
|
{ |
|
'user_input': input, |
|
'retrieved_context': context_for_query, |
|
'model_response': prediction |
|
} |
|
)) |
|
f.write("\n") |
|
|
|
return prediction |
|
|
|
demo = gr.ChatInterface( |
|
fn=predict, |
|
title="AMA on Tesla 10-K statements", |
|
description="This web API presents an interface to ask questions on contents of the Tesla 10-K reports for the period 2019 - 2023.", |
|
examples=[["What was the total revenue of the company in 2022?"], |
|
["Summarize the Management Discussion and Analysis section of the 2021 report in 50 words."], |
|
["What was the company's debt level in 2020?"], |
|
["Identify 5 key risks identified in the 2019 10k report?"], |
|
["What is the view of the management on the future of electric vehicle batteries?"] |
|
], |
|
cache_examples=False, |
|
theme=gr.themes.Base(), |
|
concurrency_limit=8, |
|
show_progress="full" |
|
) |
|
|
|
demo.launch(auth=("demouser", os.getenv('PASSWD'))) |