File size: 5,138 Bytes
02a2d80 11503ab 2bb543a 11503ab 8a8d9dd 7f0ff91 11503ab 49c2234 11503ab 2bb543a 9e59998 11503ab 755689d 21bd98b 755689d 2bb543a 11503ab 2bb543a 11503ab 2bb543a 11503ab 2bb543a 11503ab 2bb543a 11503ab 2bb543a 11503ab 2bb543a 11503ab 2bb543a 597f25d 02a2d80 11503ab 80d2c6b 02a2d80 11503ab 02a2d80 11503ab 02a2d80 26608f4 11503ab 26608f4 2bb543a 11503ab 7fb2b42 11503ab 02a2d80 26608f4 33aae2c 11503ab 7fb2b42 26608f4 2bb543a 4ac5be0 |
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 |
import streamlit as st
import time
import os
import pickle
import numpy as np
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_together import TogetherEmbeddings
from langchain.chat_models import ChatOpenAI
from sklearn.metrics.pairwise import cosine_similarity
# ------------------ بارگذاری چانکها و امبدینگها ------------------
@st.cache_resource
def load_chunks_and_embeddings():
embeddings_file = 'embeddings.pkl'
if os.path.exists(embeddings_file):
st.success("✅ امبدینگها از فایل کش بارگذاری شد.")
with open(embeddings_file, 'rb') as f:
data = pickle.load(f)
return data['chunk_texts'], data['chunk_embeddings'], data['embeddings_model']
else:
with st.spinner('📄 در حال پردازش PDF و ساخت امبدینگها...'):
loader = PyPDFLoader('test1.pdf')
pages = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=0)
chunks = splitter.split_documents(pages)
embeddings_model = TogetherEmbeddings(
api_key="0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979"
)
chunk_texts = [chunk.page_content for chunk in chunks]
# ساخت امبدینگ با progress bar
progress = st.progress(0, text="در حال ساخت امبدینگ چانکها...")
chunk_embeddings = []
for i, text in enumerate(chunk_texts):
chunk_embeddings.append(embeddings_model.embed_query(text))
progress.progress((i + 1) / len(chunk_texts))
# ذخیره در فایل کش
with open(embeddings_file, 'wb') as f:
pickle.dump({
'chunk_texts': chunk_texts,
'chunk_embeddings': chunk_embeddings,
'embeddings_model': embeddings_model,
}, f)
st.success(f"✅ {len(chunk_texts)} چانک پردازش و ذخیره شد.")
return chunk_texts, chunk_embeddings, embeddings_model
chunk_texts, chunk_embeddings, embeddings_model = load_chunks_and_embeddings()
# ------------------ ساخت مدل LLM ------------------
llm = ChatOpenAI(
base_url="https://api.together.xyz/v1",
api_key='0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979',
model="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free"
)
# ------------------ پاسخ بر اساس ۱۰ چانک نزدیک ------------------
def answer_from_pdf(question):
# ۱- ساخت امبدینگ سوال
question_embedding = embeddings_model.embed_query(question)
# ۲- محاسبه شباهت
similarities = cosine_similarity(
[question_embedding],
chunk_embeddings
)[0]
# ۳- انتخاب ۱۰ چانک نزدیک
top_indices = np.argsort(similarities)[-10:][::-1]
selected_chunks = [chunk_texts[i] for i in top_indices]
# ۴- ساخت پرامپت
context = "\n\n".join(selected_chunks)
prompt = f"""با توجه به متن زیر فقط به زبان فارسی پاسخ بده:
متن:
{context}
سوال:
{question}
پاسخ:"""
response = llm.invoke(prompt)
return response.content
# ------------------ Chat Streamlit UI ------------------
st.title('📚 چت با PDF (با ۱۰ چانک نزدیک و کش شده)')
if 'messages' not in st.session_state:
st.session_state.messages = []
if 'pending_prompt' not in st.session_state:
st.session_state.pending_prompt = None
# نمایش هیستوری چت
for msg in st.session_state.messages:
with st.chat_message(msg['role']):
st.markdown(f"🗨️ {msg['content']}", unsafe_allow_html=True)
# گرفتن سوال از کاربر
prompt = st.chat_input("سوال خود را وارد کنید...")
if prompt:
st.session_state.messages.append({'role': 'user', 'content': prompt})
st.session_state.pending_prompt = prompt
st.rerun()
# وقتی سوال جدید داری
if st.session_state.pending_prompt:
with st.chat_message('ai'):
thinking = st.empty()
thinking.markdown("🤖 در حال پردازش...")
# پاسخ بر اساس نزدیکترین چانکها
response = answer_from_pdf(st.session_state.pending_prompt)
answer = response.strip()
if not answer:
answer = "متاسفم، اطلاعات دقیقی در این مورد ندارم."
thinking.empty()
full_response = ""
placeholder = st.empty()
# تدریجی نشون دادن پاسخ
for word in answer.split():
full_response += word + " "
placeholder.markdown(full_response + "▌")
time.sleep(0.03)
placeholder.markdown(full_response)
st.session_state.messages.append({'role': 'ai', 'content': full_response})
st.session_state.pending_prompt = None
|