探索 LLM:從基礎原理到 RAG 實現的深度解析

一.LLM基礎知識

1.1 大語言模型(Large Language Model,LLM)

  1. 他是模型,是 AI 能力的核心。
  2. 他是語言模型,其核心能力在于語言能力。
  3. 他是大語言模型,與傳統模型相比,它最大的特點就是“大”。

1.2 AI應用

  1. AI應用,就是以 LLM 為核心的各種應用
  2. 從API的角度理解GPT模型,它最核心的參數就是輸入一個或多個字符串,然后,大模型輸出一個字符串
  3. 與傳統的應用開發不同的是,這個 API 并非是傳統應用開發中按照特定預期處理的結果。
  4. 使用傳統的 API,我們需要關注的是接口文檔,而想要發揮 LLM 的威力,我們需要對大模型有一定的了解

1.3 大模型原理

  1. 一次添加一個詞
  2. 下一個詞是什么
  3. token
  4. 溫度(Temperature):表示隨機性強弱的概念
    這個參數越小,表示確定性越強,越大,表示隨機性越強,簡單理解就是,溫度越高越活躍
  5. Embedding :在大模型內部處理的是向量,,Embedding 是一種將高維數據(如文本、圖像、視頻等)轉換為低維向量表示的技術。這種技術在自然語言處理(NLP)、計算機視覺等領域有著廣泛的應用。Embedding 的核心思想是將離散數據映射到連續的向量空間,使得相似的數據點在向量空間中的距離較近,而不相似的數據點則距離較遠。

1.4 promot工程

  1. 提示詞 = 定義角色 + 背景信息 + 任務目標 + 輸出要求
  2. 要求:大模型處理復雜任務場景的能力
  3. 原因:Agent背后的技術能讓大模型推斷下一步行為,利用大模型的推理能力,依賴于promot工程
  4. 起源:Natural Language Processing(NLP):如果給予 AI 適當的引導,它能更準確地理解我們的意圖,響應我們的指令
  5. 零樣本提示(Zero-Shot Prompting):適合簡單的任務。比如,一些簡單查詢就可以使用零樣本提示。我們需要做的就是調整提示詞
  6. 少樣本提示(Few-Shot Prompting):適合復雜的任務。比如,我們需要讓 AI 回答一個問題,我們需要提供一些例子,讓 AI 學習這些例子,然后再回答問題。
  7. 思維鏈提示(Chain-of-Thought Prompting):思維鏈提示給出的答案則是帶有完整的思考過程,是一個“慢下來”的答案,于是得到了一個正確的答案
  8. ReAct 框架(Reasoning + Acting) :推理 + 行動=大模型為了完成一個大目標,需要不斷地做一些任務。每個任務都會經歷思考(Thought)、行動(Action)、觀察(Observation)三個階段。

二.LLM-Code

2.1 Open AI API

  • Text Generation:生成和處理文本
  • Embeddings:文本轉向量
  • Speech to Text:語音轉文本
  • Image Generation:生成圖像
  • Vision:處理圖像輸入

2.2 SSE

  • SSE 是服務器發送事件(Server-Sent Event),它是一種服務器推送技術,客戶端通過 HTTP 連接接收來自服務器的自動更新
  • 它描述了服務器如何在建立初始客戶端連接后向客戶端發起數據傳輸。
  1. 為啥不用WebSocket
  • SSE 的技術特點契合流式應答的需求:客戶端與大模型的交互是一次性的,每產生一個 token,服務端就可以給客戶端推送一次,當生成內容結束時,斷掉連接,無需考慮客戶端的存活情況
  • 如果采用 WebSocket 的話,服務端就需要維護連接,像 OpenAI 這樣的服務體量,維護連接就會造成很大的服務器壓力,而且,在生成內容場景下,也沒有向服務端進一步發送內容,WebSocket 的雙向通信在這里也是多余的
  • SSE 這項技術而言,它存在已經很長時間了,2004 年就有人提出,大模型才流行起來

2.3 核心的三個抽象

  • ChatModel:整個框架的核心,根據輸入的內容生成輸出
  • PromptTemplate: 負責處理輸入,有效拆分開發者提示詞和用戶提示詞
  • OutputParser:負責處理輸出,許多輸出解析器里包含了格式指令

2.4 編碼實現

from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.prompts import ChatPromptTemplate 
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnableWithMessageHistory # 設置 API 密鑰
api_key = "你的密鑰"
# 初始化 ChatOpenAI 實例時傳遞 API 密鑰
chat_model = ChatOpenAI(model="gpt-4o-mini", api_key=api_key)
store = {}
def get_session_history(session_id: str) -> BaseChatMessageHistory:if session_id not in store:store[session_id] = InMemoryChatMessageHistory()return store[session_id]
prompt = ChatPromptTemplate.from_messages([("system","你現在扮演程序員的角色,可以直接生成代碼",),MessagesPlaceholder(variable_name="messages"),]
)
with_message_history = RunnableWithMessageHistory(prompt | chat_model,get_session_history
)
config = {"configurable": {"session_id": "chatLLMCode"}}
while True:user_input = input("You:> ")if user_input.lower() == 'exit':breakstream = with_message_history.stream({"messages": [HumanMessage(content=user_input)]},config=config)for chunk in stream:print(chunk.content, end='', flush=True)print()

三.RAG

3.1 檢索增強生成(Retrieval Augmented Generation,RAG)

  1. 檢索增強生成(Retrieval Augmented Generation,RAG)是一種結合了檢索和生成的技術,它可以在生成文本時,利用外部的知識庫來增強生成的內容。
  2. 檢索增強生成:在本地檢索到相關的內容,把它增強到提示詞里,然后再去做內容生成
    產生背景:

* 讓LLM知道自己的行業知識,有兩種方式

  1. 模型微調:使用業務信息對已經訓練好的模型進行微調
  2. RAG:在上下文中帶有業務信息,讓大模型據此進行整合

3.2 Embeddings和VectorStore

  1. Embeddings:Embeddings 是一種將高維數據(如文本、圖像、視頻等)轉換為低維向量表示的技術。這種技術在自然語言處理(NLP)、計算機視覺等領域有著廣泛的應用。Embeddings 的核心思想是將離散數據映射到連續的向量空間,使得相似的數據點在向量空間中的距離較近,而不相似的數據點則距離較遠。
  2. VectorStore:VectorStore 是一種用于存儲和檢索向量數據的技術。它可以將高維向量數據存儲在一個向量空間中,以便快速查找相似的向量。VectorStore 的核心思想是將高維數據映射到低維向量空間,以便進行高效的相似度搜索。
    3.索引(Indexing):索引是一種用于快速查找數據的技術。它可以將數據存儲在一個索引中,以便快速查找數據。索引的核心思想是將數據映射到一個索引空間中,以便進行高效的查找。
  3. 相似度搜索(Similarity Search):相似度搜索是一種用于查找與給定向量最相似的向量的技術。它可以將給定的向量與索引中的向量進行比較,以便找到最相似的向量。相似度搜索的核心思想是將給定的向量映射到索引空間中,以便進行高效的查找。

3.3 索引過程

  1. 首先,我們需要將文本數據轉換為向量。這可以通過使用 Embeddings 技術來實現。
  2. 然后,我們需要將向量存儲在一個向量空間中。這可以通過使用 VectorStore 技術來實現。
  3. 最后,索引把信息放到向量數據庫中,而檢索就是把信息提取出來,提取出來的信息與用戶提示詞合并起來,再到大模型去完成生成

RAG 是為了讓大模型知道更多的東西。

3.4 RAG的實現

# 導入 operator 模塊中的 itemgetter 函數,用于從字典中獲取指定鍵的值
from operator import itemgetter
# 導入 typing 模塊中的 List 類型,用于定義列表類型的變量
from typing import List
# 導入 tiktoken 庫,用于計算字符串中的 token 數量
import tiktoken
# 從 langchain_core.messages 模塊中導入各種消息類和消息修剪函數
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage, ToolMessage, SystemMessage, trim_messages
# 從 langchain_core.chat_history 模塊中導入聊天歷史類
from langchain_core.chat_history import BaseChatMessageHistory, InMemoryChatMessageHistory
# 從 langchain_core.prompts 模塊中導入提示模板類和消息占位符類
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 從 langchain_core.runnables 模塊中導入可運行傳遞類
from langchain_core.runnables import RunnablePassthrough
# 從 langchain_core.runnables.history 模塊中導入帶有消息歷史的可運行類
from langchain_core.runnables.history import RunnableWithMessageHistory
# 從 langchain_openai 模塊中導入 OpenAIEmbeddings 類,用于生成文本的嵌入向量
from langchain_openai import OpenAIEmbeddings
# 從 langchain_openai.chat_models 模塊中導入 ChatOpenAI 類,用于與 OpenAI 的聊天模型進行交互
from langchain_openai.chat_models import ChatOpenAI
# 從 langchain_chroma 模塊中導入 Chroma 類,用于與 Chroma 向量數據庫進行交互
from langchain_chroma import Chroma# 創建一個 Chroma 向量數據庫實例,指定集合名稱為 "rag",嵌入函數為 OpenAIEmbeddings(),持久化目錄為 "vectordb"
vectorstore = Chroma(collection_name="rag",embedding_function=OpenAIEmbeddings(),persist_directory="vectordb"
)# 將向量數據庫轉換為檢索器,使用相似度搜索類型
retriever = vectorstore.as_retriever(search_type="similarity")# 定義一個函數,用于計算字符串中的 token 數量
def str_token_counter(text: str) -> int:# 獲取 "o200k_base" 編碼enc = tiktoken.get_encoding("o200k_base")# 返回編碼后的字符串長度return len(enc.encode(text))# 定義一個函數,用于計算消息列表中的 token 數量
def tiktoken_counter(messages: List[BaseMessage]) -> int:# 初始化 token 數量為 3num_tokens = 3# 每個消息的 token 數量為 3tokens_per_message = 3# 每個名稱的 token 數量為 1tokens_per_name = 1# 遍歷消息列表for msg in messages:# 如果消息是人類消息,設置角色為 "user"if isinstance(msg, HumanMessage):role = "user"# 如果消息是 AI 消息,設置角色為 "assistant"elif isinstance(msg, AIMessage):role = "assistant"# 如果消息是工具消息,設置角色為 "tool"elif isinstance(msg, ToolMessage):role = "tool"# 如果消息是系統消息,設置角色為 "system"elif isinstance(msg, SystemMessage):role = "system"# 如果消息類型不支持,拋出異常else:raise ValueError(f"Unsupported messages type {msg.__class__}")# 累加 token 數量num_tokens += (tokens_per_message+ str_token_counter(role)+ str_token_counter(msg.content))# 如果消息有名稱,累加名稱的 token 數量if msg.name:num_tokens += tokens_per_name + str_token_counter(msg.name)# 返回 token 數量return num_tokens# 創建一個消息修剪器,設置最大 token 數量為 4096,策略為 "last",token 計數器為 tiktoken_counter,包括系統消息
trimmer = trim_messages(max_tokens=4096,strategy="last",token_counter=tiktoken_counter,include_system=True,
)# 創建一個空字典,用于存儲會話歷史
store = {}# 定義一個函數,用于獲取會話歷史
def get_session_history(session_id: str) -> BaseChatMessageHistory:# 如果會話 ID 不存在,創建一個新的內存聊天歷史實例if session_id not in store:store[session_id] = InMemoryChatMessageHistory()# 返回會話歷史實例return store[session_id]# 創建一個 ChatOpenAI 實例,用于與 OpenAI 的聊天模型進行交互
model = ChatOpenAI()# 創建一個聊天提示模板,包含系統消息、歷史消息占位符和人類消息
prompt = ChatPromptTemplate.from_messages([("system","""You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.Context: {context}""",),MessagesPlaceholder(variable_name="history"),("human", "{question}"),]
)# 定義一個函數,用于格式化文檔列表
def format_docs(docs):# 返回格式化后的文檔字符串return "\n\n".join(doc.page_content for doc in docs)# 創建一個上下文獲取器,通過檢索器獲取相關文檔,并格式化文檔
context = itemgetter("question") | retriever | format_docs
# 創建第一個步驟,將上下文賦值給 "context" 鍵
first_step = RunnablePassthrough.assign(context=context)
# 創建一個鏈,將第一個步驟、提示模板、消息修剪器和聊天模型連接起來
chain = first_step | prompt | trimmer | model# 創建一個帶有消息歷史的可運行實例,將鏈、會話歷史獲取器、輸入消息鍵和歷史消息鍵連接起來
with_message_history = RunnableWithMessageHistory(chain,get_session_history=get_session_history,input_messages_key="question",history_messages_key="history",
)# 設置配置,指定會話 ID 為 "dreamhead"
config = {"configurable": {"session_id": "dreamhead"}}# 無限循環
while True:# 獲取用戶輸入user_input = input("You:> ")# 如果用戶輸入為 "exit",退出循環if user_input.lower() == 'exit':break# 如果用戶輸入為空,繼續循環if user_input.strip() == "":continue# 使用帶有消息歷史的可運行實例處理用戶輸入,并獲取流式響應stream = with_message_history.stream({"question": user_input}, config=config)# 逐塊打印流式響應內容for chunk in stream:print(chunk.content, end='', flush=True)# 打印換行符print()

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

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

相關文章

Mac cursor設置jdk、Maven版本

基本配置 – Cursor 使用文檔 首先是系統用戶級別的設置參數,運行cursor,按下ctrlshiftp,輸入Open User Settings(JSON),在彈出的下拉菜單中選中下面這樣的: 在打開的json編輯器中追加下面的內容: {"…

ARM64平臺Flutter環境搭建

ARM64平臺Flutter環境搭建 Flutter簡介問題背景搭建步驟1. 安裝ARM64 Android Studio2. 安裝Oracle的JDK3. 安裝 Dart和 Flutter 開發插件4. 安裝 Android SDK5. 安裝 Flutter SDK6. 同意 Android 條款7. 運行 Flutter 示例項目8. 修正 aapt2 報錯9. 修正 CMake 報錯10. 修正 N…

selenium clear()方法清除文本框內容

在使用Selenium進行Web自動化測試時,清除文本框內容是一個常見的需求。這可以通過多種方式實現,取決于你使用的是哪種編程語言(如Python、Java等)以及你的具體需求。以下是一些常見的方法: 1. 使用clear()方法 clear…

基于海思soc的智能產品開發(視頻的后續開發)

【 聲明:版權所有,歡迎轉載,請勿用于商業用途。 聯系信箱:feixiaoxing 163.com】 前面我們討論了camera,也討論了屏幕驅動,這些都是基礎的部分。關鍵是,我們拿到了這些視頻數據之后,…

vue3+webOffice合集

1、webOffice 初始化 1)officeType: 文檔位置:https://solution.wps.cn/docs/web/quick-start.html#officetype 2)appId: 前端使用appId 后端需要用到AppSecret 3)fileId: 由后端返回,前端無法生成,與上傳文…

2025牛客寒假算法營2

A題 知識點&#xff1a;模擬 打卡。檢查給定的七個整數是否僅包含 1,2,3,5,6 即可。為了便于書寫&#xff0c;我們可以反過來&#xff0c;檢查這七個整數是否不為 4 和 7。 時間 O(1)&#xff1b;空間 O(1)。 #include <bits/stdc.h> using namespace std;signed main()…

記錄一次k8s起不來的排查過程

我在k8s集群&#xff0c;重啟了一個node宿主機&#xff0c;竟然發現kubelet起不來了&#xff01;報錯如下 這個報錯很模糊&#xff0c;怎么排查呢。這樣&#xff0c;開兩個界面&#xff0c;一個重啟kubelet&#xff0c;一個看系統日志(/var/log/message:centos&#xff0c;/va…

Docker Desktop 在Windows 環境中開發、測試和運行容器化的應用程序

Docker 為 Windows 提供了專門的桌面版工具&#xff0c;稱為 Docker Desktop&#xff0c;它允許你在 Windows 環境中開發、測試和運行容器化的應用程序。 如何在 Windows 上使用 Docker Docker Desktop Docker Desktop 是一個專為 Windows 設計的應用程序&#xff0c;它簡化了…

仿 RabbitMQ 的消息隊列3(實戰項目)

七. 消息存儲設計 上一篇博客已經將消息統計文件的讀寫代碼實現了&#xff0c;下一步我們將實現創建隊列文件和目錄。 實現創建隊列文件和目錄 初始化 0\t0 這樣的初始值. //創建隊列對應的文件和目錄&#xff1a;public void createQueueFile(String queueName) throws IO…

HTTP 配置與應用(局域網)

想做一個自己學習的有關的csdn賬號&#xff0c;努力奮斗......會更新我計算機網絡實驗課程的所有內容&#xff0c;還有其他的學習知識^_^&#xff0c;為自己鞏固一下所學知識&#xff0c;下次更新HTTP 配置與應用&#xff08;不同網段&#xff09;。 我是一個萌新小白&#xf…

root用戶Linux銀河麒麟服務器安裝vnc服務

安裝必要桌面環境組件 yum install mate-session-manager -y mate-session #確定是否安裝成功安裝vnc服務器 yum install tigervnc-server -y切換到root為root得vnc設置密碼 su root vncpasswd給root用戶設置vnc服務器文件 vi /etc/systemd/system/vncserver:1.service [Un…

理解深度學習pytorch框架中的線性層

文章目錄 1. 數學角度&#xff1a; y W x b \displaystyle y W\,x b yWxb示例 2. 編程實現角度&#xff1a; y x W T b \displaystyle y x\,W^T b yxWTb3. 常見錯誤與易混點解析4. 小結參考鏈接 在神經網絡或機器學習的線性層&#xff08;Linear Layer / Fully Connect…

C#Object類型的索引,序列化和反序列化

前言 最近在編寫一篇關于標準Mes接口框架的文章。其中有一個非常需要考究的內容時如果實現數據靈活和可使用性強。因為考慮數據靈活性&#xff0c;所以我一開始選取了Object類型作為數據類型&#xff0c;Object作為數據Value字段&#xff0c;String作為數據Key字段&#xff0c…

大模型應用與部署 技術方案

大模型應用與部署 技術方案 一、引言 人工智能蓬勃發展,Qwen 大模型在自然語言處理領域地位關鍵,其架構優勢盡顯,能處理文本創作等多類復雜任務,提供優質交互。Milvus 向量數據庫則是向量數據存儲檢索利器,有高效索引算法(如 IVF_FLAT、HNSWLIB 等)助力大規模數據集相似…

【Prometheus】Prometheus如何監控Haproxy

?? 歡迎大家來到景天科技苑?? &#x1f388;&#x1f388; 養成好習慣&#xff0c;先贊后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者簡介&#xff1a;景天科技苑 &#x1f3c6;《頭銜》&#xff1a;大廠架構師&#xff0c;華為云開發者社區專家博主&#xff0c;…

C# 控制打印機:從入門到實踐

在開發一些涉及打印功能的應用程序時&#xff0c;使用 C# 控制打印機是一項很實用的技能。這篇文章就來詳細介紹下如何在 C# 中實現對打印機的控制。 一、準備工作 安裝相關庫&#xff1a;在 C# 中操作打印機&#xff0c;我們可以借助System.Drawing.Printing命名空間&#x…

Go語言中的值類型和引用類型特點

一、值類型 值類型的數據直接包含值&#xff0c;當它們被賦值給一個新的變量或者作為參數傳遞給函數時&#xff0c;實際上是創建了原值的一個副本。這意味著對新變量的修改不會影響原始變量的值。 Go中的值類型包括&#xff1a; 基礎類型&#xff1a;int&#xff0c;float64…

GPT 結束語設計 以nanogpt為例

GPT 結束語設計 以nanogpt為例 目錄 GPT 結束語設計 以nanogpt為例 1、簡述 2、分詞設計 3、結束語斷點 1、簡述 在手搓gpt的時候&#xff0c;可能會遇到一些性能問題&#xff0c;即關于是否需要全部輸出或者怎么節約資源。 在輸出語句被max_new_tokens 限制&#xff0c…

《探秘:人工智能如何為鴻蒙Next元宇宙網絡傳輸與延遲問題破局》

在元宇宙的宏大愿景中&#xff0c;流暢的網絡傳輸和低延遲是保障用戶沉浸式體驗的關鍵。鴻蒙Next結合人工智能技術&#xff0c;為解決這些問題提供了一系列創新思路和方法。 智能網絡監測與預測 人工智能可以實時監測鴻蒙Next元宇宙中的網絡狀況&#xff0c;包括帶寬、延遲、…

深入MapReduce——計算模型設計

引入 通過引入篇&#xff0c;我們可以總結&#xff0c;MapReduce針對海量數據計算核心痛點的解法如下&#xff1a; 統一編程模型&#xff0c;降低用戶使用門檻分而治之&#xff0c;利用了并行處理提高計算效率移動計算&#xff0c;減少硬件瓶頸的限制 優秀的設計&#xff0c…