File size: 3,963 Bytes
02a2d80 11503ab 8a8d9dd b0a7f96 11503ab 49c2234 11503ab c14d65f 11503ab c14d65f 33aae2c 11503ab 9e59998 11503ab 755689d 21bd98b 755689d 11503ab 597f25d 02a2d80 11503ab 80d2c6b 02a2d80 11503ab 02a2d80 11503ab 02a2d80 26608f4 11503ab 26608f4 11503ab 7fb2b42 11503ab 02a2d80 26608f4 33aae2c 11503ab 7fb2b42 26608f4 |
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 |
import streamlit as st
import time
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():
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]
chunk_embeddings = embeddings_model.embed_documents(chunk_texts)
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
)
# ۳- نزدیکترین چانک
best_idx = np.argmax(similarities)
best_chunk = chunk_texts[best_idx]
# ۴- ساخت پرامپت
prompt = f"""بر اساس متن زیر فقط به زبان فارسی پاسخ بده:
متن:
{best_chunk}
سوال:
{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
|