Loading

Embedding和向量数据库

向量 = 把信息统一编码成可计算的数字,让机器能用数学理解语义、关系和相似度,越相近则越匹配

向量 = 信息的数字表示

相似度 = 数字之间的距离

AI 智能 = 大规模向量匹配

向量表征

在人工智能领域,向量表征(Vector Representation)是核心概念之一。通过将文本、图像、声音、行为甚至复杂关系转化为高维向量(Embedding),AI系统能够以数学方式理解和处理现实世界中的复杂信息。这种表征方式为机器学习模型提供了统一的“语言”。

向量表征的本质

向量表征的本质:万物皆可数学化

核心思想:

  • 降维抽象:将复杂对象(如一段文字、一张图片)映射到低维稠密向量空间,保留关键语义或特征
  • 相似性度量:向量空间中的距离(如余弦相似度)反映对象之间的语义关联(如“猫”和“狗”的向量距离小于“猫”和“汽车”)

数学意义:

  • 特征工程自动化:传统机器学习依赖人工设计特征(如文本的TF-IDF),而向量表征通过深度学习自动提取高阶抽象特征
  • 跨模态统一:文本、图像、视频等不同模态数据可映射到同一向量空间,实现跨模态检索(如“用文字搜图片”)
应用场景
  1. 自然语言处理(NLP)

    • 词向量(Word2Vec、GloVe): 单词映射为向量,解决“一词多义”问题(如“苹果”在“水果”和“公司”上下文中的不同向量)。

    • 句向量(BERT、Sentence-BERT): 整句语义编码,用于文本相似度计算、聚类(如客服问答匹配)。

    • 知识图谱嵌入(TransE、RotatE): 将实体和关系表示为向量,支持推理(如预测“巴黎-首都-法国”的三元组可信度)。

  2. 计算机视觉(CV)

    • 图像特征向量(CNN特征): ResNet、ViT等模型提取图像语义,用于以图搜图、图像分类。
    • 跨模态对齐(CLIP): 将图像和文本映射到同一空间,实现“描述文字生成图片”或反向搜索。
  3. 推荐系统 -

    • 用户/物品向量: 用户行为序列(点击、购买)编码为用户向量,商品属性编码为物品向量,通过向量内积预测兴趣匹配度(如YouTube推荐算法)。
  4. 复杂系统建模

    • 图神经网络(GNN): 社交网络中的用户、商品、交互事件均表示为向量,捕捉网络结构信息(如社区发现、欺诈检测)。
    • 时间序列向量化: 将股票价格、传感器数据编码为向量,预测未来趋势(如LSTM、Transformer编码)。
向量表征技术实现

1.经典方法

  • 无监督学习:Word2Vec通过上下文预测(Skip-Gram)或矩阵分解(GloVe)生成词向量。

  • 有监督学习:微调预训练模型(如BERT)适应具体任务,提取任务相关向量。

2.前沿方向

  • 对比学习(Contrastive Learning):通过构造正负样本对(如“同一图片的不同裁剪”为正样本),拉近正样本向量距离,推开负样本(SimCLR、MoCo)。

  • 多模态融合:将文本、图像、语音等多模态信息融合为统一向量(如Google的MUM模型)。

  • 动态向量:根据上下文动态调整向量(如Transformer的注意力机制),解决静态词向量无法适应多义性的问题

向量

image-20260311161949899

文本向量

image-20260311162227098

向量间的相似度计算

image-20260311162603559

余弦相似度是通过计算两个向量夹角的余弦值来衡量相似性,等于两个向量的点积除以两个向量长度的乘积

image-20260311162706730

Embedding Models 嵌入模型

嵌入(Embedding)是指非结构化数据转换为向量的过程,通过神经网络模型或相关大模型,将真实世界的离散数据投影到高维数据空间上,根据数据在空间中的不同距离,反映数据在物理世界的相似度。

嵌入模型的本质

嵌入模型(Embedding Model)是一种将离散数据(如文本、图像)映射到连续向量空间的技术。

通过高维向量表示(如 768 维或 3072 维),模型可捕捉数据的语义信息,使得语义相似的文本在向量空间中距离更近。

例如:“忘记密码” 和 “账号锁定” 会被编码为相近的向量,从而支持语义检索,而非仅关键词匹配

核心作用

  • 语义编码:将文本、图像等转换为向量,保留上下文信息(如 BERT 的 CLS Token 或均值池化)。

  • 相似度计算:通过余弦相似度、欧氏距离等度量向量关联性,支撑检索增强生成(RAG)、推荐系统等应用。

  • 信息降维:压缩复杂数据为低维稠密向量,提升存储与计算效率

关键技术原理

  • 上下文依赖:现代模型(如 BGE-M3)动态调整向量,捕捉多义词在不同语境中的含义。
  • 训练方法:对比学习(如 Word2Vec 的 Skip-gram/CBOW)、预训练 + 微调(如 BERT)
主流嵌入模型和选型指南

Embedding 模型将文本转换为数值向量,捕捉语义信息,使计算机能够理解和比较内容的 "意义"。选择 Embedding 模型的考虑因素:

因素 说明
任务性质 匹配任务需求 (问答、搜索、聚类等)
领域特性 通用 vs 专业领域 (医学、法律等)
多语言支持 需处理多语言内容时考虑
维度 权衡信息丰富度与计算成本
许可条款 开源 vs 专有服务
最大 Tokens 适合的上下文窗口大小

最佳实践:为特定应用测试多个 Embedding 模型,评估在实际数据上的性能而非仅依赖通用基准。

通用全能型

  • BGE-M3:北京智源研究院开发,支持多语言、混合检索(稠密 + 稀疏向量),处理 8K 上下文,适合企业级知识库。
  • NV-Embed-v2:基于 Mistral-7B,检索精度高(MTEB 得分 62.65),但需较高计算资源。

垂直领域特化型

  • 中文场景:BGE-large-zh-v1.5(合同 / 政策文件)、M3E-base(社交媒体分析)。
  • 多模态场景:BGE-VL(图文跨模态检索),联合编码 OCR 文本与图像特征。

轻量化部署型

  • nomic-embed-text:768 维向量,推理速度比 OpenAI 快 3 倍,适合边缘设备。
  • gte-qwen2-1.5b-instruct:1.5B 参数,16GB 显存即可运行,适合初创团队原型验证。

选型决策树

  1. 中文为主 → BGE 系列 > M3E;
  2. 多语言需求 → BGE-M3 > multilingual-e5;
  3. 预算有限 → 开源模型(如 Nomic Embed)。
嵌入模型调用
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),  
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1" 
)

completion = client.embeddings.create(
    model="text-embedding-v4",
    input='a7',
    dimensions=1024,
    encoding_format="float"
)

print(completion.model_dump_json())

向量数据库

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

高效存储、快速检索和管理高纬度向量数据的系统称为向量数据库

一种专门用于存储和检索高维向量数据的数据库。它将数据(如文本、图像、音频等)通过嵌入模型转换为向量形式,并通过高效的索引和搜索算法实现快速检索。

向量数据库的核心作用是实现相似性搜索,即通过计算向量之间的距离(如欧几里得距离、余弦相似度等)来找到与目标向量最相似的其他向量。它特别适合处理非结构化数据,支持语义搜索、内容推荐等场景。

核心功能:

  • 向量存储

  • 相似性度量

  • 相似性搜索

image-20260311181431143

如何检索和存储向量
  • 存储:向量数据库将嵌入向量存储为高维空间中的点,并为每个向量分配唯一标识符(ID),同时支持存储元数据。

  • 检索:通过近似最近邻(ANN)算法(如PQ等)对向量进行索引和快速搜索。比如,FAISS和Milvus等数据库通过高效的索引结构加速检索。

向量数据库与传统数据库对比
  1. 数据类型
  • 传统数据库:存储结构化数据(如表格、行、列)。
  • 向量数据库:存储高维向量数据,适合非结构化数据。
  1. 查询方式
  • 传统数据库:依赖精确匹配(如=、<、>)。
  • 向量数据库:基于相似度或距离度量(如欧几里得距离、余弦相似度)。
  1. 应用场景
  • 传统数据库:适合事务记录和结构化信息管理。
  • 向量数据库:适合语义搜索、内容推荐等需要相似性计算的场景。
  • 向量数据库的意义是快速的检索;
  • 向量数据库本身不生成向量,向量是由 Embedding 模型产生的;
  • 向量数据库与传统的关系型数据库是互补的,不是替代关系,在实际应用中根据实际需求经常同时使用。
Chroma向量数据库

官方文档:https://docs.trychroma.com/docs/overview/introduction

什么是 Chroma?

Chroma 是一款开源的向量数据库,专为高效存储和检索高维向量数据设计。其核心能力在于语义相似性搜索,支持文本、图像等嵌入向量的快速匹配,广泛应用于大模型上下文增强(RAG)、推荐系统、多模态检索等场景。与传统数据库不同,Chroma 基于向量距离(如余弦相似度、欧氏距离)衡量数据关联性,而非关键词匹配。

核心优势

  • 轻量易用:以 Python/JS 包形式嵌入代码,无需独立部署,适合快速原型开发。
  • 灵活集成:支持自定义嵌入模型(如 OpenAI、HuggingFace),兼容 LangChain 等框架。
  • 高性能检索:采用 HNSW 算法优化索引,支持百万级向量毫秒级响应。
  • 多模式存储:内存模式用于开发调试,持久化模式支持生产环境数据落地。
ChromaDB安装与配置和使用

安装

# 安装
pip install chromadb            

初始化客户端

import chromadb

# 1.内存模式,一般不建议使用
# 内存客户端的所有数据(向量、元数据、集合)都存储在内存中,程序退出、进程崩溃、服务器重启后,所有数据会全部丢失
# 内存客户端是和进程绑定的,无法单独部署、扩展,且不支持生产机特性
client = chromadb.EphemeralClient()

# 2. 本地持久化客户端, 数据持久化到本地文件夹
client = chromadb.PersistentClient(path="./chroma")


增删改查

集合是 Chroma 中管理数据的基本单元,类似关系数据库的表

  1. 创建向量模型

    client = chromadb.PersistentClient(path="./chroma")
    
    # 1. 默认模型,默认使用DefaultEmbeddingFunctions是基于Sentence Transformers 的 MiniLM-L6-v2 模型
    default_ef = embedding_functions.DefaultEmbeddingFunction()
    
    
    
    # 2. 使用 OpenAI 的嵌入模型,默认使用 text-embedding-ada-002 模型
    openai_ef = embedding_functions.OpenAIEmbeddingFunction(
        api_key="",
        model_name=""
    )
    
    
    # 3.使用自定义模型
    # 自定义 Embedding 函数类(继承 ChromaDB 的 EmbeddingFunction 接口)
    class MyEmbeddingFunction(EmbeddingFunction):
        def __init__(self):
            # 初始化自定义模型(这里用 Sentence-BERT 为例)
            self.model = SentenceTransformer('all-MiniLM-L6-v2')
    
        def __call__(self, texts: Documents) -> Embeddings:
            """
            核心方法:将文本列表转换为向量列表
            :param texts: 输入的文本列表(Documents 本质是 List[str])
            :return: 向量列表(Embeddings 本质是 List[List[float]])
            """
            # 1. 处理空文本(避免模型报错)
            texts = [text if text.strip() else "" for text in texts]
    
            # 2. 调用自定义模型生成向量
            embeddings = self.model.encode(
                texts,
                convert_to_numpy=True,  # 输出 numpy 数组(方便后续处理)
                normalize_embeddings=True  # 归一化向量(提升检索效果)
            )
    
            # 3. 转换为 List[List[float]] 格式(ChromaDB 要求的格式)
            embeddings = embeddings.tolist()
    
            # 4. 校验输出格式
            if len(embeddings) != len(texts):
                raise ValueError(f"生成的向量数量({len(embeddings)})与文本数量({len(texts)})不匹配")
    
            return embeddings
    
    

    2.集合操作

    # 创建集合 collection(类似数据库表)
    collection = client.get_or_create_collection(
        name="my_collection",
        configuration={
            # HNSW 索引算法,基于图的近似最近邻搜索算法(
            "hnsw": {
                "space": "cosine",  # 指定余弦相似度计算
                "ef_search": 100,  # 用于搜索的优化参数,值越大,搜索精度越高,但速度越慢
                "ef_construction": 100,  # 用于构建索引的优化参数,值越大,索引质量越高,构建时间越长
                "max_neighbors": 16,  # 每个节点的最大邻居数
                "num_threads": 4  # 用于搜索和构建索引的线程数
            },
            # 指定向量模型
            "embedding_function": default_ef
        }
    )
    
    # 查询集合
    collection = client.get_collection(name="my_collection")
    
    # 删除集合
    client.delete_collection(name="my_collection")
    
    # 返回集合中数据的条数
    print(collection.count())
    # 返回集合中的数据,默认10条,可以使用limit指定数量
    print(collection.peek())
    
    

    3.数据操作

    """ 添加数据 """
    
    # 方式1:集合添加数据,自动生成向量(使用集合指定的嵌入模型)
    collection.add(
        # 文档的集合
        documents = ["RAG是一种检索增强生成技术", "向量数据库存储文档的嵌入表示", "在机器学习领域,智能体(Agent)通常指能够感知环境、做出决策并采取行动以实现特定目标的实体"],
        # 文档元数据信息
        metadatas = [{"source": "RAG"}, {"source": "向量数据库"}, {"source": "Agent"}],
        # id
        ids = ["id1", "id2", "id3"]
    )
    
    # 方式2:集合添加数据吗,手动传入预计算向量(实际开发中推荐使用)
    collection.add(
        # 使用现有的向量模型生成好向量传入
        embeddings = get_embeddings("向量方法"),
        documents = ["文本1", "文本2"],
        ids = ["id3", "id4"]
    )
    
    """查询数据"""
    
    result = collection.query(
        query_texts=  ["RAG是什么"], #要检索的内容
        n_results=2,  # 要求返回的的数据条数,默认是10,如果指定了,一定会返回对应的条数
    )
    
    
    result = collection.query(
        query_texts=  ["RAG是什么"], #要检索的内容
        n_results=2,  # 要求返回的的数据条数,默认是10,如果指定了,一定会返回对应的条数
        where={"source":"RAG"}  # 根据源数据过滤,优先级大于n_results
    )
    
    
    result = collection.query(
        query_texts=  ["RAG是什么"], #要检索的内容
        n_results=2,  # 要求返回的的数据条数,默认是10,如果指定了,一定会返回对应的条数
        where_document={"$contains":"检索增强生成技术"}  # 按文档内容过滤
    )
    
    result = collection.query(
        query_embeddings=  [[0.5,0.6]], #根据向量进行查询
        n_results = 2
      
    )
    print(result)
    
    """更新数据"""
    collection.update(ids=["id1"],documents=["RAG真牛逼"])
    
    """删除数据"""
    collection.delete(ids=["id1"])
    
CS模式
# 启动服务端
chroma run --path /db_path
# 客户端连接
chroma_client = chromadb.HttpClient(host='localhost', port=8000)
posted @ 2026-03-12 16:19  木子七  阅读(145)  评论(0)    收藏  举报