基于SambaNova的DeepSeek-R1、Qdrant二进制量化以及LangGraph,实现了32倍内存缩减的一个构建快速RAG系统方案
猫头虎分享最近阅读的一个适合处理大量文件和数据的场景构建快速RAG系统方案,通过Qdrant的二进制量化技术,减少向量数据的内存占用, 结合SambaNova DeepSeek-R1的推理能力,快速响应并提供高质量答案。
摘要 本文结合 SambaNova Systems 的 DeepSeek-R1 强大推理能力、Qdrant 的二进制量化(Binary Quantization,BQ)技术,以及 LangGraph 的流程编排能力,打造一个高性能、低内存占用的多文档检索增强生成(RAG)系统。通过对向量数据进行 1 bit 极限压缩,并配合「先快速筛选、后精确重评分」策略,实现高维嵌入检索的高速响应与高质量答案。 使用SambaNova Systems的高性能DeepSeek-R1、Qdrant 的 二进制量化以及 LangGraph 的编排功能。
大家好,我是 猫头虎,AI全栈工程师,某科技公司CEO,猫头虎技术团队创始人,也被大家称为虎哥。我目前是COC北京城市开发者社区主理人、COC西安城市开发者社区主理人,以及云原生开发者社区主理人,在多个技术领域如云原生、前端、后端、运维和AI都有超多内容更新。
感谢全网三十多万粉丝的持续支持,我希望通过我的分享,帮助大家更好地掌握和使用各种技术产品,提升开发效率与体验。
本方案主要包含三大核心组件:
整体流程如下:
当面对数百万、乃至上亿条文档嵌入时,传统的 float32
向量(每维 4 Byte)带来的内存压力不可小觑。以常见的 1536 维 OpenAI 文本嵌入为例:
量化(Quantization)技术通过压缩向量分量,牺牲少量精度换取存储与计算效率。
float32
(32 bit)降为 1 bit。核心价值:
from qdrant_client import QdrantClient, models
client = QdrantClient(
url="http://localhost:6333",
prefer_grpc=True,
)
# 名称可自定义
collection_name = "binary-quantization"
if not client.collection_exists(collection_name):
client.create_collection(
collection_name=collection_name,
vectors_config=models.VectorParams(
size=1536, # 嵌入维度
distance=models.Distance.DOT, # 点积距离
on_disk=True, # 原始向量存磁盘
),
optimizers_config=models.OptimizersConfigDiff(
default_segment_number=5,
),
hnsw_config=models.HnswConfigDiff(
m=0, # HNSW 参数(示例)
),
quantization_config=models.BinaryQuantization(
binary=models.BinaryQuantizationConfig(always_ram=True),
),
)
else:
print("Collection 已存在")
on_disk=True
将 原始浮点向量 存储于磁盘,节省 RAMalways_ram=True
将 二进制向量 与索引常驻 RAM,实现极速检索pip install langgraph langchain langchain-community \
langchain-qdrant fastembed langchain-sambanova pypdf
from langchain_community.document_loaders import PyPDFDirectoryLoader
loader = PyPDFDirectoryLoader(
path="./data/",
glob="**/[!.]*.pdf",
extract_images=False,
mode="page",
extraction_mode="plain",
)
docs = loader.load()
# 清理换行与制表符
for d in docs:
d.page_content = d.page_content.replace("\n", " ").replace("\t", " ")
from langchain_community.embeddings import FastEmbedEmbeddings
from langchain_qdrant import QdrantVectorStore
embeddings = FastEmbedEmbeddings(model_name="thenlper/gte-large")
vector_store = QdrantVectorStore(
client=client,
collection_name=collection_name,
embedding=embeddings,
)
vector_store.add_documents(docs)
from langchain_sambanova import ChatSambaNovaCloud
from langgraph.graph import START, StateGraph
from langchain_core.documents import Document
from typing_extensions import TypedDict
# 定义状态结构
class State(TypedDict):
question: str
context: list[Document]
answer: str
# 初始化 LLM
import os
from google.colab import userdata
os.environ['SAMBANOVA_API_KEY'] = userdata.get("SAMBANOVA_API_KEY")
llm = ChatSambaNovaCloud(
model="DeepSeek-R1",
max_tokens=1024,
temperature=0.1,
top_p=0.01,
)
# 检索节点
def search(state: State):
docs = vector_store.max_marginal_relevance_search(state["question"])
return {"context": docs}
# 生成节点
SYSTEM_TEMPLATE = """…"""
HUMAN_TEMPLATE = """…"""
def generate(state: State):
ctx = "\n\n".join(
f"{d.page_content}\nMetadata: Source-{d.metadata['source']} Page-{d.metadata['page_label']}"
for d in state["context"]
)
messages = [
{"role": "system", "content": SYSTEM_TEMPLATE},
{"role": "user", "content": HUMAN_TEMPLATE.format(context_str=ctx, query=state["question"])},
]
resp = llm.invoke(messages)
return {"answer": resp.content}
# 组装图
graph_builder = StateGraph(State).add_sequence([search, generate])
graph_builder.add_edge(START, "search")
graph = graph_builder.compile()
# 执行示例
response = graph.invoke({"question": "如何快速进入工作状态?"})
print(response["answer"])
指标 | 原始 Float32 | Binary Quantization | 缩减倍数 |
---|---|---|---|
向量存储(1M) | 6 GB | 0.1875 GB | ≈32× |
检索响应时间(平均) | 150 ms | 30 ms | ≈5× |