File size: 5,597 Bytes
5b67970
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import streamlit as st
import os
from dotenv import load_dotenv
from langchain import HuggingFaceHub
from langchain_community.embeddings import HuggingFaceBgeEmbeddings
from langchain_community.vectorstores.chroma import Chroma
from langchain.prompts import ChatPromptTemplate
load_dotenv()
import time

os.environ['HUGGINGFACEHUB_API_TOKEN'] = os.getenv("HUGGINGFACEHUB_API_TOKEN")

CHROMA_PATH = "chroma"

PROMPT_TEMPLATE = """Use the following pieces of context to answer the question at the end.

If you don't know the answer, just say that you don't know, don't try to make up an answer.

Use three sentences maximum and keep the answer as full sentence structure.

Always say "thanks for asking!" at the end of the answer.



### Content: 

{context}



### Question:

{question}



Helpful Answer:

"""

# App title
st.set_page_config(page_title="BLINKpedia Chatbot", page_icon='BLINKpedia.png')

# Replicate Credentials
with st.sidebar:
    st.image('BLINKpedia.png',)
    st.logo('BLINKpedia_open.png', icon_image='BLINKpedia_close.png')
    st.title('BLINKpedia Chatbot')
    st.subheader('Models and parameters')
    st.markdown('''

                This model is designed to generate text content related to BLACKPINK, a globally renowned K-pop girl group. It leverages state-of-the-art natural language processing techniques to produce coherent and contextually relevant text based on input prompts.

                ## Model Details

                - **Model Name**: [BLINKpedia](https://huggingface.co/la-min/BLINKpedia)

                - **Model Type**: Text Generation

                - **Training Data**: Curated datasets containing information about BLACKPINK, including lyrics, interviews, news articles, and fan content.

                - **Framework**: Hugging Face Transformers

                ## Contributors

                - [La Min Ko Ko](https://www.linkedin.com/in/la-min-ko-ko-907827205/)

                - [Kyu Kyu Swe](https://www.linkedin.com/in/kyu-kyu-swe-533718171/)

                ''')

# Store LLM generated responses
if "messages" not in st.session_state.keys():
    st.session_state.messages = [{"role": "assistant", "content": "How may I assist you today?"}]

# Display or clear chat messages
for message in st.session_state.messages:
    with st.chat_message(message["role"], avatar= "🤖" if message["role"] != "user" else "🧠"):
        st.write(message["content"])

def clear_chat_history():
    st.session_state.messages = [{"role": "assistant", "content": "How may I assist you today?"}]
st.sidebar.button('Clear Chat History', on_click=clear_chat_history)

def BgeEmbedding():
    model_name = "BAAI/bge-small-en"
    model_kwargs = {"device": "cpu"}
    encode_kwargs = {"normalize_embeddings": True}
    hf = HuggingFaceBgeEmbeddings(
        model_name=model_name, model_kwargs=model_kwargs, encode_kwargs=encode_kwargs,
    )
    return hf

def generate_format_prompt(input):
     # Prepare the DB.
    embedding_function = BgeEmbedding()
    db = Chroma(persist_directory=CHROMA_PATH, embedding_function=embedding_function)

    results = db.similarity_search_with_relevance_scores(input, k=4)

    if len(results) == 0 or results[0][1] < 0.7:
        print(f"Unable to find matching results.")
    
    context_text = "\n\n---\n\n".join([doc.page_content for doc, _score in results])
    prompt_template = ChatPromptTemplate.from_template(PROMPT_TEMPLATE)
    prompt = prompt_template.format(context=context_text, question=input)
    
    return prompt
    

def generate_llama2_response(prompt_input):
    format_prompt = generate_format_prompt(prompt_input)
    llm =  HuggingFaceHub(repo_id="unsloth/tinyllama-chat", model_kwargs={"temperature":0.2,})
    output = llm.invoke(format_prompt)

    return output

def response_generator(txt):
    for word in txt.split():
        yield word + " "
        time.sleep(0.05)
        
def dynamic_waiting_message(elapsed_time):
    if elapsed_time <= 5:
        return "Thinking..."
    elif elapsed_time <= 10:
        return "The result is almost here..."
    elif elapsed_time <= 15:
        return "It's really coming out now..."
    else:
        return "Just a little longer..."

st.markdown(
    """

<style>

    .st-emotion-cache-1c7y2kd {

        flex-direction: row-reverse;

        text-align: right;

        background-color: transparent;

    }

    .st-emotion-cache-1v0mbdj img{

        border-radius: 20px;

    }

    .st-emotion-cache-1mi2ry5{

        align-items: center;

    }

</style>

""",
    unsafe_allow_html=True,
)
    
    
    
# Main execution
def main():
    start_time = time.time()
    
    # User-provided prompt
    if prompt := st.chat_input():
        st.session_state.messages.append({"role": "user", "content": prompt})
        with st.chat_message("user", avatar="🧠"):
            st.write(prompt)

    # Generate a new response if last message is not from assistant
    if st.session_state.messages[-1]["role"] != "assistant":
        with st.chat_message("assistant", avatar="🤖"):
            with st.spinner(dynamic_waiting_message(time.time() - start_time)):
                response = generate_llama2_response(prompt)
                answer_response = response.split("Helpful Answer:")[1]
            st.write_stream(response_generator(answer_response))
        message = {"role": "assistant", "content": answer_response}
        st.session_state.messages.append(message)

if __name__ == "__main__":
    main()