一拷沸、大模型開發(fā)整理流程
1.1延届、什么是大模型開發(fā)
我們將開發(fā)以大語言模型為功能核心椭符、通過大語言模型的強(qiáng)大理解能力和生成能力荔燎、結(jié)合特殊的數(shù)據(jù)或業(yè)務(wù)邏輯來提供獨(dú)特功能的應(yīng)用稱為大模型開發(fā)。
開發(fā)大模型相關(guān)應(yīng)用销钝,其技術(shù)核心點(diǎn)雖然在大語言模型上有咨,但一般通過調(diào)用 API 或開源模型來實(shí)現(xiàn)核心的理解與生成,通過 Prompt Enginnering 來實(shí)現(xiàn)大語言模型的控制蒸健,因此座享,雖然大模型是深度學(xué)習(xí)領(lǐng)域的集大成之作,大模型開發(fā)卻更多是一個(gè)工程問題似忧。
在大模型開發(fā)中渣叛,我們一般不會去大幅度改動模型,而是將大模型作為一個(gè)調(diào)用工具橡娄,通過 Prompt Engineering诗箍、數(shù)據(jù)工程、業(yè)務(wù)邏輯分解等手段來充分發(fā)揮大模型能力挽唉,適配應(yīng)用任務(wù)滤祖,而不會將精力聚焦在優(yōu)化模型本身上。
大模型開發(fā)與傳統(tǒng)的AI 開發(fā)在整體思路上有著較大的不同瓶籽。
- 傳統(tǒng)AI 開發(fā):首先需要將復(fù)雜的業(yè)務(wù)邏輯依次拆解匠童,對于每個(gè)子業(yè)務(wù)構(gòu)造訓(xùn)練數(shù)據(jù)與驗(yàn)證數(shù)據(jù),對于每個(gè)子業(yè)務(wù)訓(xùn)練優(yōu)化模型塑顺,最后形成完整的模型鏈路來解決整個(gè)業(yè)務(wù)邏輯汤求。
- 大模型開發(fā):用 Prompt Engineering 來替代子模型的訓(xùn)練調(diào)優(yōu),通過 Prompt 鏈路組合來實(shí)現(xiàn)業(yè)務(wù)邏輯严拒,用一個(gè)通用大模型 + 若干業(yè)務(wù) Prompt 來解決任務(wù)扬绪,從而將傳統(tǒng)的模型訓(xùn)練調(diào)優(yōu)轉(zhuǎn)變成了更簡單、輕松裤唠、低成本的 Prompt 設(shè)計(jì)調(diào)優(yōu)挤牛。
大模型開發(fā)與傳統(tǒng) AI 開發(fā)在評估思路上也有了質(zhì)的差異。
- 傳統(tǒng) AI 開發(fā):構(gòu)造訓(xùn)練集种蘸、測試集墓赴、驗(yàn)證集,通過在訓(xùn)練集上訓(xùn)練模型航瞭、在測試集上調(diào)優(yōu)模型诫硕、在驗(yàn)證集上最終驗(yàn)證模型效果來實(shí)現(xiàn)性能的評估。
- 大模型開發(fā):更敏捷刊侯、靈活章办,不會在初期顯式地確定訓(xùn)練集、驗(yàn)證集滨彻,而是直接從實(shí)際業(yè)務(wù)需求出發(fā)構(gòu)造小批量驗(yàn)證集藕届,設(shè)計(jì)合理 Prompt 來滿足驗(yàn)證集效果。然后疮绷,不斷從業(yè)務(wù)邏輯中收集當(dāng)下 Prompt 的 Bad Case翰舌,并將 Bad Case 加入到驗(yàn)證集中,針對性優(yōu)化 Prompt冬骚,最后實(shí)現(xiàn)較好的泛化效果椅贱。
1.2、大模型開發(fā)整體流程
1.2.1只冻、設(shè)計(jì)
包括確定目標(biāo)庇麦,設(shè)計(jì)功能。
確定目標(biāo):在進(jìn)行開發(fā)前喜德,需要確定開發(fā)的目標(biāo)山橄,即要開發(fā)的應(yīng)用的應(yīng)用場景、目標(biāo)人群舍悯、核心價(jià)值航棱。一般應(yīng)先設(shè)定最小化目標(biāo)睡雇,從構(gòu)建一個(gè) mvp(最小可行性產(chǎn)品)開始,逐步進(jìn)行完善和優(yōu)化饮醇。
設(shè)計(jì)功能:確定開發(fā)目標(biāo)后它抱,設(shè)計(jì)本應(yīng)用所要提供的功能,首先確定應(yīng)用的核心功能朴艰,然后延展設(shè)計(jì)核心功能的上下游功能观蓄;例如,想打造一款個(gè)人知識庫助手祠墅,核心功能就是結(jié)合個(gè)人知識庫內(nèi)容進(jìn)行問題的回答侮穿,上游功能——用戶上傳知識庫、下游功能——用戶手動糾正模型回答毁嗦,就是子功能亲茅。
1.2.2、架構(gòu)搭建
搭建整體架構(gòu):搭建項(xiàng)目的整體架構(gòu)金矛,實(shí)現(xiàn)從用戶輸入到應(yīng)用輸出的全流程貫通芯急。包括搭建整體架構(gòu)和搭建數(shù)據(jù)庫。
目前驶俊,絕大部分大模型應(yīng)用都是采用的特定數(shù)據(jù)庫+ Prompt + 通用大模型的架構(gòu)娶耍。
推薦基于 LangChain 框架進(jìn)行開發(fā)。LangChain 提供了 Chain饼酿、Tool 等架構(gòu)的實(shí)現(xiàn)榕酒,可以基于 LangChain 進(jìn)行個(gè)性化定制,實(shí)現(xiàn)從用戶輸入到數(shù)據(jù)庫再到大模型最后輸出的整體架構(gòu)連接故俐。
搭建數(shù)據(jù)庫: 大模型應(yīng)用需要進(jìn)行向量語義檢索想鹰,一般使用諸如 chroma 的向量數(shù)據(jù)庫。搭建數(shù)據(jù)庫需要收集數(shù)據(jù)并進(jìn)行預(yù)處理药版,再向量化存儲到數(shù)據(jù)庫中愕乎。數(shù)據(jù)預(yù)處理一般包括從多種格式向純文本的轉(zhuǎn)化西土,例如 pdf瑞筐、markdown福荸、html、音視頻等还栓,以及對錯(cuò)誤數(shù)據(jù)碌廓、異常數(shù)據(jù)、臟數(shù)據(jù)進(jìn)行清洗剩盒。完成預(yù)處理后谷婆,需要進(jìn)行切片、向量化構(gòu)建出個(gè)性化數(shù)據(jù)庫。
1.2.3纪挎、Prompt Engineering
明確 Prompt 設(shè)計(jì)的一般原則及技巧期贫,構(gòu)建出一個(gè)來源于實(shí)際業(yè)務(wù)的小型驗(yàn)證集,基于小型驗(yàn)證集設(shè)計(jì)滿足基本要求廷区、具備基本能力的 Prompt唯灵。
優(yōu)質(zhì)的 Prompt 對大模型能力具有極大影響贾铝,需要逐步迭代構(gòu)建優(yōu)質(zhì)的 Prompt Engineering 來提升應(yīng)用性能隙轻。
1.2.4、驗(yàn)證迭代
驗(yàn)證迭代在大模型開發(fā)中是極其重要的一步垢揩,指通過不斷發(fā)現(xiàn) Bad Case 并針對性改進(jìn) Prompt Engineering 來提升系統(tǒng)效果玖绿、應(yīng)對邊界情況。在完成上一步的初始化 Prompt 設(shè)計(jì)后叁巨,應(yīng)該進(jìn)行實(shí)際業(yè)務(wù)測試斑匪,探討邊界情況,找到 Bad Case锋勺,并針對性分析 Prompt 存在的問題蚀瘸,從而不斷迭代優(yōu)化,直到達(dá)到一個(gè)較為穩(wěn)定庶橱、可以基本實(shí)現(xiàn)目標(biāo)的 Prompt 版本贮勃。
1.2.5、前后端搭建
完成 Prompt Engineering 及其迭代優(yōu)化之后苏章,就完成了應(yīng)用的核心功能寂嘉,可以充分發(fā)揮大語言模型的強(qiáng)大能力。接下來搭建前后端枫绅,設(shè)計(jì)產(chǎn)品頁面泉孩,讓應(yīng)用上線成為產(chǎn)品。
兩種快速開發(fā) Demo 的框架:Gradio 和 Streamlit并淋,可以幫助個(gè)體開發(fā)者迅速搭建可視化頁面實(shí)現(xiàn) Demo 上線寓搬。
在完成前后端搭建之后,應(yīng)用就可以上線體驗(yàn)了县耽。接下來就需要進(jìn)行長期的用戶體驗(yàn)跟蹤句喷,記錄 Bad Case 與用戶負(fù)反饋,再針對性進(jìn)行優(yōu)化即可酬诀。
二脏嚷、項(xiàng)目流程簡析
基于個(gè)人知識庫的問答助手介紹項(xiàng)目流程。
項(xiàng)目原理:項(xiàng)目原理如下圖所示瞒御,過程包括加載本地文檔 -> 讀取文本 -> 文本分割 -> 文本向量化 -> question向量化 -> 在文本向量中匹配出與問句向量最相似的 top k個(gè) -> 匹配出的文本作為上下文和問題一起添加到 prompt中 -> 提交給 LLM生成回答父叙。
2.1、項(xiàng)目規(guī)劃與需求分析
1、項(xiàng)目目標(biāo):基于個(gè)人知識庫的問答助手
2趾唱、核心功能:
1涌乳、上傳文檔、創(chuàng)建知識庫甜癞;
2夕晓、選擇知識庫,檢索用戶提問的知識片段悠咱;
3蒸辆、提供知識片段與提問,獲取大模型回答析既;
4躬贡、流式回復(fù);
5眼坏、歷史對話記錄
3拂玻、確定技術(shù)架構(gòu)和工具:
1、LangChain框架
2宰译、Chroma知識庫
3檐蚜、大模型使用 GPT、科大訊飛的星火大模型沿侈、文心一言闯第、GLM 等
4、前后端使用 Gradio 和 Streamlit肋坚。
2.2乡括、數(shù)據(jù)準(zhǔn)備與向量知識庫構(gòu)建
2.2.1、收集和整理用戶提供的文檔
用戶常用文檔格式有 pdf智厌、txt诲泌、doc 等,首先使用工具讀取文本铣鹏,通常使用 langchain 的文檔加載器模塊敷扫,也可以使用 python 比較成熟的包進(jìn)行讀取。
由于目前大模型使用 token 的限制诚卸,需要對讀取的文本進(jìn)行切分葵第,將較長的文本切分為較小的文本,這時(shí)一段文本就是一個(gè)單位的知識合溺。
2.2.2卒密、將文檔詞向量化
使用文本嵌入(Embeddings)對分割后的文檔進(jìn)行向量化,使語義相似的文本片段具有接近的向量表示棠赛。然后哮奇,存入向量數(shù)據(jù)庫膛腐,這個(gè)流程正是創(chuàng)建 索引(index) 的過程。
向量數(shù)據(jù)庫對各文檔片段進(jìn)行索引鼎俘,支持快速檢索哲身。這樣,當(dāng)用戶提出問題時(shí)贸伐,可以先將問題轉(zhuǎn)換為向量勘天,在數(shù)據(jù)庫中快速找到語義最相關(guān)的文檔片段。然后將這些文檔片段與問題一起傳遞給語言模型捉邢,生成回答脯丝。
2.2.3、將向量化后的文檔導(dǎo)入Chroma知識庫歌逢,建立知識庫索引
Chroma 向量庫輕量級且數(shù)據(jù)存儲在內(nèi)存中巾钉,非常容易啟動和開始使用。
用戶知識庫內(nèi)容經(jīng)過 embedding 存入向量知識庫秘案,然后用戶每一次提問也會經(jīng)過 embedding,利用向量相關(guān)性算法(例如余弦算法)找到最匹配的幾個(gè)知識庫片段潦匈,將這些知識庫片段作為上下文阱高,與用戶問題一起作為 prompt 提交給 LLM 回答。
2.3茬缩、大模型集成與API連接
- 集成GPT赤惊、星火、文心凰锡、GLM 等大模型未舟,配置 API 連接。
- 編寫代碼掂为,實(shí)現(xiàn)與大模型 API 的交互裕膀,以便獲取問題答案。
2.4勇哗、核心功能實(shí)現(xiàn)
- 構(gòu)建 Prompt Engineering昼扛,實(shí)現(xiàn)大模型回答功能,根據(jù)用戶提問和知識庫內(nèi)容生成回答欲诺。
- 實(shí)現(xiàn)流式回復(fù)抄谐,允許用戶進(jìn)行多輪對話。
- 添加歷史對話記錄功能扰法,保存用戶與助手的交互歷史蛹含。
2.5、核心功能迭代優(yōu)化
- 進(jìn)行驗(yàn)證評估塞颁,收集 Bad Case浦箱。
- 根據(jù) Bad Case 迭代優(yōu)化核心功能實(shí)現(xiàn)卧斟。
2.6、前端與用戶交互界面開發(fā)
- 使用 Gradio 和 Streamlit 搭建前端界面憎茂。
- 實(shí)現(xiàn)用戶上傳文檔珍语、創(chuàng)建知識庫的功能。
- 設(shè)計(jì)用戶界面竖幔,包括問題輸入板乙、知識庫選擇、歷史記錄展示等拳氢。
2.7募逞、部署測試與上線
- 部署問答助手到服務(wù)器或云平臺,確辈銎溃可在互聯(lián)網(wǎng)上訪問放接。
- 進(jìn)行生產(chǎn)環(huán)境測試,確保系統(tǒng)穩(wěn)定留特。
- 上線并向用戶發(fā)布纠脾。
2.8、維護(hù)與持續(xù)改進(jìn)
- 監(jiān)測系統(tǒng)性能和用戶反饋蜕青,及時(shí)處理問題苟蹈。
- 定期更新知識庫,添加新的文檔和信息右核。
- 收集用戶需求慧脱,進(jìn)行系統(tǒng)改進(jìn)和功能擴(kuò)展。
三贺喝、項(xiàng)目架構(gòu)簡析
3.1菱鸥、整體架構(gòu)
搭建一個(gè)基于大模型的個(gè)人知識庫助手,基于 LangChain 框架搭建躏鱼,核心技術(shù)包括 LLM API 調(diào)用氮采、向量數(shù)據(jù)庫、檢索問答鏈等挠他。項(xiàng)目整體架構(gòu)如下:
項(xiàng)目從底向上依次分為 LLM 層扳抽、數(shù)據(jù)層、數(shù)據(jù)庫層殖侵、應(yīng)用層與服務(wù)層:
3.1.1贸呢、LLM 層
基于四種流行 LLM API (OpenAI-ChatGPT、百度文心拢军、訊飛星火楞陷、智譜GLM)進(jìn)行了 LLM 調(diào)用封裝,支持用戶以統(tǒng)一的入口茉唉、方式來訪問不同的模型固蛾,支持隨時(shí)進(jìn)行模型的切換结执;
在 LLM 層,構(gòu)建了一個(gè) Self_LLM 基類艾凯,基類定義了所有 API 的一些共同參數(shù)(如 API_Key献幔,temperature 等);在該基類基礎(chǔ)上繼承實(shí)現(xiàn)了上述四種 LLM API 的自定義 LLM趾诗。四種 LLM 的原生 API 封裝在了統(tǒng)一的 get_completion 函數(shù)中蜡感。
3.1.2、數(shù)據(jù)層
包括個(gè)人知識庫的源數(shù)據(jù)(包括 pdf恃泪、txt郑兴、md 等)以及 Embedding API,源數(shù)據(jù)經(jīng)過 Embedding 處理可以被向量數(shù)據(jù)庫使用贝乎;
3.1.3情连、數(shù)據(jù)庫層
基于個(gè)人知識庫源數(shù)據(jù)搭建的向量數(shù)據(jù)庫,本項(xiàng)目中選擇了 Chroma览效。在該層實(shí)現(xiàn)了源數(shù)據(jù)處理却舀、創(chuàng)建向量數(shù)據(jù)庫的方法;
3.1.4、應(yīng)用層
應(yīng)用層封裝了整個(gè)項(xiàng)目的全部核心功能朽肥〗ぃ基于 LangChain 提供的檢索問答鏈基類進(jìn)行了進(jìn)一步封裝,支持通過 model 參數(shù)進(jìn)行不同模型切換以及便捷實(shí)現(xiàn)基于數(shù)據(jù)庫的檢索問答衡招。
實(shí)現(xiàn)了兩個(gè)檢索問答鏈,分別是有歷史記錄的 Chat_QA_Chain 和沒有歷史記錄的 QA_Chain每强;
3.1.5始腾、服務(wù)層
實(shí)現(xiàn)了 Gradio 搭建 Demo 與 FastAPI 組建 API 兩種方式來支持本項(xiàng)目的服務(wù)訪問。
3.2空执、代碼結(jié)構(gòu)
-project
-readme.md 項(xiàng)目說明
-requirements.txt 使用依賴包的版本
-llm LLM調(diào)用封裝
-self_llm.py 自定義 LLM 基類
-wenxin_llm.py 自定義百度文心 LLM
-spark_llm.py 自定義訊飛星火 LLM
-zhipuai_llm.py 自定義智譜AI LLM
-call_llm.py 將各個(gè) LLM 的原生接口封裝在一起
-test.ipynb 使用示例
-embedding embedding調(diào)用封裝
-zhipuai_embedding.py 自定義智譜AI embedding
-call_embedding.py 調(diào)用 embedding 模型
-data 源數(shù)據(jù)路徑
-database 數(shù)據(jù)庫層封裝
-create_db.py 處理源數(shù)據(jù)及初始化數(shù)據(jù)庫封裝
-qa_chain 應(yīng)用層封裝
-qa_chain.py 封裝檢索問答鏈浪箭,返回一個(gè)檢索問答鏈對象
-chat_qa_chian.py:封裝對話檢索鏈,返回一個(gè)帶有歷史記錄的對話檢索鏈對象
-get_vectordb.py 返回向量數(shù)據(jù)庫對象
-model_to_llm.py 調(diào)用模型
-test.ipynb 使用示例
-serve 服務(wù)層封裝
-run_gradio.py 啟動 Gradio 界面
-api.py 封裝 FastAPI
-run_api.sh 啟動 API
-test.ipynb 使用示例
3.3辨绊、項(xiàng)目邏輯
1奶栖、用戶:可以通過 run_gradio 或者 run_api 啟動整個(gè)服務(wù);
2门坷、服務(wù)層調(diào)用 qa_chain.py 或 chat_qa_chain 實(shí)例化對話檢索鏈對象宣鄙,實(shí)現(xiàn)全部核心功能;
3默蚌、服務(wù)層和應(yīng)用層都可以調(diào)用冻晤、切換 prompt_template.py 中的 prompt 模板來實(shí)現(xiàn) prompt 的迭代;
4绸吸、也可以直接調(diào)用 call_llm 中的 get_completion 函數(shù)來實(shí)現(xiàn)不使用數(shù)據(jù)庫的 LLM鼻弧;
5设江、應(yīng)用層調(diào)用已存在的數(shù)據(jù)庫和 llm 中的自定義 LLM 來構(gòu)建檢索鏈;
6攘轩、如果數(shù)據(jù)庫不存在叉存,應(yīng)用層調(diào)用 create_db.py 創(chuàng)建數(shù)據(jù)庫,該腳本可以使用 openai embedding 也可以使用 embedding.py 中的自定義 embedding