datawhale大模型應用開發夏令營學習筆記一

參考自

  • 基于LangChain+LLM的本地知識庫問答:從企業單文檔問答到批量文檔問答
  • datawhale的llm-universe

作者現在在datawhale夏令營的大模型應用開發這個班中,作為一個小白,為了能為團隊做出一點貢獻,現在就要開始學習怎么使用langchain的api來實現基本的功能!

隨便談談

由于科大訊飛的星火杯已經為我們提供了 星火大模型 的API,我也不好進行模型調參,現在能做的就是開展prompt工程,結合RAG,給到模型優質的輸入信息,幫助它正確回答我提出的疑問和要求。我首先學的就是這兩個。

我一開始的想法是做本地知識庫,那么模型是怎么知道這些知識呢?我們知道一個人的知識儲備,可以來自他的積累,也可以來自他現在手里正翻著的書(或者當場百度:))。大模型也一樣。我們可以在訓練大模型時讓他學習龐大的知識,也可以在提問一些小眾知識時附加可參考的內容(比如在詢問一個rust的第三方庫怎么用時,順帶把這個庫的文檔文本一起給他,讓他參考這些文檔進行回答)

  • 參數知識:在訓練期間學習到的知識,隱式存儲在神經網絡的權重中。
  • 非參數知識:存儲在外部知識源中,例如向量數據庫。

當然,直接傳整篇文檔的方式比較粗暴,可以事先將全篇文檔放入向量數據庫或知識圖譜(統稱為知識庫)。那么一次問答的過程為:首先用戶提問請回答我的xx問題,然后大模型根據用戶的提問去知識庫中匹配并獲取相關的參考資料,然后再將用戶輸入改為根據 xxxxx 這些參考資料,請回答我的xx問題并傳入大模型。

一步步基于langchain實現訊飛大模型的調用和RAG

主要參考自datawhale的教程https://github.com/datawhalechina/llm-universe/tree/main/notebook,確實比較詳細
我實操的大概過程為:

  1. 調用星火大模型
  2. 讀取Markdown或pdf作為本地知識,并解析出其中的文本,并進行數據清洗
  3. 對解析出的文本進行文本切分。因為單個文檔的長度往往會超過模型支持的上下文,導致檢索得到的知識太長超出模型的處理能力
  4. 調用星火的文本向量化接口
  5. 使用Chroma存儲向量并檢索,即建立本地知識庫
  6. 使用template,并使用langchain的LCEL語法實現一條鏈式處理,該鏈將獲取輸入變量,將這些變量傳遞給提示模板以創建提示,將提示傳遞給語言模型,然后通過(可選)輸出解析器傳遞輸出。
  7. 將"知識庫檢索"這一過程加入處理鏈中,實現大模型鏈接本地知識庫
  8. 基于Memory模塊讓大模型能使用到歷史對話,實現帶上下文的對話
  9. streamlit的教學我沒看,目前考慮使用Gradio

以上過程均基于langchain的api。
我這里只放一些重點內容,對詳細過程感興趣的同學可以跟著教程繼續學習,我就不粘貼一遍教程里的代碼了

RAG和微調的對比

特征比較RAG微調
知識更新直接更新檢索知識庫,無需重新訓練。信息更新成本低,適合動態變化的數據。通常需要重新訓練來保持知識和數據的更新。更新成本高,適合靜態數據。
外部知識擅長利用外部資源,特別適合處理文檔或其他結構化/非結構化數據庫。將外部知識學習到 LLM 內部。
數據處理對數據的處理和操作要求極低。依賴于構建高質量的數據集,有限的數據集可能無法顯著提高性能。
模型定制側重于信息檢索和融合外部知識,但可能無法充分定制模型行為或寫作風格。可以根據特定風格或術語調整 LLM 行為、寫作風格或特定領域知識。
可解釋性可以追溯到具體的數據來源,有較好的可解釋性和可追蹤性。黑盒子,可解釋性相對較低。
計算資源需要額外的資源來支持檢索機制和數據庫的維護。依賴高質量的訓練數據集和微調目標,對計算資源的要求較高。
推理延遲增加了檢索步驟的耗時單純 LLM 生成的耗時
降低幻覺通過檢索到的真實信息生成回答,降低了產生幻覺的概率。模型學習特定領域的數據有助于減少幻覺,但面對未見過的輸入時仍可能出現幻覺。
倫理隱私檢索和使用外部數據可能引發倫理和隱私方面的問題。訓練數據中的敏感信息需要妥善處理,以防泄露。

LangChain

封裝了很多模型的調用方式以及工具比如chain、memory等
https://python.langchain.com/v0.2/docs/integrations/llms/

Prompt

在 ChatGPT 推出并獲得大量應用之后,Prompt 開始被推廣為給大模型的所有輸入。即,我們每一次訪問大模型的輸入為一個 Prompt,而大模型給我們的返回結果則被稱為 Completion。

Temperature

LLM 生成是具有隨機性的,我們一般可以通過控制 temperature 參數來控制 LLM 生成結果的隨機性與創造性。

Temperature 一般取值在 0~1 之間,當取值較低接近 0 時,預測的隨機性會較低,產生更保守、可預測的文本,不太可能生成意想不到或不尋常的詞。當取值較高接近 1 時,預測的隨機性會較高,所有詞被選擇的可能性更大,會產生更有創意、多樣化的文本,更有可能生成不尋常或意想不到的詞。

對于不同的問題與應用場景,我們可能需要設置不同的 temperature。例如,在個人知識庫助手項目中,我們一般將 temperature 設置為 0,從而保證助手對知識庫內容的穩定使用,規避錯誤內容、模型幻覺;在產品智能客服、科研論文寫作等場景中,我們同樣更需要穩定性而不是創造性;但在個性化 AI、創意營銷文案生成等場景中,我們就更需要創意性,從而更傾向于將 temperature 設置為較高的值。

System Prompt

在使用 ChatGPT API 時,你可以設置兩種 Prompt:一種是 System Prompt,該種 Prompt 內容會在整個會話過程中持久地影響模型的回復,且相比于普通 Prompt 具有更高的重要性;另一種是 User Prompt,這更偏向于我們平時提到的 Prompt,即需要模型做出回復的輸入。
System Prompt 一般在一個會話中僅有一個。在通過 System Prompt 設定好模型的人設或是初始設置后,我們可以通過 User Prompt 給出模型需要遵循的指令。
例如,當我們需要一個幽默風趣的個人知識庫助手,并向這個助手提問我今天有什么事時,可以構造如下的 Prompt:

{"system prompt": "你是一個幽默風趣的個人知識庫助手,可以根據給定的知識庫內容回答用戶的提問,注意,你的回答風格應是幽默風趣的","user prompt": "我今天有什么事務?"
}

Prompt工程

可以理解為使用結構化的提問方式,向模型傳入更詳細的提問內容,引導大模型進行更精確和正確的回答
具體可參考https://github.com/datawhalechina/llm-universe/blob/main/notebook/C2%20%E4%BD%BF%E7%94%A8%20LLM%20API%20%E5%BC%80%E5%8F%91%E5%BA%94%E7%94%A8/3.%20Prompt%20Engineering.ipynb

此次開發用到的官方文檔

  • langchain中使用sparkllm
  • langchain中使用spark的文本向量化
  • langchain中解析文件中的文本
  • langchain中使用Chroma

還是貼個代碼

知識庫為一篇Markdown https://github.com/sunface/rust-course/blob/main/src/advance/macro.md
這里的代碼參考datawhale的代碼,只實現了鏈接知識庫和結合上下文對話,沒有用到LCEL。深入源碼以及看官方文檔后發現,LangChain非常多的API棄用或將被棄用,API改動這么頻繁,而且有些API都不好在IDE里跳到源碼,難怪langchain的爭議這么大。

import os
import re
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.llms.sparkllm import SparkLLM
from langchain_community.embeddings import SparkLLMTextEmbeddings
from langchain_community.document_loaders import UnstructuredMarkdownLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain.prompts.chat import ChatPromptTemplate,SystemMessagePromptTemplate,HumanMessagePromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain# 通過環境變量的方式設置秘鑰,具體的key-value可以在IDE內點進源碼查看
def load_env():# 星火認知大模型Spark Max的URL值,其他版本大模型URL值請前往文檔(https://www.xfyun.cn/doc/spark/Web.html)查看#星火認知大模型調用秘鑰信息,請前往訊飛開放平臺控制臺(https://console.xfyun.cn/services/bm35)查看#星火認知大模型Spark Max的domain值,其他版本大模型domain值請前往文檔(https://www.xfyun.cn/doc/spark/Web.html)查看os.environ["IFLYTEK_SPARK_API_URL"] = "wss://spark-api.xf-yun.com/v3.5/chat"os.environ["IFLYTEK_SPARK_API_KEY"] = ""os.environ["IFLYTEK_SPARK_API_SECRET"] = ""os.environ["IFLYTEK_SPARK_APP_ID"] = ""os.environ["IFLYTEK_SPARK_LLM_DOMAIN"] = "generalv3.5"# 文本向量化os.environ["SPARK_APP_ID"] = ""os.environ["SPARK_API_KEY"] =  ""os.environ["SPARK_API_SECRET"] = ""# 使用UnstructuredMarkdownLoader讀取時似乎不能讀emoji
# 此時需要預先處理文件,再使用API解析無emoji的Markdown文件
def remove_emojis(text):try:co = re.compile(u'[\U00010000-\U0010ffff]')except re.error:co = re.compile(u'[\uD800-\uDBFF][\uDC00-\uDFFF]')no_emojis_text = co.sub(r'', text)return no_emojis_text# 長文本切分為多個小文檔
def text_split(doc):# 知識庫中單段文本長度CHUNK_SIZE = 500# 知識庫中相鄰文本重合長度OVERLAP_SIZE = 50# 使用遞歸字符文本分割器text_splitter = RecursiveCharacterTextSplitter(chunk_size=CHUNK_SIZE,chunk_overlap=OVERLAP_SIZE)return text_splitter.split_documents(doc)def prepare_knowledge():# 此篇文章無emojifiles = ["macro.md"]md_pages = []for f in files:loader = UnstructuredMarkdownLoader(f)md_page = loader.load()# 打印這個文檔來自哪個的文件名# source = md_page.metadata['source']# print(source)# 刪除無必要的連續換行md_page[0].page_content = md_page[0].page_content.replace('\n\n', '\n')md_pages.extend(md_page)# 文本切分docs = text_split(md_pages)# 實例化星火文本向量化接口的調用工具embeddings = SparkLLMTextEmbeddings()# 可以直接調用來向量化文本# embeddings.aembed_query(text)/aembed_documents(doc)# 初始化一個Chroma向量數據庫,讓Chroma將文檔向量化# 并將數據庫文件和向量數據保存到文件夾中vectordb = Chroma.from_documents(documents=docs,embedding=embeddings,persist_directory='./vector')vectordb.persist()if __name__ == '__main__':# 設置環境變量load_env()# 實例化星火大模型調用工具llm = SparkLLM(temperature=0.95)# 初始化知識庫prepare_knowledge()# 加載本地知識庫embeddings = SparkLLMTextEmbeddings()vector_db = Chroma(persist_directory="./vector", embedding_function=embeddings)# 對話歷史記錄memory = ConversationBufferMemory(memory_key="chat_history",return_messages=True,  # 將以消息列表的形式返回聊天記錄,而不是單個字符串)# 模版system_template = """使用提供的上下文和聊天記錄回答用戶的問題。不知道也不要編造答案,回答盡量簡要。并且總是在回答的最后說“謝謝你的提問!”----------------CONTEXT:{context}CHAT HISTORY:{chat_history}USER QUESTION:{question}"""messages = [SystemMessagePromptTemplate.from_template(system_template),HumanMessagePromptTemplate.from_template("{question}")]qa_prompt = ChatPromptTemplate.from_messages(messages)# 創建問答鏈,為其添加檢索知識庫和歷史記錄的功能qa = ConversationalRetrievalChain.from_llm(llm,retriever=vector_db.as_retriever(),combine_docs_chain_kwargs={'prompt': qa_prompt},memory=memory)print("第一次問答:")question = "我可以在你這里學習到關于提示工程的知識嗎?"result = qa({"question": question})print(result['answer'])print("第二次問答:")question = "為什么?"result = qa({"question": question})print(result['answer'])

在這里插入圖片描述
在這里插入圖片描述

由于突然文本向量化接口突然報錯,上述代碼我這里測試不了構建知識庫了。但好在可以加載之前構建好的知識庫來測試后面的代碼。代碼總體應該沒問題,之后再看看
Request error: 11202, {‘header’: {‘code’: 11202, ‘message’: ‘licc failed’, ‘sid’: ‘emb000fc090@dx1907452bed6738d882’}}
Request error: 11202, {‘header’: {‘code’: 11202, ‘message’: ‘licc failed’, ‘sid’: ‘emb000ebcb7@dx1907452bf547020882’}}

TODO

  • 怎么持久化以及加載歷史信息,這篇博客到時候可以參考:【LangChain】對話式問答(Conversational Retrieval QA)
  • 怎么將知識圖譜作為知識庫
  • 評測和優化

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/40710.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/40710.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/40710.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

實戰教程:如何用JavaScript構建一個功能強大的音樂播放器,兼容本地與在線資源

項目地址:Music Player App 作者:Reza Mehdikhanlou 視頻地址:youtube 我將向您展示如何使用 javascript 編寫音樂播放器。我們創建一個項目,您可以使用 javascript 從本地文件夾或任何 url 播放音頻文件。 項目目錄 assets 1…

頂級10大AI測試工具

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎?訂閱我們的簡報,深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同,從行業內部的深度分析和實用指南中受益。不要錯過這個機會,成為AI領…

暑期編程預習指南

暑期編程預習指南 高考結束后,迎來的是一段難得的假期時光。對于那些有志于踏入IT領域的高考生來說,這段時間無疑是一個重要的起點。為了幫助你們更好地利用這個假期,為未來的學習和職業生涯打下堅實的基礎,特此提供一份編程預習…

JWT入門

JWT與TOKEN JWT(JSON Web Token)是一種基于 JSON 格式的輕量級安全令牌,通常用于在網絡應用間安全地傳遞信息。而“token”一詞則是一個更廣泛的術語,用來指代任何形式的令牌,用于在計算機系統中進行身份驗證或授權。J…

【?講解下Laravel為什么會成為最優雅的PHP框架?】

🎥博主:程序員不想YY啊 💫CSDN優質創作者,CSDN實力新星,CSDN博客專家 🤗點贊🎈收藏?再看💫養成習慣 ?希望本文對您有所裨益,如有不足之處,歡迎在評論區提出…

cloudreve 設置開機服務

創建一個Systemd服務文件: 打開終端并創建一個新的服務文件: sudo nano /etc/systemd/system/cloudreve.service 在服務文件中添加以下內容: 根據你的設置調整路徑和參數,然后將以下配置粘貼到文件中: [Unit] Descri…

Django學習第四天

啟動項目命令 python manage.py runserver 分頁功能封裝到類中去 封裝的類的代碼 """ 自定義的分頁組件,以后如果想要使用這個分頁組件,你需要做: def pretty_list(request):# 靚號列表data_dict {}search_data request.GET.get(q, &…

Excel為數據繪制拆線圖,并將均值線疊加在圖上,以及整個過程的區域錄屏python腳本

Excel為數據繪制拆線圖,并將均值線疊加在圖上,以及整個過程的區域錄屏python腳本 1.演示動畫A.視頻B.gif動畫 2.跟蹤鼠標區域的錄屏腳本 Excel中有一組數據,希望畫出曲線,并且能把均值線也繪制在圖上,以下動畫演示了整個過程,并且提供了區域錄屏腳本,原理如下: 為節約空間,避免…

從華為和特斯拉之爭,看智能駕駛的未來

“一旦特斯拉完全解決自動駕駛問題并量產Optimus,任何空頭都將被消滅,即使是比爾-蓋茨也不例外。”7月2日,馬斯克再次在社交媒體X上畫下了這樣的“大餅”。 與此同時,特斯拉的股價在最近的三個交易日也迎來了24%的漲幅&#xff0c…

中俄汽車產業鏈合作前景廣闊,東方經濟論壇助力雙邊合作與創新

隨著中國汽車零部件企業的競爭力和創新能力不斷增強,中國汽車及零部件行業在俄羅斯的市場份額和品牌影響力顯著提升,中俄兩國在汽車產業鏈上的合作展現出巨大的潛力和廣闊的前景。2024年5月,俄羅斯乘用車新車銷量達到12.8萬輛,同比…

7.基于SpringBoot的SSMP整合案例-表現層開發

目錄 1.基于Restfu1進行表現層接口開發 1.1創建功能類 1.2基于Restful制作表現層接口 2.接收參數 2使用Apifox測試表現層接口功能 保存接口: 分頁接口: 3.表現層一致性處理 3.1先創建一個工具類,用作后端返回格式統一類:…

SpringMVC 的工作流程和詳細解釋

Spring MVC(Model-View-Controller)框架是基于經典的 MVC 設計模式構建的,用于開發 Web 應用程序。下面是 Spring Boot MVC 的工作流程和詳細解釋: 1.客戶端發起請求 1.客戶端(通常是瀏覽器)發起 HTTP 請求…

招聘智能管理系統設計

設計一個招聘智能管理系統,需要從多個維度考慮,包括但不限于用戶界面、功能模塊、數據安全、算法模型等。以下是一個基本的設計框架: 1. 系統架構: 前端:提供直觀的用戶界面,包括應聘者和招聘者的登錄/注冊…

Python學習篇:Python基礎知識(三)

目錄 1 Python保留字 2 注釋 3 行與縮進 ?編輯4 多行語句 5 輸入和輸出 6 變量 7 數據類型 8 類型轉換 9 表達式 10 運算符 1 Python保留字 Python保留字(也稱為關鍵字)是Python編程語言中預定義的、具有特殊含義的標識符。這些保留字不能用作…

Android 工具腳本

工具腳本 Shell腳本 獲取Git分支名稱 def gitBranch() {def branch ""def proc "git rev-parse --abbrev-ref HEAD".execute()proc.in.eachLine { line -> branch line }proc.err.eachLine { line -> println line }proc.waitFor()branch }

生信算法9 - 正則表達式匹配氨基酸序列、核型和字符串

1. 使用正則表達式匹配指定的氨基酸序列 import re# 氨基酸序列 seq VSVLTMFRYAGWLDRLYMLVGTQLAAIIHGVALPLMMLI# 正則表達式匹配 match re.search(r[A|G]W, seq)# 打印match及匹配到開始位置和結束位置 print(match) # <re.Match object; span(10, 12), matchGW> prin…

DP學習——觀察者模式

學而時習之&#xff0c;溫故而知新。 2個角色 分為啥主題和觀察者角色。 我覺得主題就是干活的&#xff0c;打工仔&#xff0c;為觀察者干活。 一對多。一個主題&#xff0c;多個觀察者——就像一個開發人員對多個項目經理——項目經理拿小皮鞭抽呀抽呀&#xff0c;受不了。 …

代碼隨想錄算法訓練營第70天圖論9[1]

代碼隨想錄算法訓練營第70天:圖論9 ? 拓撲排序精講 卡碼網&#xff1a;117. 軟件構建(opens new window) 題目描述&#xff1a; 某個大型軟件項目的構建系統擁有 N 個文件&#xff0c;文件編號從 0 到 N - 1&#xff0c;在這些文件中&#xff0c;某些文件依賴于其他文件的…

5款軟件讓電腦更方便,更快,更好看

? 你有沒有想過&#xff0c;有些軟件能讓你的電腦用起來更方便&#xff0c;更快&#xff0c;更好看&#xff1f; 1. 屏幕動畫創作——Screen To Gif ? Screen To Gif是一款功能強大的屏幕錄制軟件&#xff0c;專注于將屏幕上的動態內容轉換為高質量的GIF動畫。它不僅支持自…

《ClipCap》論文筆記(下)

原文出處 [2111.09734] ClipCap: CLIP Prefix for Image Captioning (arxiv.org) 原文翻譯 接上篇 《ClipCap》論文筆記&#xff08;上&#xff09;-CSDN博客 4. Results Datasets.我們使用 COCO-captions [7,22]、nocaps [1] 和 Conceptual Captions [33] 數據集。我們根…