ask_agent
ask_agent
如果你想詢問較複雜的問題,使用ask_agent,語言模型會將你的問題拆解來提供較好的回答。
example
1 | ak = akasha.Doc_QA( |
1 | LPWAN和5G的主要區別在於他們的頻寬、延遲、成本和應用場景。 |
如果你想詢問較複雜的問題,使用ask_agent,語言模型會將你的問題拆解來提供較好的回答。
1 | ak = akasha.Doc_QA( |
1 | LPWAN和5G的主要區別在於他們的頻寬、延遲、成本和應用場景。 |
如果您不想自己創建問題集來評估當前參數的性能,您可以使用 eval.auto_create_questionset 功能自動生成一個包含參考答案的問題集。隨後,您可以使用 eval.auto_evaluation 獲取評估指標,如 Bert_score、Rouge 和 LLM_score(對於問答問題集),以及單選問題集的正確率。這些分數範圍從 0 到 1,較高的值表示生成的回答與參考答案更接近。
如範例,以下創建了一個名為 ‘mic_essay.txt’ 的問題集文本文件,其中包含十個問題和參考答案。每個問題都是從 ‘doc/mic/‘ 目錄中給定文檔的內容段落中隨機生成的。然後,您可以使用該問題集文本文件來評估要測試的參數的性能。
1 | import akasha.eval as eval |
1 | bert_score: 0.782 |
question_type 参数提供了四種問題類型:fact、summary、irrelevant、compared,預設是 fact。
1 | import akasha.eval as eval |
如果你想生成特定主題的問題,你可以使用 create_topic_questionset 函數,它會使用輸入的主題在文檔中找到相關的文件段落並生成問題集。
1 | import akasha.eval as eval |
若要測試各種參數對語言模型回答的好壞,可以使用auto_evalution函數。首先,您需要基於您要使用的文檔構建一個問題集(.txt)。
您可以生成單選題文件或問答題文件。
1 | 應回收廢塑膠容器材質種類不包含哪種? 1.聚丙烯(PP) 2.聚苯乙烯(PS) 3.聚氯乙烯(PVC) 4.低密度聚乙烯(LDPE) 4 |
1 | import akasha.eval as eval |
1 | 問題:根據文件中的訊息,智慧製造的複雜性已超越系統整合商的負荷程度,未來產業鏈中的角色將傾向朝共和共榮共創智慧製造商機,而非過往的單打獨鬥模式發展。請問為什麼 供 應商、電信商、軟體開發商、平台商、雲端服務供應商、系統整合商等角色會傾向朝共和共榮共創智慧製造商機的方向發展? |
1 | import akasha.eval as eval |
對於問答題文件,因為無法準確判別語言模型的回答是否正確,我們使用bert_score, rouge_score, llm_score,藉由比較語言模型的回答與問答題文件中的參考答案,來得出0~1之間的分數
使用bert-score套件計算回答與參考答案的每個token之間的contextual embeddings similarity.
1 | import akasha |
將語言模型的回答與問答題文件中的參考答案進行分詞後,藉由ROUGE 評估生成相似度分數
1 | import akasha |
利用另一種語言模型,將語言模型的回答與問答題文件中的參考答案進行比較,生成相似度分數
1 | import akasha |
若要測試所有可用的組合並找到最佳參數,您可以使用 optimum_combination 函數。您可以提供不同的嵌入模型、文件段落大小、語言模型、文件搜索方法以及最相關文檔的數量(topK),該函數將測試所有組合以找到根據給定的問題集和文檔的最佳組合。請注意,最佳得分組合是最高正確率組合,而最佳性價比組合是需要最少token以獲得正確答案的組合。
1 | import akasha.eval as eval |
1 | Best correct rate: 1.000 |
若要創建文本文件的摘要(.pdf、.txt.、docx),您可以使用 summary.summarize_file 函數。如範例,以下使用 map_reduce 摘要方法指示語言模型生成大約 500 字的摘要。有兩種摘要類型,map_reduce 和 refine,map_reduce 將對每個文本段落進行摘要,然後使用所有摘要的文本段落生成最終摘要;refine 將逐個摘要每個文本段落,並使用前一個摘要作為摘要下一段的提示,以獲得更高水平的摘要一致性。
1 | import akasha |
1 |
|
使用參數model便可以選擇不同的語言模型,預設是openai:gpt-3.5-turbo.
(請先完成設定 API Key)
1 | import akasha |
1 | import akasha |
安裝llama-cpp-python可以使用cpu推論.gguf格式的模型,或是安裝akasha時選擇llama-cpp
1 | pip install llama-cpp-python |
llama-cpp允許使用quantized模型並執行在cpu上,你可以從huggingface上下載.gguf llama-cpp 模型,如範例,如果你的模型下載到”model/“路徑下,可以使用以下方法加載模型
1 | import akasha |
llama-cpp同樣允許使用gpu運算模型,但安裝套件時需要使用cmake安裝,並確認已安裝g++, gcc和nvidia driver & toolkit,詳細請見llama-cpp-python
1 | CMAKE_ARGS="-DGGML_CUDA=on" FORCE_CMAKE=1 python -m pip install --upgrade --force-reinstall llama-cpp-python>=0.3.1 --no-cache-dir |
如果你使用別人的api或者透過支援openAI api框架的部署自己的模型(例如vllm, TGI, litellm…),你可以使用 remote:{your LLM api url} 來加載模型,若須指定模型名稱,使用 remote:{your LLM api url}@{your model name} 。
若遠端api需要api金鑰,請先完成設定環境變數 REMOTE_API_KEY ,參考設定 API Key
1 | import akasha |
(請先完成設定 API Key)
1 | import akasha |
(請先完成設定 API Key)
1 | import akasha |
1 | openai_model = "openai:gpt-3.5-turbo" # need environment variable "OPENAI_API_KEY" |
如果你想使用其他模型,可以建立一個輸入是prompt的函數並回傳語言模型的回答,並將此函數作為model參數
我們建立一個test_model函數,並可以將它作為參數輸入進get_response回答問題
1 | import akasha |
以上使用model參數選擇模型後,便會在Doc_QA物件內建立模型的物件model_obj(LLM)
1 | import akasha |
也可以使用輔助函數建立LLM物件
1 | import akasha |
此LLM物件也可直接傳入Doc_QA,避免重複宣告
1 | import akasha |
使用_llm_type()可取得語言模型的類別
1 | import akasha |
若要使用語言模型進行推論,可以使用函式call_model
1 | import akasha |
若要呼叫語言模型即時回答,可以使用函式call_stream_model
1 | import akasha |
如果你有大量不需要連貫的推理需求,可以使用akasha.helper.call_batch_model 來進行批量推理來提升速度。
1 | def call_batch_model(model: LLM, prompt: List[str], |
1 | import akasha |
使用參數embeddings便可以選擇不同的嵌入模型,預設是openai:text-embedding-ada-002.
(請先完成設定 API Key)
1 | import akasha |
1 | import akasha |
(請先完成設定 API Key)
1 | import akasha |
每個嵌入模型都有max sequence length,超過的話後面的文字就會被截斷,不會拿進去做嵌入。
1 | openai_emb = "openai:text-embedding-ada-002" # need environment variable "OPENAI_API_KEY" # 8192 max seq length |
如果你想使用其他模型,可以建立一個輸入是texts:list的函數,代表的是文件庫中所有分割好的文字段落,此函數需回傳embedding之後每段文字的向量,並將此函數作為embeddings參數
我們建立一個test_embed函數,並可以將它作為參數輸入進get_response回答問題
1 | import akasha |
以上使用embeddings參數選擇模型後,便會在Doc_QA物件內建立模型的物件embeddings_obj(Embeddings)
1 | import akasha |
也可以使用輔助函數建立Embeddings物件
1 | import akasha |
此Embeddings物件也可直接傳入Doc_QA,避免重複宣告
1 |
|
創建完Embeddings物件後,可以直接使用來得到文件片段的向量資料(list[list[float]])
1 |
|
當你想從大量文檔db中取出特定的文件db,以縮小搜尋範圍時,可以使用 extract_db_by_file (by file source name) 或 extract_db_by_keyword (by id)
1 | import akasha |
根據使用的語言模型不同,使用不同的格式來下指令可以得到更好的結果,akasha目前提供 gpt, llama, chat_gpt, chat_mistral, chat_gemini, auto 等格式
若選擇 auto會根據模型類別來決定提示格式
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 | import akasha |
1 | import akasha |
使用search_type參數可選擇不同的文件搜尋方法去找出與問題相關的文件段落,可使用svm, mmr, tfidf, knn。另可使用merge,為前三者的合併。
支持向量機(svm) 使用輸入提示和文件向量來訓練svm模型,訓練後,svm可用於基於其與訓練數據的相似性對新向量進行評分。
Max Marginal Relevance(mmr) 通過余弦相似度選擇相似的文件,但它也考慮多樣性,因此它還會懲罰與已選擇文件的接近。
詞頻-逆文檔頻率(tfidf) 是信息檢索和文本挖掘中常用的權重技術。TF-IDF是一種統計方法,用於評估詞語在一個文檔集合或語料庫中相對於該集合中的一個特定文檔的重要性。
K-最近鄰居(KNN) 是一種機器學習算法,用於分類和回歸問題。對於新數據點,它計算其與已知數據點的距離,然後基於最近的 k 個鄰居來預測類別或數值。在分類中,以多數票決定類別,而在回歸中則計算鄰居的平均值。
***Okapi BM25(bm25)***(BM 是最佳匹配的縮寫)是一種基於查詢詞出現在每個文檔中的檢索功能,而不考慮它們在文檔中的相鄰關系的排名一組文檔的方法。它是一系列具有略有不同組件和參數的評分函數。
rerank 使用bge-reranker模型對文檔進行相似度排序,速度較慢。 (rerank/rerank:bge-reranker-large)
auto/ audo_rerank 是另一種可以選擇的文件搜尋策略,使用 bm25 來搜尋相同詞語的文件,並用 svm 搜尋近似詞意的文件,若為 audo_rerank 且兩者皆沒有找到,則使用rerank模型去遍歷文件,但會相當緩慢。
如果你希望設計自己的方法找尋最相似的文檔,可以建立search_type函數,並將此函數作為search_type參數
此函數輸入包含:
如範例,我們使用歐幾里得距離度量來識別最相關的文檔。它返回一個表示距離小於指定閾值的查詢和文檔嵌入之間的前 k 個文檔的索引列表。
1 | import akasha |
在akasha中,文件搜尋的結果會以list of Document的形式回傳,Docuement為一個儲存文件內容(page_content)和後設資料(metadata)的物件,可以以此進行宣告和取用。
1 | from langchain.schema import Document |
若您想自行進行文件搜尋,在akasha中,文件搜尋是以以下流程進行:
1 | import akasha |
若您只想使用單一的搜尋方法(如 mmr, svm, knn, tfidf, bm25),且不想限制文件的總token數量,可以使用 get_relevant_documents_and_scores取得文件排序結果(list of Documents)與相似度的分數(list of float)
1 | import akasha |
若您不想限制文件的總token數量,可以使用 retri_docs取得文件排序結果(list of Documents)
可根據參數 topK指定回傳的文件片段數量上限
1 | import akasha |
在akasha中,chromadb建立完之後,會被儲存成dbs物件,會儲存chromadb中的文件內容、metadata、向量資料、unique id,並被使用於後續的vector similarity search。
該物件可以添加多個chromadb資料,也可與其他dbs物件互相結合,也可根據filter抽取出需要的向量資料。
processMultiDB可對多個文件集(list of directory)建立chromadb,並回傳dbs物件與建立不成功的檔案list,若文件內容、使用嵌入模型、chunk size相等的chromadb已存在,則不會重新創建而直接讀取。
文件內容改變也會建立新的chromadb,設定參數ignore_check=True則不進行文件內容更改與否的確認,可更快的進行chromadb的讀取。
1 | import akasha |
使用多個文字檔案創建chromadb可使用 createDB_file,使用資料夾創建chromadb則使用 createDB_directory
創建完的dbs物件(db_files, db_directory)可以直接輸入進 get_response中,減少重複讀取。
1 | import akasha |
在建立向量資料時,若您不想根據整個文件片段進行embedding,可以使用 akasha.db.create_keyword_chromadb,可自訂義函式來輸出想進行embedding的關鍵字,如以下範例
我們定義了一個函式 generate_llm_keyword 請語言模型根據文件段落產生3~5個關鍵字並回傳。
當我們使用 akasha.db.create_keyword_chromadb,建立向量資料(chromadb),每個文件片段便會根據自訂義函式 generate_llm_keyword的輸出來進行embedding
1 | import akasha |
若不使用自訂義函式,預設的函式 akasha.generate_keyword需安裝keybert套件
1 | pip install keybert |
您可以直接宣告akasha.dbs()建立空的dbs物件,也可以利用已建立的chromadb建立dbs物件。
dbs物件包含ids(每個文字段落的unique id), embeds(每個文字段落的向量), metadatas(每個文字段落的後設資料), docs(每個文字段落的內容) 。
1 | import akasha |
dbs物件之間可以使用.merge相互結合
1 | import akasha |
dbs物件可以添加新的chromadb資料
1 | import akasha |
使用get_Docuemnts可以得到當前dbs物件中儲存的Documents list (包含page_contents文件內容和metadata後設資料)
1 | import akasha |
extract_db_by_file可以將檔名符合file_name_list中的所有資料提取出來生成新的dbs物件
1 | import akasha |
extract_db_by_keyword可以將文字段落中存在任何keyword_list中keyword的所有資料提取出來生成新的dbs物件
1 | import akasha |
extract_db_by_ids可以將存在id_list中的的所有資料提取出來生成新的dbs物件
1 | import akasha |
pop_db_by_ids會將所選id_list中的的所有資料從dbs物件中移除
1 | import akasha |
若不需要向量資料,只需要Documents(page_content, metadata),可使用get_docs_from_doc從文件資料夾中讀取文件內容並切割成chunk_size文件段落,此函式會回傳docs(list of Documents)和不成功的檔案名稱list。
1 | import akasha |
根據文件資料夾、嵌入模型、chunk size輸出所有文件段落的後設資料list,用於自查詢
將更新完的metadata list存回chromadb,用於自查詢
1 |
|