HNU-Final / create_vector_store.py
Mokhtar
feat: upgrade to Gemini 2.5, add caching, and add developer credits
d243c37
Raw History Blame Contribute Delete
3.17 kB
# create_vector_store.py β€” Rebuild vector store from markdown data files
import os
import shutil
from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings
from dotenv import load_dotenv
# --- Project Settings ---
DATA_PATH = os.path.join(os.path.dirname(__file__), "university_data_arabic")
DB_PATH = os.path.join(os.path.dirname(__file__), "vectorstores", "db")
EMBEDDING_MODEL_NAME = "intfloat/multilingual-e5-small"
HF_CACHE_DIR = os.path.join(os.path.dirname(__file__), ".cache", "huggingface")
def build_vector_store():
"""
Builds the ChromaDB vector store from markdown files.
Workflow:
1. Loads all .md files from university_data_arabic/
2. Splits them into ~1000 char chunks with 200 char overlap
3. Embeds using intfloat/multilingual-e5-small (local model, cached on disk)
4. Persists the vector store to vectorstores/db/
The embedding model (~470MB) is downloaded only once and cached in .cache/
"""
load_dotenv()
if not os.path.exists(DATA_PATH):
print(f"❌ Data folder '{DATA_PATH}' not found.")
print(f" Create it and add your .md files there.")
return
# Clean old vector store to ensure fresh data
if os.path.exists(DB_PATH):
print(f"πŸ—‘οΈ Removing old vector store at {DB_PATH}")
shutil.rmtree(DB_PATH)
# 1. Load all .md files
print(f"πŸ“‚ Loading files from: {DATA_PATH}...")
loader = DirectoryLoader(
DATA_PATH,
glob="**/*.md",
loader_cls=TextLoader,
loader_kwargs={'encoding': 'utf-8'},
show_progress=True
)
documents = loader.load()
if not documents:
print("❌ No .md files found. Add markdown files to the data directory.")
return
print(f" Found {len(documents)} documents")
# 2. Split into chunks
print("βœ‚οΈ Splitting documents into chunks...")
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
chunked_documents = text_splitter.split_documents(documents)
print(f" Created {len(chunked_documents)} chunks")
# 3. Initialize embedding model
print(f"🧠 Loading embedding model: {EMBEDDING_MODEL_NAME}...")
embedding_model = HuggingFaceEmbeddings(
model_name=EMBEDDING_MODEL_NAME,
cache_folder=HF_CACHE_DIR,
model_kwargs={'device': 'cpu'},
encode_kwargs={'normalize_embeddings': True}
)
# 4. Build and persist ChromaDB
print(f"πŸ’Ύ Building vector store at: {DB_PATH}...")
vector_store = Chroma.from_documents(
documents=chunked_documents,
embedding=embedding_model,
persist_directory=DB_PATH
)
print("-" * 45)
print("βœ… Vector store built successfully!")
print(f" Documents: {len(documents)}")
print(f" Chunks: {len(chunked_documents)}")
print(f" Location: {DB_PATH}")
print("-" * 45)
if __name__ == "__main__":
build_vector_store()