【RAG】向量检索

1.什么是向量

向量是一种有大小和方向的数学对象。它可以表示为从一个点到另一个点的有向线段。例如,二维空间中的向量可以表示为 ( x , y ) (x,y) (x,y),表示从原点 ( 0 , 0 ) (0,0) (0,0) 到点 ( x , y ) (x,y) (x,y) 的有向线段。

以此类推,可以用一组坐标 ( x 0 , x 1 , … , x N − 1 ) (x_0, x_1, \ldots, x_{N-1}) (x0,x1,,xN1) 表示一个 N N N 维空间中的向量, N N N 叫向量的维度。

1.1 文本向量(Text Embedding)

  1. 将文本转成一组 N N N 维浮点数,即文本向量又叫 Embeddings
  2. 向量之间可以计算距离,距离远近对应语义相似度大小

1.2 向量是怎么得到的?

  1. 构建相关(正立)与不相关(负例)的句子对儿样本
  2. 训练双塔式模型,让正例间的距离小,负例间的距离大

扩展:https://www.sbert.net

2.向量的相似度计算

欧氏距离、余弦距离
在这里插入图片描述

import numpy as np
from numpy import dot
from numpy.linalg import norm

def cos_sim(a, b):
    '''余弦距离 -- 越大越相似'''
    return dot(a, b)/(norm(a)*norm(b))


def l2(a, b):
    '''欧氏距离 -- 越小越相似'''
    x = np.asarray(a)-np.asarray(b)
    return norm(x)

def get_embeddings(texts, model="text-embedding-ada-002", dimensions=None):
    '''封装 OpenAI 的 Embedding 模型接口'''
    if model == "text-embedding-ada-002":
        dimensions = None
    if dimensions:
        data = client.embeddings.create(
            input=texts, model=model, dimensions=dimensions).data
    else:
        data = client.embeddings.create(input=texts, model=model).data
    return [x.embedding for x in data]

test_query = ["测试文本"]
vec = get_embeddings(test_query)[0]
print(f"Total dimension: {len(vec)}")
print(f"First 10 elements: {vec[:10]}")

### 输出

Total dimension: 1536
First 10 elements: [-0.007280634716153145, -0.006147929932922125, -0.010664181783795357, 0.001484171487390995, -0.010678750462830067, 0.029253656044602394, -0.01976952701807022, 0.005444996990263462, -0.01687038503587246, -0.01207733154296875]
# query = "国际争端"

# 且能支持跨语言
query = "global conflicts"

documents = [
    "联合国就苏丹达尔富尔地区大规模暴力事件发出警告",
    "土耳其、芬兰、瑞典与北约代表将继续就瑞典“入约”问题进行谈判",
    "日本岐阜市陆上自卫队射击场内发生枪击事件 3人受伤",
    "国家游泳中心(水立方):恢复游泳、嬉水乐园等水上项目运营",
    "我国首次在空间站开展舱外辐射生物学暴露实验",
]

query_vec = get_embeddings([query])[0]
doc_vecs = get_embeddings(documents)

print("Query与自己的余弦距离: {:.2f}".format(cos_sim(query_vec, query_vec)))
print("Query与Documents的余弦距离:")
for vec in doc_vecs:
    print(cos_sim(query_vec, vec))

print()

print("Query与自己的欧氏距离: {:.2f}".format(l2(query_vec, query_vec)))
print("Query与Documents的欧氏距离:")
for vec in doc_vecs:
    print(l2(query_vec, vec))
### 输出

Query与自己的余弦距离: 1.00
Query与Documents的余弦距离:
0.7622749944010915
0.7563038106493584
0.7426665802579038
0.7079273699608006
0.7254355321045072

Query与自己的欧氏距离: 0.00
Query与Documents的欧氏距离:
0.6895288502682277
0.6981349637998769
0.7174028746492277
0.7642939833636829
0.7410323668625171

3. 向量数据库

向量数据库,是为向量检索设计的中间件

# !pip install chromadb

# 环境端差异,对pysqlite的兼容处理
import os
if os.environ.get('CUR_ENV_IS_STUDENT',False):
    import sys
    __import__('pysqlite3')
    sys.modules['sqlite3'] = sys.modules.pop('pysqlite3')
###
# 暂只取两页(第一章)
paragraphs = extract_text_from_pdf(
    "llama2.pdf",
    page_numbers=[2, 3],
    min_line_length=10
)

##### 
import chromadb
from chromadb.config import Settings


class MyVectorDBConnector:
    def __init__(self, collection_name, embedding_fn):
        chroma_client = chromadb.Client(Settings(allow_reset=True))

        # 为了演示,实际不需要每次 reset()
        chroma_client.reset()

        # 创建一个 collection
        self.collection = chroma_client.get_or_create_collection(
            name=collection_name)
        self.embedding_fn = embedding_fn

    def add_documents(self, documents):
        '''向 collection 中添加文档与向量'''
        self.collection.add(
            embeddings=self.embedding_fn(documents),  # 每个文档的向量
            documents=documents,  # 文档的原文
            ids=[f"id{i}" for i in range(len(documents))]  # 每个文档的 id
        )

    def search(self, query, top_n):
        '''检索向量数据库'''
        results = self.collection.query(
            query_embeddings=self.embedding_fn([query]),
            n_results=top_n
        )
        return results

# 创建一个向量数据库对象
vector_db = MyVectorDBConnector("demo", get_embeddings)
# 向向量数据库中添加文档
vector_db.add_documents(paragraphs)

user_query = "Llama 2有多少参数"
# user_query = "Does Llama 2 have a conversational variant"
results = vector_db.search(user_query, 2)

for para in results['documents'][0]:
    print(para+"\n")
输出:
1. Llama 2, an updated version of Llama 1, trained on a new mix of publicly available data. We also increased the size of the pretraining corpus by 40%, doubled the context length of the model, and adopted grouped-query attention (Ainslie et al., 2023). We are releasing variants of Llama 2 with 7B, 13B, and 70B parameters. We have also trained 34B variants, which we report on in this paper but are not releasing.§

 In this work, we develop and release Llama 2, a family of pretrained and fine-tuned LLMs, Llama 2 and Llama 2-Chat, at scales up to 70B parameters. On the series of helpfulness and safety benchmarks we tested, Llama 2-Chat models generally perform better than existing open-source models. They also appear to be on par with some of the closed-source models, at least on the human evaluations we performed (see Figures 1 and 3). We have taken measures to increase the safety of these models, using safety-specific data annotation and tuning, as well as conducting red-teaming and employing iterative evaluations. Additionally, this paper contributes a thorough description of our fine-tuning methodology and approach to improving LLM safety. We hope that this openness will enable the community to reproduce fine-tuned LLMs and continue to improve the safety of those models, paving the way for more responsible development of LLMs. We also share novel observations we made during the development of Llama 2 and Llama 2-Chat, such as the emergence of tool usage and temporal organization of knowledge.
澄清几个关键概念:
  • 向量数据库的意义是快速的检索;
  • 向量数据库本身不生成向量,向量是由 Embedding 模型产生的;
  • 向量数据库与传统的关系型数据库是互补的,不是替代关系,在实际应用中根据实际需求经常同时使用。

4.向量数据库服务

# Server 端
chroma run --path /db_path

# Client端
import chromadb
chroma_client = chromadb.HttpClient(host='localhost', port=8000)

5.主流向量数据库对比

在这里插入图片描述

<think>好的,我现在需要处理用户关于RAG模型中向量的使用说明和实现细节的问题。首先,我得回顾一下用户之前的提问和我的回答,确保信息连贯。用户之前询问了RAG模型中的向量相关信息,现在需要更详细的使用说明或实现细节。 首先,我应该明确RAG模型的结构,特别是向量生成和检索部分。根据之前的引用,用户提到了VectorRAG和GraphRAG的区别,以及Word2Vec和Milvus的应用场景。需要将这些内容整合到回答中。 用户可能需要知道如何生成文本向量,这里可以引用Word2Vec的两种模型:CBOW和Skip-gram。同时,要提到其他方法如BERT或Transformer模型。这部分需要详细说明生成步骤,比如分词、模型选择、训练等。 接下来是向量存储,用户可能想知道如何选择向量数据库,比如Milvus或FAISS。需要解释这些数据库的特点和适用场景,比如处理大规模数据时的性能优化。 然后是检索增强部分,要说明如何通过相似度计算找到相关文本,并输入到生成模型。这里可以举例说明,比如使用余弦相似度或ANN算法。 实现细节方面,可以分步骤讲解:数据预处理、模型选择、向量存储、检索策略和生成模型。每个步骤需要具体的技术要点,比如预处理中的清洗和分词,模型选择时的考虑因素,存储时的索引优化等。 可能还需要引用用户提供的资料,比如引用[2]中的Word2Vec实现步骤,引用[3]中Milvus的应用场景。要确保引用标记正确,并自然地融入回答中。 同时,用户示例中提到了生成相关问题,我需要根据内容提出相关问题,比如向量生成方法的选择、性能优化、应用场景差异等。 最后,检查回答是否符合系统级指令:使用正确的中文和LaTeX格式,结构清晰,引用正确,相关问题相关且合理。需要避免使用任何Markdown,保持自然口语化,但这里要转换为正式的回答格式。</think>### RAG模型中向量的使用说明与实现细节 RAG检索增强生成)模型通过结合检索与生成两大模块提升文本生成质量,其中**向量技术**是核心组件,主要用于文本表示与检索环节。以下是关键实现细节: --- #### 一、向量生成方法 1. **文本向量化技术** - **传统方法**:使用$Word2Vec$模型(如CBOW或Skip-gram)将词映射到低维空间,句子向量通过词向量加权平均生成[^2]。 - 例如:句子$s$的向量表示为$\vec{s} = \frac{1}{n}\sum_{i=1}^n \vec{w_i}$,其中$\vec{w_i}$为词向量。 - **深度学习方法**:采用$BERT$、$RoBERTa$等预训练模型生成上下文相关向量,公式为$\vec{d} = \text{BERT}(s)[\text{CLS}]$。 - **训练步骤**: - 数据预处理(分词、去停用词) - 选择模型架构(如Skip-gram更适合低频词) - 调整超参数(向量维度、窗口大小) 2. **向量归一化** 对生成向量进行L2归一化:$\vec{v}_{\text{norm}} = \frac{\vec{v}}{||\vec{v}||_2}$,以提升相似度计算稳定性。 --- #### 二、向量存储与检索 1. **向量数据库选型** - **Milvus**:支持高性能ANN(近似最近邻)搜索,适合亿级数据量[^3]。 - **FAISS**:Facebook开源的库,提供GPU加速和多种索引类型(IVF、HNSW)。 - 选择依据:数据规模、延迟要求、硬件条件。 2. **检索优化策略** - **混合检索**:结合向量相似度(余弦距离)与关键词匹配(BM25)提升召回率。 - **分层索引**:先粗筛(如IVF索引)再精排,平衡速度与精度。 --- #### 三、实现流程示例 1. **数据预处理** ```python from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") tokens = tokenizer("RAG模型的核心是向量检索", return_tensors="pt") ``` 2. **向量生成与存储** ```python import milvus collection = milvus.Collection("doc_vectors") vectors = model.encode(texts) # 使用BERT生成向量 collection.insert([vectors]) ``` 3. **检索增强生成** ```python query_vec = model.encode(user_query) results = collection.search(query_vec, top_k=5) context = " ".join([doc.text for doc in results]) output = generator.generate(context + query) ``` --- #### 四、性能优化关键点 1. **向量维度选择**:常用256-768维,过高维度增加计算开销,过低丢失语义信息。 2. **批量处理**:使用GPU并行计算加速向量生成。 3. **量化压缩**:对向量进行8-bit量化,减少内存占用(精度损失可控)。 --- ### 相关问题 1. Word2Vec与BERT生成的向量RAG中的效果差异? 2. 如何评估向量检索系统的召回率与准确率? 3. Milvus和FAISS在千万级数据下的性能对比? 4. 向量维度与检索耗时的量化关系是什么? [^1]: GraphRAG通过知识图谱增强关系推理能力,与VectorRAG形成互补。 [^2]: Word2Vec通过CBOW/Skip-gram模型学习词向量,适用于轻量级场景。 [^3]: Milvus支持以图搜图、智能问答等需要高吞吐向量检索的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星星点点洲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值