Chroma 向量数据库学习笔记
Chroma 向量数据库学习笔记
1. 什么是 Chroma?
Chroma 是一个开源的嵌入式向量数据库。它主要用于存储和检索嵌入向量,这些向量通常由大型语言模型 (LLM) 或其他机器学习模型生成,用于表示文本、图像或其他类型数据的语义信息。Chroma 的设计目标是易于使用、轻量级、且专为 LLM 应用优化。
核心特点:
- 易于上手: 提供了简洁的 Python API,可以快速集成到 LLM 应用中。
- 嵌入式: 默认情况下,数据存储在本地,无需单独部署和管理服务器。也支持客户端-服务器模式。
- 内存优先: 为了速度,Chroma 优先使用内存存储,但也支持持久化到磁盘。
- 专为 LLM 优化: 针对文本嵌入的特性进行了优化,例如支持元数据过滤和多种相似度度量。
- 活跃的社区: 开源且社区活跃,持续更新和改进。
2. 核心概念
- Collection (集合): Chroma 中存储数据的基本单元。一个 Collection 包含多个嵌入向量和相关的元数据。可以把 Collection 类比于传统数据库中的表。
- Embedding (嵌入向量): 由模型生成的,用于表示数据语义信息的向量。例如,可以使用 OpenAI 的
text-embedding-ada-002
模型将文本转换为 1536 维的向量。 - Metadata (元数据): 与嵌入向量相关联的额外信息,例如文档的标题、作者、创建日期等。元数据可以用于过滤和排序搜索结果。
- Documents (文档): 在 LlamaIndex 等框架中,文档是文本及其元数据的组合。Chroma 可以直接存储文档,或者只存储文档的嵌入向量。
- Query (查询): 用于在 Collection 中搜索相似嵌入向量的操作。Chroma 支持多种查询方式,例如 k-最近邻 (k-NN) 搜索。
- Distance Function (距离函数): 用于衡量嵌入向量之间相似度的函数。常用的距离函数包括余弦相似度、欧几里得距离等。
3. 基本用法 (Python)
import chromadb# 1. 创建 Chroma 客户端 (默认内存模式)
client = chromadb.Client()# 2. 创建或获取一个 Collection
collection = client.get_or_create_collection(name="my_collection")# 3. 添加数据 (嵌入向量和元数据)
collection.add(embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 2.4], [3.1, 4.1, 2.1]], # 嵌入向量metadatas=[{"chapter": "1", "page": "3"}, {"chapter": "2", "page": "47"}, {"chapter": "2", "page": "5"}], # 元数据documents=["This is document1", "This is document2", "This is document3"], #可选的文档内容ids=["id1", "id2", "id3"], # 每个数据点的唯一 ID
)# 4. 查询 (搜索相似的嵌入向量)
results = collection.query(query_embeddings=[[1.2, 2.4, 3.1]], # 查询向量n_results=2, # 返回最相似的 2 个结果where={"chapter": "2"}, # 可选的元数据过滤器where_document={"$contains":"document"} #可选的文档内容过滤器
)# 5. 查看结果
print(results)
# {'ids': [['id1', 'id3']],
# 'embeddings': None,
# 'metadatas': [[{'chapter': '1', 'page': '3'}, {'chapter': '2', 'page': '5'}]],
# 'documents': [['This is document1', 'This is document3']],
# 'distances': [[0.10000000149011612, 0.20000000298023224]]}# 6. 持久化到磁盘 (可选)
# client = chromadb.PersistentClient(path="./chroma_db") # 指定路径
# 再次运行程序时,Chroma 会自动从磁盘加载数据# 7. 删除 Collection
# client.delete_collection(name="my_collection")
代码解释:
-
chromadb.Client()
: 创建 Chroma 客户端。默认使用内存模式,数据不会持久化。 -
client.get_or_create_collection(name="my_collection")
: 获取或创建一个名为 “my_collection” 的 Collection。如果 Collection 不存在,则创建;如果存在,则返回已有的 Collection 对象。 -
- 向 Collection 中添加数据。
collection.add(...)
embeddings
: 嵌入向量列表。每个向量都是一个浮点数列表。metadatas
: 元数据列表。每个元数据都是一个字典。documents
: (可选)原始文档内容的列表。ids
: 每个数据点的唯一 ID 列表。
-
- 在 Collection 中执行查询。
collection.query(...)
query_embeddings
: 查询向量的列表。n_results
: 指定返回最相似的多少个结果。where
: (可选)元数据过滤器。使用字典指定过滤条件。where_document
: (可选) 文档内容过滤器。
-
client.persist()
: 将内存中的数据持久化到磁盘。 -
chromadb.PersistentClient(path="./chroma_db")
: 创建持久化模式的 Chroma 客户端。数据将存储在指定的路径下。
4. 进阶用法
-
距离函数: Chroma 默认使用欧几里得距离,但支持其他距离函数,如余弦相似度。可以在创建 Collection 时指定:
collection = client.get_or_create_collection(name="my_collection",embedding_function=None, # 如果使用自定义的嵌入函数,需要设置为 Nonemetadata={"hnsw:space": "cosine"} # 使用余弦相似度 )
-
索引参数: Chroma 使用 HNSW (Hierarchical Navigable Small World) 索引来加速相似度搜索。可以调整 HNSW 的参数以平衡搜索速度和精度。
-
客户端-服务器模式: Chroma 支持将数据存储在单独的服务器上,客户端通过 gRPC 进行通信。这适用于大规模数据和分布式场景。
-
与 LlamaIndex 集成: LlamaIndex 可以直接使用 Chroma 作为向量存储。
from llama_index.vector_stores import ChromaVectorStore from llama_index.core import VectorStoreIndex# 创建 Chroma 向量存储 chroma_vector_store = ChromaVectorStore(chroma_collection=collection)# 使用 Chroma 向量存储构建 LlamaIndex 索引 index = VectorStoreIndex.from_documents(documents,vector_store=chroma_vector_store )
-
批量操作: Chroma 提供了批量添加、更新和删除数据的接口,可以提高效率。
5. 总结
Chroma 是一个简单易用、功能强大的向量数据库,特别适合于 LLM 应用中存储和检索文本嵌入向量。它的轻量级、内存优先的设计使其非常适合快速原型开发和小型项目。对于大规模数据和生产环境,可以考虑使用其客户端-服务器模式或与其他向量数据库(如 Pinecone, Milvus)集成。LlamaIndex 提供了与 Chroma 的无缝集成,使得构建基于 LLM 的 RAG 系统更加方便。