好,繼續玩垃圾,呢篇同上篇一樣,都係唔會完整既筆記。甚至符係,任務仲未完成,不過到左一個milestone,所以停一停,打篇野順便整理下思緒。所以內容無保証。
話說,上次搭左Ollama server 後,部機太廢,唯有用個部機行得到最勁的model ,試左llama3.2 3.2B 呢個,叫做速度可以接受。
為左爭取更多工作時間,搭返個Open WebUI 整返個AI Helpdesk取代自己先,將啲公司內部系統的開發同使用說明書PDF塞晒入去,有User打來問時就介紹佢自己用,效果唔太差,都為部份用戶解決到啲問題,起碼佢可以話到比User知去邊個位或者去搵野方向。
好,而家到正經野,有大堆文字要處理。呢個任務唔易搞,如果可以將佢地入晒VectorDB 然後去做Similarity Search再餵比LLM去答啲用戶提問,
本來想用pgvector來存放chunks,不過弄了一回,發現了有人做了個SQLite 的Plugin。這個小玩具應該好玩。
不過,你玩玩具時玩具玩你,原作者之前寫左個SQLite-vss 既Plugin,搞左大輪,爬左好多文。搞左啲,之後先睇到篇,原來原作者見vss有缺點,於是從新推倒重來,用Pure C 寫左個SQLite-vec 既Plug-in。
咁Langchain就將兩個都納入左佢Core既vectorstores ,唔用Langchain由至可,呢件又係伏野來。網上都有人講,佢其中一個缺點係,成日改動。無錯,如果搵啲例子或者Tutorial,vss係放左向langchain_community.vectorstores入面,其實都唔止SQLiteVec,其他HuggingFaceEmbeddings,甚至作為好核心common既Ollama 佢都成日搬位。
如果咁唔好彩抄功課抄中啲舊舊地(其實可能係24年上半年的Example),就會有以下信息彈出來:
LangChainDeprecationWarning: The class `HuggingFaceEmbeddings` was deprecated in LangChain 0.2.2 and will be removed in 1.0.
An updated version of the class exists in the :class:`~langchain-huggingface package and should be used instead.
To use it run `pip install -U :class:`~langchain-huggingface` and import as `from :class:`~langchain_huggingface import HuggingFaceEmbeddings``.
如果係
from langchain_community.llms import Ollama
就要改成:
from langchain_ollama import OllamaLLM
當然,你係要唔改都行到,只係會狂彈出warning。
好,咁整個Virtualenv 裝晒啲架餐先:
要裝既包括但不限於sqlite3, sqlite_vec, langchain_community, langchain_experimental
咁作為開始,先用返佢Loader將PDF 讀返來,
from langchain_community.document_loaders import PDFPlumberLoader
from langchain_experimental.text_splitter import SemanticChunker
from langchain_huggingface import HuggingFaceEmbeddings
pdf_path = '/....path.../xxxxx.pdf'
docs = loader.load()
print("Processing PDF: ", pdf_path)
print("Number of pages in the PDF:", len(docs))
下面呢段就將讀返來的PDF砌開:
text_splitter = SemanticChunker(HuggingFaceEmbeddings())
documents = text_splitter.split_documents(docs)
texts = [doc.page_content for doc in docs]
print("Number of chunks created: ", len(documents))
然後,我地要搵返個model 做embedding,當然,業界做得最好就OpenAI,但我地係要搞山寨,當然用免費野。又爬左一輪文,就用呢個All-miniLM-L6-v2。
embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
跟住要講既係,Langchain佢本身有個From_texts的func,用SQLite-vss係可以自動build晒所有野,但呢個Function向SQLite-vec係無implement,仲要因為Document Object 個ID 問題,搞到要睇左好多Langchain base.py 同vec的Source code。
搞左大輪,其實都唔知點搞,跟返佢source要乜就比乜佢,首先開返個 SQLite connection。跟住要用enable_load_extension去load vec 個Plugin。
con = sqlite3.connect(db_path)
con.enable_load_extension(True)
sqlite_vec.load(con)
搞掂左之後init SQLiteVec:
vector_store = SQLiteVec(table="state_union", connection = False, embedding=embedding_function, db_file=db_path)
呢舊野的method可以呢度查到:
上面切左的doc source就放左入一個List texts 果度,直接比佢就得:
a = vector_store.add_texts(texts)
行完之後會有個 xxx.db file建立左向你指定的地方,用DBbrowser 開可以見到有六個Tables,有個叫state_union table就係PDF 內文,佢有個 text_embedding 的col name 打開係一大堆HEX,就係embedding。
咁Similarity search同RAG 比個LLM 就留返後面講。