人工智能
重新排序器和两阶段检索的强大功能用于检索增强生成

此代码片段演示了如何配置和使用 jina-colbert-v1-en 模型来索引文档集合,利用其有效处理长上下文的能力。
使用 Reranker 实施两阶段检索
现在我们已经了解了两阶段检索和重新排序背后的原理,让我们在 RAG 系统的背景下探索它们的实际实现。我们将利用流行的库和框架来演示这些技术的集成。
设置环境
在深入研究代码之前,让我们先设置开发环境。我们将使用 Python 和几个流行的 NLP 库,包括 Hugging Face Transformers、Sentence Transformers 和 LanceDB。
# Install required libraries !pip install datasets huggingface_hub sentence_transformers lancedb
资料准备
出于演示目的,我们将使用 Hugging Face Datasets 中的“ai-arxiv-chunked”数据集,其中包含 400 多篇关于机器学习、自然语言处理和大型语言模型的 ArXiv 论文。
from datasets import load_dataset dataset = load_dataset("jamescalam/ai-arxiv-chunked", split="train") <pre>
接下来,我们将预处理数据并将其分割成更小的块,以方便高效的检索和处理。
from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") def chunk_text(text, chunk_size=512, overlap=64): tokens = tokenizer.encode(text, return_tensors="pt", truncation=True) chunks = tokens.split(chunk_size - overlap) texts = [tokenizer.decode(chunk) for chunk in chunks] return texts chunked_data = [] for doc in dataset: text = doc["chunk"] chunked_texts = chunk_text(text) chunked_data.extend(chunked_texts)
在初始检索阶段,我们将使用 Sentence Transformer 模型将文档和查询编码为密集向量表示,然后使用 LanceDB 等向量数据库执行近似最近邻搜索。
from sentence_transformers import SentenceTransformer from lancedb import lancedb # Load Sentence Transformer model model = SentenceTransformer('all-MiniLM-L6-v2') # Create LanceDB vector store db = lancedb.lancedb('/path/to/store') db.create_collection('docs', vector_dimension=model.get_sentence_embedding_dimension()) # Index documents for text in chunked_data: vector = model.encode(text).tolist() db.insert_document('docs', vector, text) from sentence_transformers import SentenceTransformer from lancedb import lancedb # Load Sentence Transformer model model = SentenceTransformer('all-MiniLM-L6-v2') # Create LanceDB vector store db = lancedb.lancedb('/path/to/store') db.create_collection('docs', vector_dimension=model.get_sentence_embedding_dimension()) # Index documents for text in chunked_data: vector = model.encode(text).tolist() db.insert_document('docs', vector, text)
通过对文档进行索引,我们可以通过查找给定查询向量的最近邻居来执行初始检索。
from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") def chunk_text(text, chunk_size=512, overlap=64): tokens = tokenizer.encode(text, return_tensors="pt", truncation=True) chunks = tokens.split(chunk_size - overlap) texts = [tokenizer.decode(chunk) for chunk in chunks] return texts chunked_data = [] for doc in dataset: text = doc["chunk"] chunked_texts = chunk_text(text) chunked_data.extend(chunked_texts)
重新排名
初始检索后,我们将采用重新排序模型根据检索到的文档与查询的相关性对它们进行重新排序。在此示例中,我们将使用 ColBERT 重新排序器,这是一种快速、准确的基于转换器的模型,专为文档排序而设计。
from lancedb.rerankers import ColbertReranker reranker = ColbertReranker() # Rerank initial documents reranked_docs = reranker.rerank(query, initial_docs)
这个 reranked_docs
列表现在包含根据 ColBERT 重新排序器确定的与查询的相关性重新排序的文档。
增强和生成
有了重新排序的相关文档,我们就可以进入 RAG 管道的增强和生成阶段。我们将使用 Hugging Face Transformers 库中的语言模型来生成最终响应。
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM tokenizer = AutoTokenizer.from_pretrained("t5-base") model = AutoModelForSeq2SeqLM.from_pretrained("t5-base") # Augment query with reranked documents augmented_query = query + " " + " ".join(reranked_docs[:3]) # Generate response from language model input_ids = tokenizer.encode(augmented_query, return_tensors="pt") output_ids = model.generate(input_ids, max_length=500) response = tokenizer.decode(output_ids[0], skip_special_tokens=True) print(response)