前文,我们在本地windows电脑基于GGUF文件,部署了DeepSeek R1 1.5B模型,如果想在离线模式下加载本地的DeepSeek模型自行对进行训练时,是不能直接使用GGUF文件进行训练的,但是可以对模型进行微调,以下说的是第二种微调的方法:检索增强生成(RAG)。
请参照我的文章在本地部署好模型之后再继续往下看:个人windows电脑上安装DeepSeek大模型(完整详细可用教程)-CSDN博客
第一种微调方法:提示工程。可以查看我的文章:本地基于GGUF部署的DeepSeek实现轻量级调优之一:提示工程(Prompt Engineering)(完整详细教程)-CSDN博客
一、GGUF文件的定位与限制
先说明一下基于GGUF文件部署的本地DeepSeek模型为什么不能直接训练,是因为基于GGUF文件的性质和特点导致的。
1.GGUF的作用:
(1)推理优化:GGUF(GPT-Generated Unified Format)是专为高效推理设计的二进制格式,常用于llama.cpp等工具在CPU/GPU上运行量化模型。
(2)量化支持:支持多种量化方法(如Q4_K_M、Q5_K_S),显著减少显存占用,但会损失部分精度。
2.训练限制:
(1)缺乏训练所需信息:GGUF文件仅包含推理所需的权重和架构简略信息,缺少训练必需的反向传播梯度计算图、优化器状态等。
(2)框架不兼容:主流训练框架(如PyTorch、TensorFlow)无法直接加载GGUF文件进行训练。
二、实现过程说明
我已经在本地的Windows系统上成功部署了基于GGUF格式的DeepSeek R1 1.5模型,使用llama.cpp工具进行加载DeepSeek和推理,现在想要进一步部署sentence-transformers/all-MiniLM-L6-v2模型,用于实现RAG(检索增强生成)的微调。其中,部署sentence-transformers模型用于将文档和查询编码为向量,以便进行相似性检索。使用all-MiniLM-L6-v2模型作为RAG中的嵌入模型,来增强DeepSeek模型的生成效果。GGUF模型通常用于推理,而RAG需要结合检索和生成两部分,因此需要将两者结合起来。
接下来,就是如何在Windows环境下本地部署entence-transformers/all-MiniLM-L6-v2这个嵌入模型,并集成到现有的RAG流程中。我需要考虑以下几个步骤:
1. 安装依赖
确保用户安装了必要的Python库,如sentence-transformers、torch等。同时,可能需要处理Windows特有的依赖问题,比如C++编译工具链,但sentence-transformers通常不需要编译,除非需要优化。
2. 下载并保存模型
用户需要将all-MiniLM-L6-v2模型下载到本地目录。这里需要指导用户如何通过代码或命令行下载,并保存到指定路径,以便离线使用。
3. 验证模型加载
确保模型可以离线加载,并且能够生成嵌入向量。可能需要测试一些示例代码,确认没有网络请求,完全离线运行。
4. 集成到RAG流程
用户现有的RAG流程可能已经使用其他嵌入模型或方法,现在需要替换或整合sentence-transformers模型。需要指导如何修改现有的向量数据库配置,使用新的嵌入模型。
5. 性能优化
考虑到Windows系统可能存在的性能限制,尤其是如果用户没有GPU,需要提供CPU优化的建议,比如使用量化或调整批处理大小。
6. 测试和验证
确保整个流程从文档加载、分块、嵌入生成到检索和生成都能正常工作。可能需要提供示例代码和测试用例。
结合外部知识库动态扩展模型输出,RAG无需修改GGUF模型权重。关键优化技巧:
方向 | 具体方法 |
检索质量 | 1. 调整分块大小(chunk_size=256-1024) 2. 添加元数据过滤(如文档来源、日期) |
生成控制 | 1. 设置temperature=0.3减少随机性 2. 使用max_tokens限制输出长度 |
性能提升 | 1. 启用llama.cpp的GPU加速(n_gpu_layers=20) 2. 缓存常用检索结果 |
本地部署全流程如下:
(1)知识库:ChromaDB + 自定义文档
(2)检索:Sentence Transformers + 混合策略
(3)生成:llama.cpp加载GGUF模型
(4)交互:Gradio快速搭建界面
三、部署sentence-transformers/all-MiniLM-L6-v2模型
1. 安装必要的python依赖
# 安装核心库
pip install sentence-transformers transformers torch
# 安装文档处理工具
pip install pypdf python-docx langchain chromadb
以上可能是部分,可以在调试过程中看到还有哪些缺少的依赖项,再安装。
2. 创建项目目录结构
可以直接在D盘创建一个文件夹my_deepseek_project,再按下面的结构进行设置多层文件夹。DeepSeek基于DeepSeek-R1-1.5B.gguf的RAG微调项目完整文件包,包括了DeepSeek-R1-Distill-Qwen-1.5B-GGUF、sentence-transformers/all-MiniLM-L6-v2模型和训练文档。完整项目文件有2.5G,有需要的可以联系我。
my_deepseek_project/
├── models/
│ ├── deepseek/ # 存放DeepSeek GGUF模型文件
│ └── st-minilm/ # 存放sentence-transformers模型
├── chroma_db/ # 向量数据库存储
└── docs/ # 知识库文档存放处
在个人windows电脑上安装DeepSeek大模型(完整详细可用教程)-CSDN博客。我设置的项目目录是直接在D盘根目录下,所以要修改一下。
(1)剪切D盘根目录下的DeepSeek-R1-Distill-Qwen-1.5B-Q8_0.gguf和Modelfile到D:\my_deepseek_project\models\deepseek目录下。
(2)修改Modelfile文件中的路径,如下图所示。
(3)打开终端或命令行界面,进入D:\my_deepseek_project\models\deepseek,运行以下命令来重新创建Ollama模型:
ollama create my_model_name -f Modelfile
3. 下载sentence-transformers模型到本地
(1)(不推荐)创建一个python文件,如download_sentence-transformers.py。python代码如下:
from sentence_transformers import SentenceTransformer# 下载模型到指定目录model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")model.save("D:/my_deepseek_project/models/st-minilm")
CMD执行“py 再将download_sentence-transformers.py拖进去”执行。
这种可能会因为访问https://huggingface.co而无法下载,推荐使用下一种方法。
(2)CMD在魔塔社区下载(推荐)
先安装魔塔社区:pip install modelscope
在从魔塔社区下载:
modelscope download --model sentence-transformers/all-MiniLM-L6-v2
下载的模型文件都是在C盘下,C:\Users\lzm07\.cache\modelscope\hub\sentence-transformers\all-MiniLM-L6-v2。接下来将下载好的整个sentence-transformers文件夹剪接到我们设定好的项目目录D:\my_deepseek_project\models\st-minilm中。
4. 验证模型文件结构
确认D:/my_deepseek_project/models目录包含以下文件:
models/st-minilm/sentence-transformers/all-MiniLM-L6-v2
├── config.json
├── pytorch_model.bin
├── sentence_bert_config.json
├── tokenizer_config.json
└── vocab.txt
四、基于GGUF的轻量级调优之检索增强生成(RAG)
RAG核心流程:(1)知识库构建 → (2)检索相关文档 → (3)增强提示输入 → (4)生成最终回答。以下是分步实现方案:
1.本地知识库构建
向量数据库:ChromaDB(轻量级,支持本地运行)
文本嵌入模型:Sentence Transformers(离线使用all-MiniLM-L6-v2)
关键参数配置表
组件 | 参数 | 推荐值 | 说明 |
文本分块 | chunk_size | 512字符 | 平衡上下文完整性与检索效率 |
chunk_overlap | 50字符 | 防止信息割裂 | |
嵌入模型 | model_name | all-MiniLM-L6-v2 | 轻量级多语言模型 |
向量数据库 | persist_directory | ./chroma_db | 本地存储路径 |
混合检索 | weights | [0.4, 0.6] | BM25与向量检索权重比 |
(1)数据准备与格式转换
支持文档类型:
1)文本类:TXT、Markdown、HTML、JSON
2)办公文档:PDF(需OCR处理扫描件)、Word(.docx)、PowerPoint
3)代码:Python、Java等源代码文件
4)结构化数据:CSV、Excel(需转换为文本)
在确保本机上已经安装python的情况下,顺序安装python依赖项:langchain、langchain_community。如果使用清华镜像安装的命令为:pip install --extra-index-url https://pypi.tuna.tsinghua.edu.cn/simple langchain langchain_community。确保要全部安装成功。
还要安装python依赖:pip install pypdf python-docx pandas
python代码示例(完整代码在后面):
# 统一转换为纯文本from pathlib import Pathfrom langchain.document_loaders import (PyPDFLoader, # PDFDocx2txtLoader, # WordTextLoader, # TXTCSVLoader # CSV)# 加载本地文档def load_documents(directory):docs = []for ext in ["*.pdf", "*.docx", "*.txt", "*.csv"]:for file in Path(directory).glob(ext):if ext == "*.pdf":loader = PyPDFLoader(str(file))elif ext == "*.docx":loader = Docx2txtLoader(str(file))elif ext == "*.txt":loader = TextLoader(str(file))elif ext == "*.csv":loader = CSVLoader(str(file))docs.extend(loader.load())return docs
(2)文本分块与清洗
分块策略:
递归字符分割:按段落、句号、换行符分块
重叠窗口:保留相邻块的部分重叠以防信息割裂
Python代码示例:
from langchain.text_splitter import RecursiveCharacterTextSplitter# 文本分块text_splitter = RecursiveCharacterTextSplitter(chunk_size=512, # 每块约500字符chunk_overlap=50, # 块间重叠50字符separators=["\n\n", "\n", "。", "?", "!"] # 中文友好分隔符)# 执行分块split_docs = text_splitter.split_documents(documents)
清洗步骤:
去噪:移除特殊字符(如\x00)、乱码
标准化:统一全角/半角符号、繁体转简体
关键信息提取:保留标题、章节结构元数据
Python代码示例:
import refrom zhconv import convert # 中文繁简转换# 清洗文本def clean_text(text):# 移除不可见字符text = re.sub(r'[\x00-\x1F\x7F-\x9F]', '', text)# 繁体转简体text = convert(text, 'zh-cn')# 合并连续空白text = re.sub(r'\s+', ' ', text)return text.strip()for doc in split_docs:doc.page_content = clean_text(doc.page_content)
(3)向量化与本地存储
嵌入模型选择:
轻量级本地模型:sentence-transformers/all-MiniLM-L6-v2(适用于中英文)
高性能本地模型:BAAI/bge-small-zh-v1.5(专为中文优化)
向量数据库选型:
ChromaDB:轻量级、纯Python实现,适合快速本地部署
FAISS:Facebook开发的高效相似性搜索库,支持GPU加速
1)安装必要的库
首先,确保安装了chromadb、sentence-transformers和transformers库。运行以下命令:
pip install chromadb sentence-transformers transformers
2)下载并加载 all-MiniLM-L6-v2 模型
all-MiniLM-L6-v2 模型可以从知识库中检索相关信息,用于将文本嵌入到向量空间中,以便进行相似性检索。使用 sentence-transformers 库加载模型。
Python代码示例(ChromaDB):
from langchain.embeddings import HuggingFaceEmbeddingsfrom langchain.vectorstores import Chroma# 初始化嵌入模型(离线模式)embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2", #更换成本地模型model_kwargs={'device': 'cpu'}, # 无GPU时使用CPUencode_kwargs={'normalize_embeddings': True})# 创建向量库vector_db = Chroma.from_documents(documents=split_docs,embedding=embeddings,persist_directory="./chroma_db" # 本地存储路径)vector_db.persist() # 确保持久化
2.检索器配置
(1)元数据增强检索
为每个文本块添加结构化元数据,提升检索精度:
python代码示例:
# 示例:从文件名提取文档类别for doc in split_docs:source = doc.metadata['source']if "技术文档" in source:doc.metadata["category"] = "技术"elif "产品手册" in source:doc.metadata["category"] = "产品"else:doc.metadata["category"] = "通用"# 检索时过滤类别retriever = vector_db.as_retriever(search_kwargs={"filter": {"category": "技术"}})(2)检索策略优化混合检索方案:向量相似性检索:基于语义匹配关键词检索(BM25):基于精确术语匹配python代码示例:from langchain.retrievers import BM25Retriever, EnsembleRetriever# 向量检索vector_retriever = vector_db.as_retriever(search_kwargs={"k": 3})# 关键词检索bm25_retriever = BM25Retriever.from_documents(split_docs)bm25_retriever.k = 2# 混合检索器ensemble_retriever = EnsembleRetriever(retrievers=[bm25_retriever, vector_retriever],weights=[0.4, 0.6])(3)知识库更新与维护增量更新脚本:python代码示例:def update_knowledge_base(new_docs, vector_db_path):# 加载现有库existing_db = Chroma(persist_directory=vector_db_path,embedding_function=embeddings)# 处理新文档new_split_docs = text_splitter.split_documents(new_docs)existing_db.add_documents(new_split_docs)existing_db.persist()
完整的python代码如下(在上面代码基础上稍有修改):
# 安装必要依赖(如果尚未安装)
# pip install pypdf python-docx langchain sentence-transformers chromadb zhconv docx2txt rank_bm25from pathlib import Path
from langchain.document_loaders import (PyPDFLoader, # PDFDocx2txtLoader, # WordTextLoader, # TXTCSVLoader # CSV
)
from langchain.text_splitter import RecursiveCharacterTextSplitter
import re
from zhconv import convert # 中文繁简转换
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
from langchain.retrievers import BM25Retriever, EnsembleRetriever# ----------------------
# 核心函数定义部分
# ----------------------def load_documents(directory: str):"""加载指定目录下的文档"""docs = []directory_path = Path(directory)# 支持的扩展名映射表loader_mapping = {".pdf": PyPDFLoader,".docx": Docx2txtLoader,".txt": TextLoader,".csv": CSVLoader}# 遍历目录下所有文件for file_path in directory_path.glob("*"):if file_path.suffix.lower() in loader_mapping:try:loader_class = loader_mapping[file_path.suffix.lower()]loader = loader_class(str(file_path))docs.extend(loader.load())print(f"成功加载文件:{file_path.name}")except Exception as e:print(f"加载文件 {file_path.name} 失败:{str(e)}")continuereturn docsdef clean_text(text: str) -> str:"""文本清洗处理"""# 移除不可见字符text = re.sub(r'[\x00-\x1F\x7F-\x9F]', '', text)# 繁体转简体text = convert(text, 'zh-cn')# 合并连续空白text = re.sub(r'\s+', ' ', text)return text.strip()def init_knowledge_base(data_dir: str = "D:/my_deepseek_project/docs", persist_dir: str = "D:/my_deepseek_project/chroma_db"):"""初始化知识库"""# 1. 加载文档raw_documents = load_documents(data_dir)if not raw_documents:raise ValueError("未找到可处理的文档,请检查目录和文件格式")# 2. 文本分块text_splitter = RecursiveCharacterTextSplitter(chunk_size=512,chunk_overlap=50,separators=["\n\n", "\n", "。", "?", "!"])# 新增:保存分块后的文档列表global split_docs # 用于后续检索器初始化split_docs = text_splitter.split_documents(raw_documents)# 3. 清洗文本for doc in split_docs:doc.page_content = clean_text(doc.page_content)# 添加元数据(示例:从文件名提取类别)if "技术" in doc.metadata["source"]:doc.metadata["category"] = "技术"elif "产品" in doc.metadata["source"]:doc.metadata["category"] = "产品"else:doc.metadata["category"] = "通用"# 4. 创建向量存储embeddings = HuggingFaceEmbeddings(model_name=r"D:\my_deepseek_project\models\st-minilm\sentence-transformers\all-MiniLM-L6-v2",model_kwargs={'device': 'cpu'},encode_kwargs={'normalize_embeddings': True})vector_db = Chroma.from_documents(documents=split_docs,embedding=embeddings,persist_directory=persist_dir)vector_db.persist()return vector_dbdef get_retriever(vector_db, use_ensemble: bool = True):"""获取检索器"""# 向量检索vector_retriever = vector_db.as_retriever(search_kwargs={"k": 3})if use_ensemble:# 修正:使用原始Document对象初始化BM25bm25_retriever = BM25Retriever.from_documents(split_docs) # 直接使用预处理的分块文档bm25_retriever.k = 2# 混合检索return EnsembleRetriever(retrievers=[bm25_retriever, vector_retriever],weights=[0.4, 0.6])else:return vector_retrieverdef update_knowledge_base(new_data_dir: str, vector_db_path: str = "D:/my_deepseek_project/chroma_db"):"""更新知识库"""# 加载现有库,指定本地模型路径embeddings = HuggingFaceEmbeddings(model_name=r"D:\my_deepseek_project\models\st-minilm\sentence-transformers\all-MiniLM-L6-v2", # Windows路径格式model_kwargs={'device': 'cpu'} # 无GPU时使用CPU)existing_db = Chroma(persist_directory=vector_db_path,embedding_function=embeddings)# 处理新文档new_docs = load_documents(new_data_dir)if not new_docs:print("未找到新文档可添加")returntext_splitter = RecursiveCharacterTextSplitter(chunk_size=512,chunk_overlap=50)new_split_docs = text_splitter.split_documents(new_docs)# 清洗和添加元数据for doc in new_split_docs:doc.page_content = clean_text(doc.page_content)doc.metadata["category"] = "new" # 标记为新添加existing_db.add_documents(new_split_docs)existing_db.persist()print(f"成功添加 {len(new_split_docs)} 个新文档块")# ----------------------
# 主程序执行部分
# ----------------------
if __name__ == "__main__":# 初始化知识库try:vector_db = init_knowledge_base()print("知识库初始化完成")except Exception as e:print(f"知识库初始化失败:{str(e)}")exit(1)# 获取检索器retriever = get_retriever(vector_db)print("检索器初始化成功!")# 示例检索sample_query = "请解释量子计算的基本原理"docs = retriever.get_relevant_documents(sample_query)print(f"检索到 {len(docs)} 条相关文档")# 更新知识库示例(需要时取消注释)# update_knowledge_base("D:/my_deepseek_project/new_docs")
使用说明:
(1)将自己的文档放入 D:/my_deepseek_project/docs 目录(支持PDF/Word/TXT/CSV)
(2)运行脚本完成初始化:python rag_pipeline.py
(3)后续添加新文档:
1)将新文档放入 D:/Dmy_deepseek_project/new_docs 目录
2)取消注释最后一行 update_knowledge_base("D:/my_deepseek_project/new_docs")
在CMD中运行结果如下
3.集成DeepSeek模型与RAG
(1)说明
1)准备RAG微调的数据
RAG(Retrieval-Augmented Generation)需要两个主要部分:
Retriever:用于从知识库中检索相关信息。
Generator:用于生成文本。
all-MiniLM-L6-v2 模型可以作为 Retriever,用于将文本嵌入到向量空间中,以便进行相似性检索。
2)配置RAG模型
我们前文已经部署了DeepSeek R1 1.5模型,可以使用transformers库中的RagTokenizer和RagRetriever来配置RAG模型。
3)微调RAG模型
微调RAG模型需要准备训练数据,并使用Trainer或TrainingArguments进行训练。
(2)实现步骤:
1)配置GGUF模型加载
from llama_cpp import Llama# 加载DeepSeek模型deepseek = Llama(model_path=r"D:\my_deepseek_project\models\deepseek\DeepSeek-R1-Distill-Qwen-1.5B-Q8_0.gguf",n_ctx=2048,n_gpu_layers=20 # GPU加速层数(根据显存调整))
2)实现RAG问答链
def rag_query(question: str, top_k: int = 3):# 1. 检索相关文档retriever = vector_db.as_retriever(search_kwargs={"k": top_k})context_docs = retriever.get_relevant_documents(question)context = "\n".join([doc.page_content for doc in context_docs])# 2. 构建增强提示prompt = f"""基于以下上下文:{context}---问题:{question}请给出详细回答:"""# 3. 生成回答response = deepseek.create_chat_completion(messages=[{"role": "user", "content": prompt}],max_tokens=512,temperature=0.3)return response['choices'][0]['message']['content']
3)强制禁用网络访问(可以不用)
import osos.environ["TRANSFORMERS_OFFLINE"] = "1" # 禁用HF Hubos.environ["LLAMA_NO_HTTP"] = "1" # 禁用llama.cpp的网络
4)测试问答流程
question = "候鸟优化算法是什么?"answer = rag_query(question)print(f"问题:{question}\n回答:{answer}")
将以上代码全部放到前面的python文件中的最后,就可以CMD运行了。以下也是全文的完整python代码:
# 安装必要依赖(如果尚未安装)
# pip install pypdf python-docx langchain sentence-transformers chromadb zhconv docx2txt rank_bm25from pathlib import Path
from langchain.document_loaders import (PyPDFLoader, # PDFDocx2txtLoader, # WordTextLoader, # TXTCSVLoader # CSV
)
from langchain.text_splitter import RecursiveCharacterTextSplitter
import re
from zhconv import convert # 中文繁简转换
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
from langchain.retrievers import BM25Retriever, EnsembleRetriever# ----------------------
# 核心函数定义部分
# ----------------------def load_documents(directory: str):"""加载指定目录下的文档"""docs = []directory_path = Path(directory)# 支持的扩展名映射表loader_mapping = {".pdf": PyPDFLoader,".docx": Docx2txtLoader,".txt": TextLoader,".csv": CSVLoader}# 遍历目录下所有文件for file_path in directory_path.glob("*"):if file_path.suffix.lower() in loader_mapping:try:loader_class = loader_mapping[file_path.suffix.lower()]loader = loader_class(str(file_path))docs.extend(loader.load())print(f"成功加载文件:{file_path.name}")except Exception as e:print(f"加载文件 {file_path.name} 失败:{str(e)}")continuereturn docsdef clean_text(text: str) -> str:"""文本清洗处理"""# 移除不可见字符text = re.sub(r'[\x00-\x1F\x7F-\x9F]', '', text)# 繁体转简体text = convert(text, 'zh-cn')# 合并连续空白text = re.sub(r'\s+', ' ', text)return text.strip()def init_knowledge_base(data_dir: str = "D:/my_deepseek_project/docs", persist_dir: str = "D:/my_deepseek_project/chroma_db"):"""初始化知识库"""# 1. 加载文档raw_documents = load_documents(data_dir)if not raw_documents:raise ValueError("未找到可处理的文档,请检查目录和文件格式")# 2. 文本分块text_splitter = RecursiveCharacterTextSplitter(chunk_size=512,chunk_overlap=50,separators=["\n\n", "\n", "。", "?", "!"])# 新增:保存分块后的文档列表global split_docs # 用于后续检索器初始化split_docs = text_splitter.split_documents(raw_documents)# 3. 清洗文本for doc in split_docs:doc.page_content = clean_text(doc.page_content)# 添加元数据(示例:从文件名提取类别)if "技术" in doc.metadata["source"]:doc.metadata["category"] = "技术"elif "产品" in doc.metadata["source"]:doc.metadata["category"] = "产品"else:doc.metadata["category"] = "通用"# 4. 创建向量存储embeddings = HuggingFaceEmbeddings(model_name=r"D:\my_deepseek_project\models\st-minilm\sentence-transformers\all-MiniLM-L6-v2",model_kwargs={'device': 'cpu'},encode_kwargs={'normalize_embeddings': True})vector_db = Chroma.from_documents(documents=split_docs,embedding=embeddings,persist_directory=persist_dir)vector_db.persist()return vector_dbdef get_retriever(vector_db, use_ensemble: bool = True):"""获取检索器"""# 向量检索vector_retriever = vector_db.as_retriever(search_kwargs={"k": 3})if use_ensemble:# 修正:使用原始Document对象初始化BM25bm25_retriever = BM25Retriever.from_documents(split_docs) # 直接使用预处理的分块文档bm25_retriever.k = 2# 混合检索return EnsembleRetriever(retrievers=[bm25_retriever, vector_retriever],weights=[0.4, 0.6])else:return vector_retrieverdef update_knowledge_base(new_data_dir: str, vector_db_path: str = "D:/my_deepseek_project/chroma_db"):"""更新知识库"""# 加载现有库,指定本地模型路径embeddings = HuggingFaceEmbeddings(model_name=r"D:\my_deepseek_project\models\st-minilm\sentence-transformers\all-MiniLM-L6-v2", # Windows路径格式model_kwargs={'device': 'cpu'} # 无GPU时使用CPU)existing_db = Chroma(persist_directory=vector_db_path,embedding_function=embeddings)# 处理新文档new_docs = load_documents(new_data_dir)if not new_docs:print("未找到新文档可添加")returntext_splitter = RecursiveCharacterTextSplitter(chunk_size=512,chunk_overlap=50)new_split_docs = text_splitter.split_documents(new_docs)# 清洗和添加元数据for doc in new_split_docs:doc.page_content = clean_text(doc.page_content)doc.metadata["category"] = "new" # 标记为新添加existing_db.add_documents(new_split_docs)existing_db.persist()print(f"成功添加 {len(new_split_docs)} 个新文档块")# ----------------------
# 主程序执行部分
# ----------------------
if __name__ == "__main__":# 初始化知识库try:vector_db = init_knowledge_base()print("知识库初始化完成")except Exception as e:print(f"知识库初始化失败:{str(e)}")exit(1)# 获取检索器retriever = get_retriever(vector_db)print("检索器初始化成功!")# 示例检索sample_query = "请解释量子计算的基本原理"docs = retriever.get_relevant_documents(sample_query)print(f"检索到 {len(docs)} 条相关文档")# 更新知识库示例(需要时取消注释)# update_knowledge_base("D:/my_deepseek_project/new_docs")#以下是集成DeepSeek模型与RAG
from llama_cpp import Llama# 加载DeepSeek模型
deepseek = Llama(model_path=r"D:\my_deepseek_project\models\deepseek\DeepSeek-R1-Distill-Qwen-1.5B-Q8_0.gguf",n_ctx=2048,n_gpu_layers=20 # GPU加速层数(根据显存调整)
)
def rag_query(question: str, top_k: int = 3):# 1. 检索相关文档retriever = vector_db.as_retriever(search_kwargs={"k": top_k})context_docs = retriever.get_relevant_documents(question)context = "\n".join([doc.page_content for doc in context_docs])# 2. 构建增强提示prompt = f"""基于以下上下文:
{context}
---
问题:{question}
请给出详细回答:"""# 3. 生成回答response = deepseek.create_chat_completion(messages=[{"role": "user", "content": prompt}],max_tokens=512,temperature=0.3)return response['choices'][0]['message']['content']import os
os.environ["TRANSFORMERS_OFFLINE"] = "1" # 禁用HF Hub
os.environ["LLAMA_NO_HTTP"] = "1" # 禁用llama.cpp的网络# 示例查询
question = "候鸟优化算法是什么?"
answer = rag_query(question)
print(f"问题:{question}\n回答:{answer}")
CMD运行结果如下:
五、总结与建议
针对deepseek模型的微调还是原生训练,总结如下:
场景 | 推荐方案 | 可行性 |
直接训练模型 | 使用原始PyTorch模型文件 | ✅ |
快速适配模型行为 | 提示工程/RAG | ✅ |
必须基于GGUF的轻量级调整 | 转换为PyTorch格式(如支持)或使用外部增强 | x |
最终建议:
(1)优先使用原始PyTorch模型:确保文件完整(config.json + pytorch_model.bin)。
(2)离线加载配置,python代码如下:
from transformers import AutoModelmodel = AutoModel.from_pretrained("./local/model_dir",local_files_only=True # 强制离线模式)
(3)避免依赖GGUF训练:除非有特殊工具链支持,否则GGUF不适合训练场景。
直接在原始PyTorch模型文件下训练deepseek模型,请看我之后的文档哦!