本文将向你展示如何使用DeepSeek R1(一种开源推理工具)和Ollama(一个用于运行本地AI模型的轻量级框架)构建检索增强生成(RAG)系统。
使用Apidog简化API测试
想要简化你的API工作流程吗?Apidog是一个集创建、管理和运行测试以及模拟服务器于一体的解决方案。使用Apidog,你可以:
为什么选择DeepSeek R1?
DeepSeek R1是一款与OpenAI的o1相媲美的模型,但成本降低了95%,正在彻底改变RAG系统。开发者喜欢它的以下特点:
构建本地RAG系统所需工具
Ollama
Ollama允许你在本地运行像DeepSeek R1这样的模型。
ollama run deepseek-r1 # For the 7B model (default)
DeepSeek R1模型变体
DeepSeek R1的参数范围从15亿到671亿不等。对于轻量级的RAG应用,可以从15亿参数的模型开始。
ollama run deepseek-r1:1.5b
注意:更大的模型(例如700亿参数的模型)具有更好的推理能力,但需要更多的内存。
构建RAG管道的分步指南
步骤1:导入库
我们将使用:
import streamlit as st
from langchain_community.document_loaders import PDFPlumberLoader
from langchain_experimental.text_splitter import SemanticChunker
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.llms import Ollama
步骤2:上传并处理PDF文件
利用Streamlit的文件上传功能选择本地PDF文件。使用PDFPlumberLoader高效地提取文本,无需手动解析。
# Streamlit file uploader
uploaded_file = st.file_uploader("Upload a PDF file", type="pdf")
if uploaded_file:
# Save PDF temporarily
with open("temp.pdf", "wb") as f:
f.write(uploaded_file.getvalue())
# Load PDF text
loader = PDFPlumberLoader("temp.pdf")
docs = loader.load()
步骤3:策略性地拆分文档
利用Streamlit的文件上传功能选择本地PDF文件。使用PDFPlumberLoader高效地提取文本,无需手动解析。
# Split text into semantic chunks
text_splitter = SemanticChunker(HuggingFaceEmbeddings())
documents = text_splitter.split_documents(docs)
步骤4:创建可搜索的知识库
为文档块生成向量嵌入,并将它们存储在FAISS索引中。
嵌入允许进行快速、上下文相关的搜索。
# Generate embeddings
embeddings = HuggingFaceEmbeddings()
vector_store = FAISS.from_documents(documents, embeddings)
# Connect retriever
retriever = vector_store.as_retriever(search_kwargs={"k": 3}) # Fetch top 3 chunks
步骤5:配置DeepSeek R1
使用DeepSeek R1 1.5B模型设置一个检索问答(RetrievalQA)链。
这确保了答案基于PDF的内容,而不是依赖模型的训练数据。
llm = Ollama(model="deepseek-r1:1.5b") # Our 1.5B parameter model
# Craft the prompt template
prompt = """
1. Use ONLY the context below.
2. If unsure, say "I don’t know".
3. Keep answers under 4 sentences.
Context: {context}
Question: {question}
Answer:
"""
QA_CHAIN_PROMPT = PromptTemplate.from_template(prompt)
步骤6:组装RAG链
将上传、拆分和检索集成到一个连贯的管道中。
这种方法为模型提供了经过验证的上下文,从而提高了准确性。
# Chain 1: Generate answers
llm_chain = LLMChain(llm=llm, prompt=QA_CHAIN_PROMPT)
# Chain 2: Combine document chunks
document_prompt = PromptTemplate(
template="Context:\ncontent:{page_content}\nsource:{source}",
input_variables=["page_content", "source"]
)
# Final RAG pipeline
qa = RetrievalQA(
combine_documents_chain=StuffDocumentsChain(
llm_chain=llm_chain,
document_prompt=document_prompt
),
retriever=retriever
)
步骤7:启动网页界面
启动网页界面
Streamlit使用户能够输入问题并即时获得答案。
查询会检索匹配的文档块,将它们输入到模型中,并实时显示结果。
# Streamlit UI
user_input = st.text_input("Ask your PDF a question:")
if user_input:
with st.spinner("Thinking..."):
response = qa(user_input)["result"]
st.write(response)