文章目录
前言
本文主要涵盖Deepseek在ubuntu系统中的部署全流程,包括模型的下载、系统部署、本地文档向量化、向量列表存储、RAG知识库挂载、对话测试等内容
一、Deepseek模型下载(以7B为例)
说明:以下安装步骤仅限于你的服务器可以ping 通huggingface.co,如果无法ping通请参考我上一篇博客 :《【deepseek】Ubuntu/centos系统中无法直接git clone下载模型的解决方法》
1. 安装 huggingface_hub
(如果尚未安装):
首先,确保已经安装了 huggingface_hub
Python 包,它是 Hugging Face CLI 的依赖项。
bash
pip install huggingface_hub
2. 登录 Hugging Face:
使用 huggingface-cli login
命令登录你的 Hugging Face 账号。
bash
huggingface-cli login

该命令会提示你输入你的 Hugging Face 账号的 token。 你可以在 Hugging Face 网站上找到你的 token:
- 访问 https://huggingface.co/settings/tokens
- 创建一个新的 token (如果还没有)。
- 复制 token 并粘贴到终端中。
3. 安装 Git LFS (如果尚未安装):
Git LFS (Large File Storage) 用于处理大型文件,例如模型文件。
bash
sudo apt-get update
sudo apt-get install git-lfs
git lfs install
4. 克隆模型仓库:
使用 git clone
命令克隆模型仓库。
bash
git clone https://huggingface.co/deepseek-ai/deepseek-llm-7b-chat
这会将 deepseek-llm-7b-chat
模型仓库克隆到你的本地目录。
5. 下载模型文件:
进入克隆的目录:
bash
cd deepseek-llm-7b-chat
如果模型文件没有自动下载,可以使用以下命令手动下载:
bash
git lfs pull
完整步骤:
bash
# 1. 安装 huggingface_hub (如果尚未安装)
pip install huggingface_hub
# 2. 登录 Hugging Face
huggingface-cli login
# 3. 安装 Git LFS (如果尚未安装)
sudo apt-get update
sudo apt-get install git-lfs
git lfs install
# 4. 克隆模型仓库
git clone https://huggingface.co/deepseek-ai/deepseek-llm-7b-chat
# 5. 下载模型文件
cd deepseek-llm-7b-chat
git lfs pull
二、RAG本地知识库挂载
系统基本环境:Ubuntu 22.04.4 LTS
Python版本:3.10
1.安装必要的库
bash
pip install langchain transformers sentence-transformers faiss-cpu unstructured pdf2image python-docx docx2txt
langchain
: 用于构建 RAG 流程。transformers
: 用于加载 DeepSeek 7B 模型。sentence-transformers
: 用于生成文本嵌入 (embeddings)。faiss-cpu
: 用于存储和检索文本嵌入 (向量数据库)。unstructured
: 用于加载各种文档 (text, pdf, word)。pdf2image
: PDF 处理依赖。python-docx
: Word 文档处理依赖。docx2txt
: txt文档处理依赖。
2.加载文档并创建向量数据库
create_vector_db.py
python
import os
from langchain.document_loaders import TextLoader, PyPDFLoader, Docx2txtLoader, UnstructuredFileLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
from tqdm import tqdm
DATA_PATH = "data/" # 你的知识库文档所在的目录
DB_FAISS_PATH = "vectorstore/db_faiss" # 向量数据库保存路径
def create_vector_db():
"""
加载文档,切分文本,生成 embeddings 并存储到 FAISS 向量数据库中。
"""
document_paths = []
for root, _, files in os.walk(DATA_PATH):
for file in files:
file_path = os.path.join(root, file)
document_paths.append(file_path)
documents = []
for doc_path in tqdm(document_paths, desc="加载文档"):
try:
if doc_path.endswith(".txt"):
loader = TextLoader(doc_path, encoding="utf-8")
elif doc_path.endswith(".pdf"):
loader = PyPDFLoader(doc_path) # 使用 PyPDFLoader
elif doc_path.endswith(".docx") or doc_path.endswith(".doc"):
try:
loader = Docx2txtLoader(doc_path)
except ImportError:
print(f"docx2txt 未安装,尝试使用 UnstructuredFileLoader 加载 {doc_path}")
loader = UnstructuredFileLoader(doc_path)
else:
loader = UnstructuredFileLoader(doc_path) # 尝试使用通用加载器
documents.extend(loader.load())
except Exception as e:
print(f"加载文档 {doc_path} 失败: {e}")
print(f"加载的文档数量: {len(documents)}")
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
texts = text_splitter.split_documents(documents)
print(f"分割后的文本块数量: {len(texts)}")
# 过滤掉空文本块
texts = [text for text in texts if text.page_content.strip()]
# 打印文本块内容
# for i, text in enumerate(texts):
# print(f"文本块 {i}: {text.page_content}")
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
model_kwargs={'device': 'cuda' if torch.cuda.is_available() else 'cpu'})
db = FAISS.from_documents(texts, embeddings)
db.save_local(DB_FAISS_PATH)
if __name__ == "__main__":
import torch
create_vector_db()
print("向量数据库创建完成!")
DATA_PATH
: 替换为你的本地知识库文档所在的目录。DB_FAISS_PATH
: 指定向量数据库的保存路径。- 文档加载 : 使用
TextLoader
,PDFLoader
,Docx2txtLoader
,UnstructuredFileLoader
加载不同类型的文档。UnstructuredFileLoader
可以处理更多类型的文档,但可能需要安装额外的依赖。 - 文本切分 : 使用
RecursiveCharacterTextSplitter
将文档切分成小的文本块 (chunks)。chunk_size
和chunk_overlap
可以根据你的需求调整。 - Embeddings : 使用
HuggingFaceEmbeddings
生成文本块的 embeddings。sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2
是一个常用的多语言 embedding 模型。 也可以选择其他模型。 - 向量数据库 : 使用
FAISS
存储 embeddings。FAISS
是一个高效的向量相似度搜索库。
三、创建本地对话脚本
chat_rag.py
python
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains import RetrievalQA
MODEL_PATH = "./deepseek-llm-7b-chat" # 你的模型路径
DB_FAISS_PATH = "vectorstore/db_faiss" # 向量数据库路径
def load_model():
"""加载模型和 tokenizer"""
tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH)
model = AutoModelForCausalLM.from_pretrained(MODEL_PATH, device_map="auto", torch_dtype=torch.float16)
return model, tokenizer
def load_vector_db():
"""加载 FAISS 向量数据库"""
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
model_kwargs={'device': 'cuda' if torch.cuda.is_available() else 'cpu'})
db = FAISS.load_local(DB_FAISS_PATH, embeddings, allow_dangerous_deserialization=True) # 添加 allow_dangerous_deserialization=True
return db
def create_rag_chain(model, tokenizer, db):
"""创建 RAG 链"""
qa_chain = RetrievalQA.from_chain_type(
llm=model, # 这里的 llm 需要适配 langchain 的接口,需要做转换
chain_type="stuff", # "stuff" 是最简单的 chain_type, 适合小文档
retriever=db.as_retriever(search_kwargs={'k': 3}), # 从向量数据库中检索最相关的 3 个文档
return_source_documents=True, # 返回源文档
chain_type_kwargs={"prompt": prompt} # 使用自定义 prompt
)
return qa_chain
def generate_response(qa_chain, query):
"""生成回复"""
response = qa_chain({"query": query})
return response["result"], response["source_documents"]
# 自定义 Prompt
from langchain.prompts import PromptTemplate
prompt_template = """使用以下上下文来回答最后的问题。如果你不知道答案,就说你不知道,不要试图编造答案。
上下文:{context}
问题:{question}
有用的回答:"""
prompt = PromptTemplate(
template=prompt_template, input_variables=["context", "question"]
)
if __name__ == "__main__":
model, tokenizer = load_model()
db = load_vector_db()
# 适配 langchain 的 llm 接口
from langchain.llms import HuggingFacePipeline
from transformers import pipeline
pipe = pipeline("text-generation",
model=model,
tokenizer=tokenizer,
torch_dtype=torch.float16,
device_map="auto",
max_new_tokens=256,
do_sample=True,
top_p=0.9,
temperature=0.7,
num_return_sequences=1)
llm = HuggingFacePipeline(pipeline=pipe)
qa_chain = create_rag_chain(llm, tokenizer, db)
print("欢迎使用 DeepSeek 7B Chat (RAG)!")
print("输入 'exit' 退出对话。")
while True:
user_input = input("你: ")
if user_input.lower() == "exit":
print("感谢使用,再见!")
break
try:
response, source_documents = generate_response(qa_chain, user_input)
print("DeepSeek: " + response)
print("\n来源文档:")
for doc in source_documents:
print(f" - {doc.metadata['source']}")
except Exception as e:
print(f"发生错误: {e}")
print("请检查你的输入和模型是否正确加载。")
MODEL_PATH
: 替换为你的 DeepSeek 7B 模型路径。DB_FAISS_PATH
: 替换为你的向量数据库路径。load_model()
: 加载 DeepSeek 7B 模型和 tokenizer。load_vector_db()
: 加载 FAISS 向量数据库。create_rag_chain()
: 创建 RAG 链。RetrievalQA.from_chain_type()
: 使用 LangChain 的RetrievalQA
类创建 RAG 链。chain_type="stuff"
: 指定 chain type。 "stuff" 是最简单的 chain type,它将所有检索到的文档都塞到 prompt 中。 适合小文档。对于大文档,可以考虑使用 "map_reduce" 或 "refine" 等 chain type。retriever
: 使用db.as_retriever()
创建 retriever。search_kwargs={'k': 3}
表示从向量数据库中检索最相关的 3 个文档。return_source_documents=True
: 返回源文档。
generate_response()
: 生成回复。- 自定义 Prompt : 使用
PromptTemplate
自定义 Prompt,让模型更好地利用上下文信息。 - 适配 langchain 的 llm 接口 : 由于
RetrievalQA
需要 langchain 风格的 llm 接口,所以需要用HuggingFacePipeline
包装一下transformers
的pipeline
。 - 打印源文档: 在回复中打印源文档,方便验证信息的来源。
其他: 准备知识库文档
- 创建一个名为
data
的目录 (或者修改DATA_PATH
变量)。 - 将你的 text, pdf, word 文档放到
data
目录中。
四、结果展示
-
首先运行
create_vector_db.py
创建向量数据库。
-
然后运行
chat_rag.py
启动对话进行测试。
问:
答: