usearch Python API快速入门:5分钟实现向量添加与检索

usearch Python API快速入门:5分钟实现向量添加与检索

【免费下载链接】usearch Fastest Open-Source Search & Clustering engine × for Vectors & 🔜 Strings × in C++, C, Python, JavaScript, Rust, Java, Objective-C, Swift, C#, GoLang, and Wolfram 🔍 【免费下载链接】usearch 项目地址: https://gitcode.com/gh_mirrors/us/usearch

你是否还在为高维向量检索的性能问题困扰?是否需要一个简单易用却高效的向量搜索引擎?本文将带你5分钟内快速掌握usearch Python API,从安装到实现完整的向量添加与检索流程,让你轻松应对向量检索任务。

读完本文后,你将能够:

  • 安装并配置usearch Python环境
  • 创建向量索引并添加向量数据
  • 执行精确与近似向量检索
  • 实现索引的持久化与加载
  • 掌握批量操作与性能优化技巧

1. 环境准备与安装

1.1 系统要求

usearch支持多种操作系统和Python版本:

  • 操作系统:Linux、Windows、macOS
  • Python版本:3.7及以上
  • 硬件加速:支持AVX2指令集的CPU可获得最佳性能

1.2 快速安装

使用pip命令即可完成安装:

pip install usearch

如需从源码构建(适用于开发或特定版本需求):

git clone https://gitcode.com/gh_mirrors/us/usearch
cd usearch/python
pip install .

1.3 验证安装

安装完成后,通过以下代码验证:

import usearch
from usearch.index import Index

print(f"usearch version: {usearch.__version__}")
print(f"支持的距离度量: {usearch.index.MetricKind.__members__.keys()}")

预期输出应包含版本信息及支持的距离度量列表,如CosIPL2sq等。

2. 核心概念与基础架构

2.1 核心组件

usearch Python API的核心组件包括:

组件描述
Index向量索引主类,负责向量的存储、索引和检索
MetricKind距离度量类型枚举,如余弦相似度、内积、欧氏距离等
ScalarKind标量类型枚举,控制向量存储精度(f32、f16、bf16、i8等)
Matches检索结果容器,包含匹配的向量ID和距离值
BatchMatches批量检索结果容器,支持多查询向量的检索结果

2.2 工作原理

usearch采用分层 navigable small world (HNSW) 图算法,结合SIMD硬件加速,实现高效的近似最近邻搜索。其核心工作流程如下:

mermaid

HNSW算法通过构建多层图结构,在保证检索质量的同时显著提升检索速度,相比传统方法具有更高的性能。

3. 快速入门:从创建到检索

3.1 创建向量索引

首先,我们需要创建一个向量索引。以下是创建索引的基本示例:

import numpy as np
from usearch.index import Index, MetricKind, ScalarKind

# 创建索引实例
index = Index(
    ndim=384,  # 向量维度
    metric=MetricKind.Cos,  # 距离度量:余弦相似度
    dtype=ScalarKind.F32,  # 存储精度:32位浮点数
    connectivity=16,  # HNSW图连接数
    expansion_add=128,  # 添加时的搜索扩展
    expansion_search=64  # 检索时的搜索扩展
)

print(f"索引创建成功: 维度={index.ndim}, 度量={index._metric_kind}, 类型={index.dtype}")

参数说明

参数描述默认值
ndim向量维度0(动态确定)
metric距离度量类型MetricKind.Cos(余弦相似度)
dtype存储数据类型自动选择(基于度量和硬件)
connectivityHNSW图中每个节点的连接数16
expansion_add添加向量时的搜索扩展128
expansion_search检索时的搜索扩展64

3.2 添加向量

创建索引后,可以向其中添加向量。usearch支持单向量和批量向量添加:

# 生成示例数据
n_vectors = 10000
keys = np.arange(n_vectors, dtype=np.uint64)  # 向量ID
vectors = np.random.rand(n_vectors, index.ndim).astype(np.float32)  # 随机向量

# 批量添加向量
index.add(keys, vectors, threads=4)  # 使用4线程加速

print(f"添加完成: 索引大小={len(index)}, 维度={index.ndim}")

性能提示

  • 使用threads参数指定并行线程数(0表示自动检测)
  • 对于大型数据集,设置copy=False可避免数据复制(需确保向量数据生命周期覆盖索引使用期)
  • 添加进度可通过log=True参数启用进度条

3.3 向量检索

添加向量后,即可执行检索操作。usearch支持精确检索和近似检索:

# 生成查询向量
query_vector = np.random.rand(index.ndim).astype(np.float32)

# 近似检索(默认)
results = index.search(query_vector, count=10)  # 返回前10个结果

print(f"检索完成: 找到{len(results)}个结果")
print("前5个结果:")
for i, match in enumerate(results[:5]):
    print(f"  排名{i+1}: ID={match.key}, 距离={match.distance:.4f}")

# 精确检索(用于小数据集或验证)
exact_results = index.search(query_vector, count=10, exact=True)

检索结果解析

search方法返回Matches对象,包含以下属性:

  • keys: 匹配的向量ID数组
  • distances: 对应的距离值数组
  • visited_members: 访问的节点数
  • computed_distances: 计算的距离数

3.4 索引持久化与加载

usearch支持索引的保存与加载,方便后续使用:

# 保存索引
index.save("my_index.usearch")
print("索引已保存")

# 加载索引
new_index = Index.restore("my_index.usearch")
print(f"索引加载成功: 大小={len(new_index)}, 维度={new_index.ndim}")

# 内存映射(适合大型索引,无需全部加载到内存)
mapped_index = Index()
mapped_index.view("my_index.usearch")
print(f"内存映射索引: 大小={len(mapped_index)}")

持久化选项

  • save(path): 将索引完整保存到磁盘
  • load(path): 从磁盘加载索引到内存
  • view(path): 创建磁盘索引的内存映射视图(只读)
  • Index.metadata(path): 获取索引元数据(无需加载整个索引)

4. 高级功能

4.1 批量操作

usearch对批量操作进行了优化,推荐在处理大量数据时使用:

# 批量添加
n_batch = 1000
batch_keys = np.arange(n_batch, dtype=np.uint64)
batch_vectors = np.random.rand(n_batch, index.ndim).astype(np.float32)
index.add(batch_keys, batch_vectors)

# 批量检索
n_queries = 100
query_vectors = np.random.rand(n_queries, index.ndim).astype(np.float32)
batch_results = index.search(query_vectors, count=10)

print(f"批量检索完成: 查询数={len(batch_results)}, 每个查询结果数={len(batch_results[0])}")

# 处理第一个查询的结果
first_query_results = batch_results[0]
print(f"第一个查询结果: {[(match.key, match.distance) for match in first_query_results[:3]]}")

4.2 距离度量选择

usearch支持多种距离度量,适用于不同场景:

# 查看所有支持的距离度量
print("支持的距离度量:", [m for m in MetricKind.__members__.keys()])

# 创建不同度量的索引示例
index_ip = Index(ndim=128, metric=MetricKind.IP)  # 内积
index_l2 = Index(ndim=128, metric=MetricKind.L2sq)  # 平方欧氏距离
index_hamming = Index(ndim=256, metric=MetricKind.Hamming)  # 汉明距离

print(f"创建不同度量的索引: IP={index_ip._metric_kind}, L2={index_l2._metric_kind}, Hamming={index_hamming._metric_kind}")

常用度量适用场景

度量类型适用场景向量类型
Cos(余弦相似度)文本、图像特征单位向量
IP(内积)推荐系统、分类任务归一化向量
L2sq(平方欧氏距离)高维数据检索任意实值向量
Hamming(汉明距离)二进制特征二进制向量

4.3 数据类型优化

usearch支持多种数据类型,可根据精度需求和性能要求选择:

# 创建不同数据类型的索引
index_f16 = Index(ndim=128, dtype=ScalarKind.F16)  # 16位浮点数
index_bf16 = Index(ndim=128, dtype=ScalarKind.BF16)  # BF16浮点数
index_i8 = Index(ndim=128, dtype=ScalarKind.I8)  # 8位整数

print(f"数据类型比较: F16={index_f16.dtype}, BF16={index_bf16.dtype}, I8={index_i8.dtype}")

# 测试不同数据类型的性能
import time

def test_performance(dtype, n=10000):
    index = Index(ndim=128, dtype=dtype)
    keys = np.arange(n, dtype=np.uint64)
    vectors = np.random.rand(n, 128).astype(np.float32)
    
    start = time.time()
    index.add(keys, vectors)
    add_time = time.time() - start
    
    query = np.random.rand(128).astype(np.float32)
    start = time.time()
    index.search(query, 10)
    search_time = time.time() - start
    
    return {
        "dtype": dtype,
        "add_time": add_time,
        "search_time": search_time,
        "size": len(index)
    }

# 测试不同数据类型性能
results = []
for dtype in [ScalarKind.F32, ScalarKind.F16, ScalarKind.BF16, ScalarKind.I8]:
    results.append(test_performance(dtype))

print("\n不同数据类型性能比较:")
for res in results:
    print(f"{res['dtype']}: 添加时间={res['add_time']:.4f}s, 检索时间={res['search_time']:.4f}s")

数据类型比较

数据类型存储空间精度性能硬件支持
F32所有CPU
F16支持AVX2的CPU
BF16中高现代CPU(Intel Ice Lake+, AMD Zen4+)
I8最高所有CPU

5. 性能优化与最佳实践

5.1 参数调优

HNSW算法的性能和质量受多个参数影响,以下是调优建议:

# 创建优化的索引
optimized_index = Index(
    ndim=256,
    metric=MetricKind.Cos,
    connectivity=32,  # 增加连接数提高召回率
    expansion_add=256,  # 增加添加扩展提高建索引质量
    expansion_search=128  # 增加检索扩展提高召回率
)

参数调优指南

目标调整参数建议值
提高检索速度降低expansion_search16-32
提高召回率提高expansion_search64-256
减少内存占用降低connectivity8-16
提高构建速度降低expansion_add32-64
大型数据集增加connectivity16-32

5.2 批量操作性能

对于大规模数据处理,批量操作比单次操作效率更高:

# 批量添加性能对比
n = 100000
vectors = np.random.rand(n, 128).astype(np.float32)
keys = np.arange(n, dtype=np.uint64)

# 单次添加
start = time.time()
index_single = Index(ndim=128)
index_single.add(keys, vectors, threads=0)
single_time = time.time() - start

# 分批次添加
start = time.time()
index_batch = Index(ndim=128)
batch_size = 10000
for i in range(0, n, batch_size):
    batch_keys = keys[i:i+batch_size]
    batch_vectors = vectors[i:i+batch_size]
    index_batch.add(batch_keys, batch_vectors, threads=0)
batch_time = time.time() - start

print(f"单次添加: {single_time:.4f}s, 分批次添加: {batch_time:.4f}s")

批量操作最佳实践

  • 批量大小设置为1000-10000(根据向量维度调整)
  • 使用多线程加速(threads参数)
  • 对于非常大的数据集,考虑分块处理

5.3 精确检索与近似检索对比

usearch支持精确检索(线性扫描)和近似检索(HNSW),可根据需求选择:

# 生成测试数据
n = 10000
dim = 128
index = Index(ndim=dim)
keys = np.arange(n)
vectors = np.random.rand(n, dim).astype(np.float32)
index.add(keys, vectors)

query = vectors[0]  # 使用第一个向量作为查询

# 近似检索
start = time.time()
approx_results = index.search(query, count=10)
approx_time = time.time() - start

# 精确检索
start = time.time()
exact_results = index.search(query, count=10, exact=True)
exact_time = time.time() - start

# 计算召回率
approx_ids = set(approx_results.keys)
exact_ids = set(exact_results.keys)
recall = len(approx_ids.intersection(exact_ids)) / len(exact_ids)

print(f"近似检索: 时间={approx_time:.4f}s, 召回率={recall:.4f}")
print(f"精确检索: 时间={exact_time:.4f}s")

检索模式选择建议

模式速度准确率适用场景
近似检索(默认)快(毫秒级)高(可调节)大规模数据集、实时应用
精确检索慢(秒级)100%小规模数据集、结果验证

6. 常见问题与解决方案

6.1 内存占用过大

问题:处理大规模数据集时内存占用过高。

解决方案

  • 使用低精度数据类型(如F16BF16I8
  • 启用磁盘内存映射(view()方法)
  • 增加connectivity同时降低expansion_addexpansion_search
# 使用内存映射减少内存占用
index.view("large_index.usearch")  # 仅映射元数据,不加载完整索引

6.2 检索速度慢

问题:检索操作耗时过长,无法满足实时需求。

解决方案

  • 降低expansion_search参数
  • 减少返回结果数量(count参数)
  • 使用低精度数据类型
  • 增加线程数(threads参数)
# 优化检索速度
fast_results = index.search(query, count=5, expansion_search=16, threads=4)

6.3 索引构建时间长

问题:大规模数据集索引构建耗时过长。

解决方案

  • 降低expansion_add参数
  • 增加threads参数使用更多CPU核心
  • 分批次添加并监控进度
# 加速索引构建
index.add(keys, vectors, expansion_add=32, threads=8)

7. 总结与后续学习

7.1 核心功能回顾

本文介绍了usearch Python API的核心功能:

  • 索引创建与配置
  • 向量添加(单向量和批量)
  • 向量检索(精确和近似)
  • 索引持久化与加载
  • 性能优化与参数调优

通过这些功能,你可以快速实现高效的向量检索系统,满足从中小规模到大规模数据集的需求。

7.2 进阶学习路径

掌握基础后,可进一步学习:

  • 自定义距离函数:使用Numba或Cppyy实现自定义距离度量
  • 分布式检索:结合usearch的分布式功能实现大规模集群检索
  • 混合索引:结合其他索引结构(如FAISS)构建混合检索系统
  • 应用集成:与PyTorch/TensorFlow集成实现端到端的向量检索系统

7.3 资源推荐

  • 官方文档usearch GitHub仓库
  • 示例代码:仓库中python/scripts目录下的示例和测试代码
  • 性能基准BENCHMARKS.md文件包含详细性能对比数据
  • 社区支持:通过GitHub Issues提交问题和功能请求

【免费下载链接】usearch Fastest Open-Source Search & Clustering engine × for Vectors & 🔜 Strings × in C++, C, Python, JavaScript, Rust, Java, Objective-C, Swift, C#, GoLang, and Wolfram 🔍 【免费下载链接】usearch 项目地址: https://gitcode.com/gh_mirrors/us/usearch

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

抵扣说明:

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

余额充值