寫在前面
- 博文內容為基于 LangChain 數據增強 和 Ollams 本地部署 DeepSeek-R1
- 實現 K8s運維文檔檢索與問答系統 Demo
- 通過 Demo 對
LEDVR 工作流
,語義檢索
有基本認知 - 理解不足小伙伴幫忙指正 😃,生活加油
我看遠山,遠山悲憫
持續分享技術干貨,感興趣小伙伴可以關注下 _
Ollama 部署 DeepSeek-R1
過 Ollama
在本地部署 DeepSeek-R1
蒸餾模型,通過 langChain
調用,下載模型,啟動 Ollama
服務
PS C:\Users\Administrator> ollama list
NAME ID SIZE MODIFIED
deepseek-r1:latest 0a8c26691023 4.7 GB 3 seconds ago
deepseek-r1:32b 38056bbcbb2d 19 GB 2 weeks ago
deepseek-r1:14b ea35dfe18182 9.0 GB 2 weeks ago
deepseek-r1:8b 28f8fd6cdc67 4.9 GB 2 weeks ago
bge-m3:latest 790764642607 1.2 GB 2 weeks ago
PS C:\Users\Administrator> ollama serve
Error: listen tcp 127.0.0.1:11434: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
PS C:\Users\Administrator> ollama serve
2025/03/09 01:22:39 routes.go:1187: INFO server config env="map[CUDA_VISIBLE_DEVICES: GPU_DEVICE_ORDINAL: HIP_VISIBLE_DEVICES: HSA_OVERRIDE_GFX_VERSION: HTTPS_PROXY: HTTP_PROXY: NO_PROXY: OLLAMA_DEBUG:false OLLAMA_FLASH_ATTENTION:false OLLAMA_GPU_OVERHEAD:0 OLLAMA_HOST:http://127.0.0.1:11434 OLLAMA_INTEL_GPU:false OLLAMA_KEEP_ALIVE:5m0s OLLAMA_KV_CACHE_TYPE: OLLAMA_LLM_LIBRARY: OLLAMA_LOAD_TIMEOUT:5m0s OLLAMA_MAX_LOADED_MODELS:0 OLLAMA_MAX_QUEUE:512 OLLAMA_MODELS:C:\\Users\\Administrator\\.ollama\\models OLLAMA_MULTIUSER_CACHE:false OLLAMA_NOHISTORY:false OLLAMA_NOPRUNE:false OLLAMA_NUM_PARALLEL:0 OLLAMA_ORIGINS:[http://localhost https://localhost http://localhost:* https://localhost:* http://127.0.0.1 https://127.0.0.1 http://127.0.0.1:* https://127.0.0.1:* http://0.0.0.0 https://0.0.0.0 http://0.0.0.0:* https://0.0.0.0:* app://* file://* tauri://* vscode-webview://*] OLLAMA_SCHED_SPREAD:false ROCR_VISIBLE_DEVICES:]"
time=2025-03-09T01:22:39.303+08:00 level=INFO source=images.go:432 msg="total blobs: 14"
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
time=2025-03-09T01:22:39.448+08:00 level=INFO source=types.go:131 msg="inference compute" id=GPU-e65029a6-c2f9-44b1-bd76-c12e4083fa4c library=cuda variant=v12 compute=8.6 driver=12.8 name="NVIDIA GeForce RTX 3060" total="12.0 GiB" available="11.0 GiB"
LangChain 數據增強模塊
LangChain 的數據增強模塊是構建大語言模型(LLM)應用的核心組件,專注于整合、優化外部數據
以提升模型輸入的精準度與效率。
該模塊通過文檔加載器?(Document Loaders)
從多源數據(如PDF、數據庫、網頁)
中提取內容
并標準化為結構化文檔
。針對長文本或復雜格式問題,內置的文檔轉換器?(Document Transformers)支持切割、合并、過濾
等操作。
同時,模塊還通過向量存儲?(Vector Stores)和檢索器?(Retrievers)
實現數據的高效管理
,利用嵌入模型
將文本轉換為向量
,構建語義檢索能力
,從而在用戶提問時快速定位相關片段作為上下文注入提示詞模板
。
與LLM
的協作流程形成檢索增強生成(RAG)?
范式:外部數據經加載、轉換、存儲后,結合用戶問題生成動態提示詞
,通過模型包裝器調用底層API并解析輸出。其典型應用包括長文本摘要(如法律條款分析)、知識庫問答(精準召回專業內容)以及實時數據更新(定期抓取網頁信息并同步向量庫)
。通過模塊化設計,LangChain
大幅簡化了異構數據處理復雜度,為開發者提供靈活、可擴展的LLM應用支持。
LEDVR 工作流
數據增強模塊是一個多功能的數據增強集成工具,一般稱作 LEDVR
其中:
L
代表加載器(Loader)
E
代表嵌人模型包裝器(Text EmbeddingModcl)
D
代表文檔轉換器( Document Transformers)
V
代表向量存儲庫( VectorStore )
R
代表檢索器(Retriever)
加載器
負責從各種來源加載數據作為文檔,其中文檔是由文本和相關元數據組成的。無論是簡單的.txt 文件,還是任何網頁文本內容,加載器都可以將它們加載為文檔。
嵌人模型包裝器
一個專為與各種文本嵌人模型(如 OpenAI、Coherc、HuggingFace
等)交互而設計的類。它的作用與模型 I/O 模塊
的 LLM 模型包裝器
和聊天模型包裝器
一樣,用于通過嵌入模型生成向量
文檔轉換器
主要用來對文檔進行切割、組合、過濾等各種轉換
。文本切割器(RecursiveCharacterTcxtSplitter)
是最常見的文檔轉換工具。文檔轉換器的目的是將加載的文檔轉換為可被嵌入模型包裝器操作的文檔數據格式
。
向量存儲庫
是用于存儲和檢索嵌入向量
的工具,處理的數據是通過模型平臺的文本嵌人模型(Text Embedding Mode1)轉換的向量數據
,這是處理非結構化數據的-種常見方法。向量存儲庫負責存儲嵌入數據并執行向量檢索
。在檢索時,可以嵌入非結構化查詢,以檢索與嵌入數據“最相似”的嵌入向量。
檢索器
是一個接口,返回非結構化查詢
的文檔。它比向量存儲庫更通用。檢索器
無須存儲文檔,只需要返回(或檢索)文檔
。
K8s運維文檔檢索與問答系統 Demo
下面為一個基于 LEDVR 工作流(Loader → Embedding → Document Transformers → VectorStore → Retriever)與本地部署 Ollama 的完整代碼示例
Demo
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : demo_LEDVR.py
@Time : 2025/03/15 04:30:36
@Author : Li Ruilong
@Version : 1.0
@Contact : liruilonger@gmail.com
@Desc : None
"""# here put the import lib
#pip install langchain langchain-community ollama -i https://pypi.tuna.tsinghua.edu.cn/simple
#pip install faiss-cpu
#pip install pypdf
#pip install "unstructured[md]"import nltk
#nltk.download('averaged_perceptron_tagger')from langchain.prompts import PromptTemplate
from langchain_community.document_loaders import UnstructuredMarkdownLoader
from langchain_text_splitters import TokenTextSplitter
from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.llms import Ollama
from langchain.chains import RetrievalQA
import warningswarnings.filterwarnings("ignore") # 忽略嵌入模型警告#### 1. 加載md文檔 L 加載器
print("=============開始加載md文檔")
loader = UnstructuredMarkdownLoader("K8s面試系列:K8s常用API資源總結速記 .md")
documents = loader.load()print(len(documents))#### 2. 文檔轉換器 (Document Transformers)
# 2. 按token分塊
print("=============按token分塊")
text_splitter = TokenTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = text_splitter.split_documents(documents)
print(f"有效分塊數: {len(chunks)}") # 應大于0if not chunks:raise ValueError("文檔分塊失敗!請檢查原始文件內容和分塊參數。")print(len(chunks)) #### 3. 嵌入模型 (Embedding)
print("=============嵌入模型")
embeddings = OllamaEmbeddings(model="bge-m3", # 支持的模型包括bge-m3base_url="http://localhost:11434" # 默認端口11434
)#### 4. 向量存儲庫 (VectorStore)
# 構建本地 FAISS 向量數據庫
vector_db = FAISS.from_documents(chunks, embeddings)#### 5. 檢索器 (Retriever)
# 配置 Top-3 相似度檢索
retriever = vector_db.as_retriever(search_kwargs={"k": 3})### **集成 Ollama 本地模型**
# 配置本地 DeepSeek R1 模型(需提前通過 Ollama 下載)
llm = Ollama(base_url='http://localhost:11434',model="deepseek-r1:latest"
)prompt_template = """基于以下上下文回答問題:
{context}
問題:{question}
答案(不超過4句話):"""# 構建問答鏈
qa_chain = RetrievalQA.from_chain_type(llm=llm,chain_type="stuff",retriever=retriever,chain_type_kwargs={"prompt": PromptTemplate.from_template(prompt_template)},return_source_documents=True
)# 執行查詢
question = "K8s 中準入控制器資源有哪些?"
response = qa_chain.invoke({"query": question})# 輸出結果
print("回答:", response["result"])
print("參考來源:")
for doc in response["source_documents"]:print(f"- {doc.page_content[:80]}...")
下面為實際的輸出示例
PS C:\Users\Administrator\Documents\GitHub\LangChainDemo> & C:/Users/Administrator/AppData/Local/Programs/Python/Python310/python.exe c:/Users/Administrator/Documents/GitHub/LangChainDemo/demo/demo_LEDVR.py
[nltk_data] Downloading package averaged_perceptron_tagger to
[nltk_data] C:\Users\Administrator\AppData\Roaming\nltk_data...
[nltk_data] Package averaged_perceptron_tagger is already up-to-
[nltk_data] date!
=============開始加載md文檔
1
=============按token分塊
有效分塊數: 86
86
=============嵌入模型
回答: <think>
嗯,我現在要回答關于K8s中準入控制器資源的問題。根據提供的上下文,我看到有幾種不同的準入控制器,比如ValidatingAdmissionPolicy、ValidatingWebhookConfiguration和NetworkPolicy。
首先,ValidatingAdmissionPolicy是在K8s 1.30版本中發布的,用于在資源被創建、更新或刪除時執行驗證邏輯。它應用到apps/v1組中的deployment資源,并且拒絕請求如果副本數超過5。
然后是ValidatingWebhookConfiguration,這個結構包含一個配置和一個認證,允許從服務或其他地方發送鉤子調用到容器注冊表中。這意味著當服務發布到K8s的時候,會自動觸發這些鉤子,這在擴展性方面很有幫助。
接下來是NetworkPolicy,這是一組策略,可以定義網絡的白名單規則。比如,允許特定IP范圍和端口下的流量通過。雖然Flannel不支持它,但其他插件如Calico、Cilium等支持,并且這些插件可以集成到K8s中使用。
還有ResourceQuota,用于限制命名空間中的資源使用。這是一種策略,可以在集群級別限制CPU、內存等資源的使用,有助于確保資源分配公平。
總結一下,準入控制器資源包括ValidatingAdmissionPolicy、ValidatingWebhookConfiguration和NetworkPolicy,這些都是用來控制和管理K8s資源的工 具。
</think>在K8s中,準入控制器資源主要用于控制和驗證API請求。以下是一些常見的準入控制器資源及其用途:1. **ValidatingAdmissionPolicy**:- **版本信息**:發布于K8s 1.30。- **用途**:應用于特定的資源類型(如Deployments),在資源被創建、更新或刪除時執行驗證邏輯。- **示例策略**:限制部署的副本數不超過5個。2. **ValidatingWebhookConfiguration**:- **結構**:包含一個配置和一個認證,用于允許從服務或其他位置發送鉤子調用到容器注冊表中。- **用途**:簡化服務發布流程,自動觸發鉤子調用。3. **NetworkPolicy**:- **支持的工具**:Calico、Cilium、Weave Net等插件支持,并可集成到K8s中。- **用途**:定義網絡的白名單規則,允許特定IP范圍和端口下的流量通過。4. **ResourceQuota**:- **功能**:限制命名空間中的資源使用,如CPU和內存,確保資源分配公平。這些資源共同作用,幫助實施集群級別的安全和管理策略。參考來源:
- 個新的準入控制器,定義自定義的驗證邏輯,在資源被創建、更新或刪除時執行。K8s 1.30 發布正式版本yaml apiVersion: admissionr...
- .1.0/24 - namespaceSelector: #命名空間限制 matchLabels: project: myproject - podSelect...
- title: K8s面試系列:K8s常用 API 資源總結速記 tags: - Kubernetes categories: - Kubernetes toc:...
PS C:\Users\Administrator\Documents\GitHub\LangChainDemo>
可以看到答案對于這本地運行的蒸餾模型,并且只有幾十行代碼來實現的功能來說以及很不錯了。
下面部分為加載的文檔中的內容的簡單摘要,這是我之前寫的一篇博文,可以看到通過一個簡單的Demo檢索的答案很接近
…
–#### ValidatingAdmissionPolicy
一種類似 Admission Webhook
的聲明式配置方式。ValidatingAdmissionPolicy
是 K8s 1.26
版本引入的一個新的準入控制器
,定義自定義的驗證邏輯,在資源被創建、更新或刪除時執行。K8s 1.30
發布正式版本
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:name: "demo-policy.example.com"
spec:failurePolicy: Fail # Fail表示如果驗證失敗,則拒絕請求。matchConstraints: #定義哪些API請求應該被此策略驗證。resourceRules:- apiGroups: ["apps"]apiVersions: ["v1"]operations: ["CREATE", "UPDATE"]resources: ["deployments"]validations: # 具體的驗證規則- expression: "object.spec.replicas <= 5" # 驗證部署(Deployment)對象的副本數(replicas)是否小于或等于5。
這個策略將應用于所有對apps/v1組中deployments資源的CREATE和UPDATE操作,并且會拒絕任何副本數超過5的部署請求。
前面講到的 ValidatingWebhookConfiguration
和 ValidatingAdmissionPolicy
都是 Kubernetes 中的準入控制機制,但它們在設計和使用方式上有一些重要區別:
…
…
關于上面的關鍵組件做說明
模塊 | 技術實現 | 優勢說明 |
---|---|---|
Loader | UnstructuredMarkdownLoader md 格式文檔加載 | 統一處理 md 格式 |
Document Transformers | 遞歸字符分塊法保留上下文語義 | 解決長文本 token 限制問題 |
Embedding | bge-m3 輕量化模型 | 本地部署無需 API 密鑰 |
VectorStore | FAISS 高效向量檢索 | 支持毫秒級相似度匹配 |
Ollama | DeepSeek R1 7B 量化版 | 消費級 GPU 即可運行 |
這里我們在看一個有報錯信息的 Demo
.............................
loader = UnstructuredMarkdownLoader("Kubernetes 觸發 OOMKilled(內存殺手)如何排除故障.md")
...................
# 執行查詢
question = """```bash
┌──[root@vms100.liruilongs.github.io]-[~/ansible/oomkiller]
└─$kubectl apply -f oom-killer-pod.yaml
pod/oom-killer-pod created
┌──[root@vms100.liruilongs.github.io]-[~/ansible/oomkiller]
└─$kubectl get pods oom-killer-pod -w
NAME READY STATUS RESTARTS AGE
oom-killer-pod 0/1 ContainerCreating 0 7s
oom-killer-pod 1/1 Running 0 25s
oom-killer-pod 0/1 OOMKilled 0 28s
oom-killer-pod 0/1 OOMKilled 1 (18s ago) 45s
oom-killer-pod 0/1 CrashLoopBackOff 1 (13s ago) 57s
oom-killer-pod 0/1 OOMKilled 2 (29s ago) 73s
/```
上面的報錯是什么原因?如何解決?
"""
response = qa_chain.invoke({"query": question})# 輸出結果
print("回答:", response["result"])
print("參考來源:")
for doc in response["source_documents"]:print(f"- {doc.page_content[:180]}...")
PS C:\Users\Administrator\Documents\GitHub\LangChainDemo> c:; cd 'c:\Users\Administrator\Documents\GitHub\LangChainDemo'; & 'c:\Users\Administrator\AppData\Local\Programs\Python\Python310\python.exe' 'c:\Users\Administrator\.vscode\extensions\ms-python.debugpy-2025.4.1-win32-x64\bundled\libs\debugpy\launcher' '55098' '--' 'C:\Users\Administrator\Documents\GitHub\LangChainDemo\demo\demo_LEDVR.py'
[nltk_data] Downloading package averaged_perceptron_tagger to
[nltk_data] C:\Users\Administrator\AppData\Roaming\nltk_data...
[nltk_data] Package averaged_perceptron_tagger is already up-to-
[nltk_data] date!
=============開始加載md文檔
1
=============按token分塊
有效分塊數: 21
21
=============嵌入模型
回答: <think>
好吧,我現在要解決這個Kubernetes中的OOMKilled錯誤問題。讓我先理清楚發生了什么。首先,用戶運行了一個Pod,里面裝有一個叫bigmem的應用程序,這通常會模擬內存不回收的情況。當他們運行這個Pod時,發現出現了oom-killer-pod的Pod狀態,其中有兩個OOMKilled日志。根據提供的上下文,這可能是因為內存不足導致系統調用內核中的OOMKiller來終止進程。
我看到用戶提到他們使用了_ansible任務,并且在yaml文件中裝了一個 bigmem 包。這個包通常會讓容器保持大段內存,導致內存泄漏。當Pod的內存消耗超過限制時,Kubernetes會通 過CrashLoopBackOff機制調用OOMKiller來終止進程。
問題是如何解決這個問題。首先,我需要理解為什么會觸發OOM錯誤。這可能是因為內存管理不善,或者Pod的資源設置不當。例如,沒有正確設置 pod resource limits 或 container resources limit。
接下來,我應該檢查用戶生成的 YAML 文件,看看是否正確限制了pod或容器的內存。確保 bigmem 包被正確卸載,并且資源限制足夠。
此外,調整容器和pod的資源限制也是一個好方法。比如,為每個容器添加一個適當的 resource Limits,或者將 pod 的資源限制提高到足以運行所有容器,但又不超出系統處理能力。
如果資源限制不足以應對內存泄漏的問題,可能需要重新審視 bigmem 包的配置,看看是否可以適當卸載或優化其內存使用情況。
最后,如果調整資源限制后問題仍然存在,可能需要進一步檢查是否有其他進程占用過多內存,或者系統中的內存分配策略是否有問題。此外,確保容器調度器(如Podman)已經正確設置,并且沒有其他潛在的內存消耗因素。
總之,解決這個問題的關鍵在于識別導致OOM錯誤的根本原因,可能是資源限制不當或內存泄漏,然后相應地調整配置以避免這種情況。
</think>
上面的情況是由于容器內存不回收(bigmem 包的存在)導致系統調用 Kubernetes 的 OOMKiller 功能。OOMKiller 通過終止進程來釋放內存。解決方法:
1. 在 pod.yaml 中卸載 bigmem 包:/```yamlresources:bigmem-7.0-1.r29766.x86_64.rpm: null/```
2. 調整 container resource limits,限制每個容器的內存使用:/```yamlcontainers:- image=bigmem-7.0-1.r29766.x86_64.rpmresources:memory: '512MiB'/```
3. 確保 pod resource limits 足夠大,以支持所有容器同時運行。通過這些調整,可以避免因內存泄漏導致的 OOMKilled 錯誤。參考來源:
- ms100.liruilongs.github.io]-[~/ansible/oomkiller] └─$kubectl get pods oom-killer-pod -w NAME READY STATUS RESTARTS AGE oom-killer-pod 0/1 ContainerCreating 0 7s oom-killer-pod 1/1 ...
- /ansible/oomkiller] └─$
對于在生產環境的 Pod ,OOMKilled 常常 伴隨這 CrashLoopBackOff,觸發 OOM 之后,被 Kill 掉,之后由于 Pod 重啟機制,會陷入 CrashLoopBackOff
什么是 OOMKilled K8s 錯誤
當 Kubernetes 集群中的容器超出其內存限制時,Ku...
- o wide No resources found in resources namespace. ┌──[root@vms81.liruilongs.github.io]-[~/ansible/resources] └─$vim pod-demo.yaml ┌──[root@vms81.liruilongs.github.io]-[~/ansible/re...
PS C:\Users\Administrator\Documents\GitHub\LangChainDemo>
博文部分內容參考
? 文中涉及參考鏈接內容版權歸原作者所有,如有侵權請告知 😃
《LangChain 入門指南構建高可復用、可擴展的 LLM 應用程序》
書籍獲取有條件小伙伴可以支持一下原書作者,pdf 版本獲取:https://pan.quark.cn/s/2bf8697bf0d2
? 2018-至今 liruilonger@gmail.com, 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)