Spaces:
Sleeping
Sleeping
Mark Redito
commited on
Commit
·
c51c1e9
0
Parent(s):
Initial commit without large files
Browse files- .gitattributes +36 -0
- .gitignore +5 -0
- .vscode/settings.json +5 -0
- README.md +14 -0
- app.py +145 -0
- requirements.txt +19 -0
.gitattributes
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
csv/processed_markdown_data.csv filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.env
|
2 |
+
app_bak.py
|
3 |
+
app_safe.py
|
4 |
+
app_test.py
|
5 |
+
csv/processed_markdown_data.csv
|
.vscode/settings.json
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"python.pythonPath": "C:\\Users\\Mark\\.conda\\envs\\bookmarks\\python.exe",
|
3 |
+
"python.linting.pylintEnabled": true,
|
4 |
+
"python.linting.enabled": true
|
5 |
+
}
|
README.md
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
title: Bookmarkschat
|
3 |
+
emoji: 💬
|
4 |
+
colorFrom: yellow
|
5 |
+
colorTo: purple
|
6 |
+
sdk: gradio
|
7 |
+
sdk_version: 4.36.1
|
8 |
+
app_file: app.py
|
9 |
+
pinned: false
|
10 |
+
license: mit
|
11 |
+
short_description: A RAG enabled chatbot
|
12 |
+
---
|
13 |
+
|
14 |
+
An example chatbot using [Gradio](https://gradio.app), [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/v0.22.2/en/index), and the [Hugging Face Inference API](https://huggingface.co/docs/api-inference/index).
|
app.py
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import faiss
|
3 |
+
import numpy as np
|
4 |
+
import pandas as pd
|
5 |
+
from sentence_transformers import SentenceTransformer
|
6 |
+
from langchain_anthropic import ChatAnthropic
|
7 |
+
from langchain.retrievers.multi_query import MultiQueryRetriever
|
8 |
+
from langchain.chains import create_retrieval_chain
|
9 |
+
from langchain.chains.combine_documents import create_stuff_documents_chain
|
10 |
+
from langchain_core.prompts import ChatPromptTemplate
|
11 |
+
from langchain_community.vectorstores import FAISS
|
12 |
+
from langchain_community.docstore.in_memory import InMemoryDocstore
|
13 |
+
from langchain_core.documents import Document
|
14 |
+
from langchain_huggingface import HuggingFaceEmbeddings
|
15 |
+
from gradio import Markdown
|
16 |
+
import os
|
17 |
+
from dotenv import load_dotenv
|
18 |
+
|
19 |
+
# Paths
|
20 |
+
INDEX_PATH = "index/index_file.index"
|
21 |
+
CSV_PATH = "csv/processed_markdown_data.csv"
|
22 |
+
|
23 |
+
# Load FAISS index
|
24 |
+
index = faiss.read_index(INDEX_PATH)
|
25 |
+
|
26 |
+
# Load document store (CSV)
|
27 |
+
df = pd.read_csv(CSV_PATH)
|
28 |
+
all_segments = df['Segment'].tolist()
|
29 |
+
|
30 |
+
# Ensure the number of segments matches the number of vectors in the index
|
31 |
+
assert len(all_segments) == index.ntotal, "Mismatch between number of segments and vectors in the index"
|
32 |
+
|
33 |
+
# Set up HuggingFace embeddings
|
34 |
+
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
|
35 |
+
|
36 |
+
# Assuming you have the `documents` prepared like in your notebook
|
37 |
+
documents = [
|
38 |
+
Document(page_content=segment, metadata={"source": f"doc_{i}"})
|
39 |
+
for i, segment in enumerate(all_segments)]
|
40 |
+
|
41 |
+
docstore = InMemoryDocstore({f"doc_{i}": doc for i, doc in enumerate(documents)})
|
42 |
+
|
43 |
+
vector_store = FAISS(
|
44 |
+
embedding_function=embeddings,
|
45 |
+
index=index,
|
46 |
+
docstore=docstore,
|
47 |
+
index_to_docstore_id={i: f"doc_{i}" for i in range(index.ntotal)}
|
48 |
+
)
|
49 |
+
|
50 |
+
# Api key
|
51 |
+
load_dotenv()
|
52 |
+
api_key = os.getenv("ANTHROPIC_API_KEY")
|
53 |
+
|
54 |
+
# Anthropic API setup (Claude 3 Haiku)
|
55 |
+
llm = ChatAnthropic(
|
56 |
+
api_key=api_key,
|
57 |
+
model="claude-3-haiku-20240307",
|
58 |
+
temperature=0.2,
|
59 |
+
max_tokens_to_sample=1024,
|
60 |
+
)
|
61 |
+
|
62 |
+
# Multi-query retriever
|
63 |
+
multi_query_retriever = MultiQueryRetriever.from_llm(
|
64 |
+
retriever=vector_store.as_retriever(search_type="mmr", search_kwargs={"k": 6}),
|
65 |
+
llm=llm
|
66 |
+
)
|
67 |
+
|
68 |
+
# Prompt and retrieval chain setup
|
69 |
+
system_prompt = """You are an assistant with access to my notes. The notes are about different topics that are interesting to me.
|
70 |
+
Your task is to provide insights on the content I've saved in the past. You will be comprehensive and informative in your response.
|
71 |
+
Use the following pieces of retrieved context to answer the question.
|
72 |
+
If you don't know the answer, say that you don't know.
|
73 |
+
|
74 |
+
{context}"""
|
75 |
+
|
76 |
+
prompt = ChatPromptTemplate.from_messages([
|
77 |
+
("system", system_prompt),
|
78 |
+
("human", "{input}"),
|
79 |
+
])
|
80 |
+
|
81 |
+
question_answer_chain = create_stuff_documents_chain(llm, prompt)
|
82 |
+
rag_chain = create_retrieval_chain(multi_query_retriever, question_answer_chain)
|
83 |
+
|
84 |
+
# Gradio interface
|
85 |
+
info_text = """
|
86 |
+
# Welcome to My Bookmarks Chatbot
|
87 |
+
by [Mark Redito](https://markredito.com)
|
88 |
+
|
89 |
+
This chatbot has access to my browser bookmarks from 2020 to mid-2024. It covers a variety of topics I’m interested in, including Art, Technology, and Culture.
|
90 |
+
|
91 |
+
## You can use it in a few ways:
|
92 |
+
|
93 |
+
- Extract specific links. For example: "Give me the links about Ethereum"
|
94 |
+
- Get summaries of bookmarked content. Try: "Summarize 'How to do great work' by Paul Graham"
|
95 |
+
- Ask general questions on various topics. Like: "What goes into a typical music recording contract?"
|
96 |
+
|
97 |
+
## Here's a quick rundown of how it works behind the scenes:
|
98 |
+
|
99 |
+
- The system uses RAG (Retrieval-Augmented Generation) with a framework called Langchain. Basically, it helps the chatbot find and use relevant information.
|
100 |
+
- The bookmarks are stored in a database called FAISS that makes searching super fast.
|
101 |
+
- The brains of the operation is Claude 3 Haiku, a small and fast AI model by Anthropic.
|
102 |
+
- When you ask a question, the system comes up with a few more related questions to help find the right links. It then searches the database and passes the best information to Claude to craft your answer.
|
103 |
+
|
104 |
+
Keep in mind, if the chatbot can't find good information to answer your question, it'll let you know by saying something like "I don't know" or "I can't find it." And like any AI, it might make mistakes sometimes.
|
105 |
+
|
106 |
+
This is mostly a fun project I put together for my own curiosity and enjoyment. While I can't make any promises about its performance, I hope you have fun exploring and maybe discover something interesting! Enjoy!
|
107 |
+
"""
|
108 |
+
|
109 |
+
info_text_component = Markdown(info_text) # Load it once
|
110 |
+
|
111 |
+
# The respond function
|
112 |
+
|
113 |
+
def respond(message, history, max_tokens, temperature, top_p):
|
114 |
+
# Process user message through RAG chain
|
115 |
+
response = rag_chain.invoke({"input": message})# Extract the answer from the response
|
116 |
+
if isinstance(response, dict) and 'answer' in response:
|
117 |
+
answer = response['answer']
|
118 |
+
else:
|
119 |
+
answer = str(response) # Convert to string if it's not in the expected format
|
120 |
+
|
121 |
+
# Return the answer in the format expected by Gradio's chat interface
|
122 |
+
return answer
|
123 |
+
|
124 |
+
# Gradio Chat Interface
|
125 |
+
with gr.Blocks() as demo:
|
126 |
+
info_text_component
|
127 |
+
info_text_component.render() # Add static Markdown once
|
128 |
+
with gr.Accordion("Advanced Options", open=False):
|
129 |
+
max_tokens_slider = gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens")
|
130 |
+
temperature_slider = gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=1, label="Temperature")
|
131 |
+
top_p_slider = gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus sampling)")
|
132 |
+
chatbot = gr.ChatInterface(
|
133 |
+
respond,
|
134 |
+
chatbot=gr.Chatbot(height=600),
|
135 |
+
textbox=gr.Textbox(
|
136 |
+
placeholder="Type your message here (eg. How to do great work by Paul Graham?)", container=False, scale=7),
|
137 |
+
additional_inputs=[
|
138 |
+
max_tokens_slider,
|
139 |
+
temperature_slider,
|
140 |
+
top_p_slider
|
141 |
+
],
|
142 |
+
)
|
143 |
+
|
144 |
+
if __name__ == "__main__":
|
145 |
+
demo.launch()
|
requirements.txt
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
langchain==0.3.1
|
2 |
+
langchain-anthropic==0.2.1
|
3 |
+
langchain-community==0.3.1
|
4 |
+
langchain-core==0.3.6
|
5 |
+
anthropic==0.34.2
|
6 |
+
faiss-cpu
|
7 |
+
sentence-transformers==3.1.1
|
8 |
+
gradio
|
9 |
+
numpy==1.26.4
|
10 |
+
pandas==2.1.4
|
11 |
+
torch==2.4.1
|
12 |
+
transformers>=4.44.2,<4.45.0
|
13 |
+
pydantic==2.9.2
|
14 |
+
tqdm==4.66.5
|
15 |
+
python-dotenv==1.0.1
|
16 |
+
langchain-huggingface
|
17 |
+
multiprocess
|
18 |
+
xxhash
|
19 |
+
pyarrow
|