Package: usearch
USearchSmaller &FasterSingle-FileSimilarity Search Engine forVectors& 🔜TextsSpatial • Binary • Probabilistic • User-Defined MetricsC++ 11•Python 3•JavaScript•Java•Rust•C 99•Objective-C•Swift•C#•GoLang•Wolfram•SQLite3Linux • MacOS • Windows • iOS • WebAssembly✅10x fasterHNSWimplementation thanFAISS.✅ Simple and extensiblesingle C++11 headerlibrary.✅ Compatible with a dozen programming languages out of the box.✅Trustedby giants like Google and databases likeClickHouse.✅SIMD-optimized anduser-defined metricswith JIT compilation.✅ Hardware-agnosticf16&i8-half-precision & quarter-precision support.✅View large indexes from diskwithout loading into RAM.✅ Heterogeneous lookups, renaming/relabeling, and on-the-fly deletions.✅ Variable dimensionality vectors for unique applications, including search over compressed data.✅ Binary Tanimoto and Sorensen coefficients forGenomics and Chemistry applications.✅ Space-efficient point-clouds withuint40_t, accommodating 4B+ size.✅ Compatible with OpenMP and custom "executors" for fine-grained control over CPU utilization.✅ Near-real-timeclustering and sub-clusteringfor Tens or Millions of clusters.✅Semantic SearchandJoins.Technical Insightsand related articles:Uses Horner's method for polynomial approximations, beating GCC 12 by 119x.Uses Arm SVE and x86 AVX-512's masked loads to eliminate tailfor-loops.Uses AVX-512 FP16 for half-precision operations, that few compilers vectorize.Substitutes LibC'ssqrtcalls with bithacks using Jan Kadlec's constant.For every language implements a custom separate binding.For Python avoids slow PyBind11, and evenPyArg_ParseTuplefor speed.For JavaScript uses typed arrays and NAPI for zero-copy calls.Comparison with FAISSFAISS is a widely recognized standard for high-performance vector search engines.
USearch and FAISS both employ the same HNSW algorithm, but they differ significantly in their design principles.
USearch is compact and broadly compatible without sacrificing performance, primarily focusing on user-defined metrics and fewer dependencies.FAISSUSearchImprovementIndexing time ⁰100 Million 96df32,f16,i8vectors2.6 · 2.6 · 2.6 h0.3 · 0.2 · 0.2 h9.6 · 10.4 · 10.7 x100 Million 1536df32,f16,i8vectors5.0 · 4.1 · 3.8 h2.1 · 1.1 · 0.8 h2.3 · 3.6 · 4.4 xCodebase length ¹84 KSLOC3 KSLOCmaintainableSupported metrics ²9 fixed metricsany metricextendibleSupported languages ³C++, Python10 languagesportableSupported ID types ⁴32-bit, 64-bit32-bit, 40-bit, 64-bitefficientRequired dependencies ⁵BLAS, OpenMP-light-weightBindings ⁶SWIGNativelow-latencyPython binding size ⁷~ 10 MB< 1 MBdeployable⁰Testedon Intel Sapphire Rapids, with the simplest inner-product distance, equivalent recall, and memory consumption while also providing far superior search speed.
¹ A shorter codebase ofusearch/overfaiss/makes the project easier to maintain and audit.
² User-defined metrics allow you to customize your search for various applications, from GIS to creating custom metrics for composite embeddings from multiple AI models or hybrid full-text and semantic search.
³ With USearch, you can reuse the same preconstructed index in various programming languages.
⁴ The 40-bit integer allows you to store 4B+ vectors without allocating 8 bytes for every neighbor reference in the proximity graph.
⁵ Lack of obligatory dependencies makes USearch much more portable.
⁶ Native bindings introduce lower call latencies than more straightforward approaches.
⁷ Lighter bindings make downloads and deployments faster.Base functionality is identical to FAISS, and the interface must be familiar if you have ever investigated Approximate Nearest Neighbors search:$pipinstallnumpyusearchimportnumpyasnpfromusearch.indeximportIndexindex=Index(ndim=3)vector=np.array([0.2,0.6,0.4])index.add(42,vector)matches=index.search(vector,10)assertmatches[0].key==42assertmatches[0].distance<=0.001assertnp.allclose(index[42],vector)More settings are always available, and the API is designed to be as flexible as possible.index=Index(ndim=3,# Define the number of dimensions in input vectorsmetric='cos',# Choose 'l2sq', 'haversine' or other metric, default = 'ip'dtype='f32',# Quantize to 'f16' or 'i8' if needed, default = 'f32'connectivity=16,# Optional: Limit number of neighbors per graph nodeexpansion_add=128,# Optional: Control the recall of indexingexpansion_search=64,# Optional: Control the quality of the searchmulti=False,# Optional: Allow multiple vectors per key, default = False)Serialization & ServingIndexfrom DiskUSearch supports multiple forms of serialization:Into afiledefined with a path.Into astreamdefined with a callback, serializing or reconstructing incrementally.Into abufferof fixed length or a memory-mapped file that supports random access.The latter allows you to serve indexes from external memory, enabling you to optimize your server choices for indexing speed and serving costs.
This can result in20x cost reductionon AWS and other public clouds.index.save("index.usearch")loaded_copy=index.load("index.usearch")view=Index.restore("index.usearch",view=True)other_view=Index(ndim=...,metric=...)other_view.view("index.usearch")Exact vs. Approximate SearchApproximate search methods, such as HNSW, are predominantly used when an exact brute-force search becomes too resource-intensive.
This typically occurs when you have millions of entries in a collection.
For smaller collections, we offer a more direct approach with thesearchmethod.fromusearch.indeximportsearch,MetricKind,Matches,BatchMatchesimportnumpyasnp# Generate 10'000 random vectors with 1024 dimensionsvectors=np.random.rand(10_000,1024).astype(np.float32)vector=np.random.rand(1024).astype(np.float32)one_in_many:Matches=search(vectors,vector,50,MetricKind.L2sq,exact=True)many_in_many:BatchMatches=search(vectors,vectors,50,MetricKind.L2sq,exact=True)If you pass theexact=Trueargument, the system bypasses indexing altogether and performs a brute-force search through the entire dataset using SIMD-optimized similarity metrics fromSimSIMD.
When compared to FAISS'sIndexFlatL2in Google Colab,USearch may offer up to a 20x performance improvement:faiss.IndexFlatL2:55.3 ms.usearch.index.search:2.54 ms.Indexesfor Multi-Index LookupsFor larger workloads targeting billions or even trillions of vectors, parallel multi-index lookups become invaluable.
Instead of constructing one extensive index, you can build multiple smaller ones and view them together.fromusearch.indeximportIndexesmulti_index=Indexes(indexes:Iterable[usearch.index.Index]=[...],paths:Iterable[os.PathLike]=[...],view:bool=False,threads:int=0,)multi_index.search(...)ClusteringOnce the index is constructed, USearch can perform K-Nearest Neighbors Clustering much faster than standalone clustering libraries, like SciPy,
UMap, and tSNE.
Same for dimensionality reduction with PCA.
Essentially, theIndexitself can be seen as a clustering, allowing iterative deepening.clustering=index.cluster(min_count=10,# Optionalmax_count=15,# Optionalthreads=...,# Optional)# Get the clusters and their sizescentroid_keys,sizes=clustering.centroids_popularity# Use Matplotlib to draw a histogramclustering.plot_centroids_popularity()# Export a NetworkX graph of the clustersg=clustering.network# Get members of a specific clusterfirst_members=clustering.members_of(centroid_keys[0])# Deepen into that cluster, splitting it into more parts, all the same arguments supportedsub_clustering=clustering.subcluster(min_count=...,max_count=...)The resulting clustering isn't identical to K-Means or other conventional approaches but serves the same purpose.
Alternatively, using Scikit-Learn on a 1 Million point dataset, one may expect queries to take anywhere from minutes to hours, depending on the number of clusters you want to highlight.
For 50'000 clusters, the performance difference between USearch and conventional clustering methods may easily reach 100x.Joins, One-to-One, One-to-Many, and Many-to-Many MappingsOne of the big questions these days is how AI will change the world of databases and data management.
Most databases are still struggling to implement high-quality fuzzy search, and the only kind of joins they know are deterministic.
Ajoindiffers from searching for every entry, requiring a one-to-one mapping banning collisions among separate search results.Exact SearchFuzzy SearchSemantic Search ?Exact JoinFuzzy Join ?Semantic Join ??Using USearch, one can implement sub-quadratic complexity approximate, fuzzy, and semantic joins.
This can be useful in any fuzzy-matching tasks common to Database Management Software.men=Index(...)women=Index(...)pairs:dict=men.join(women,max_proposals=0,exact=False)Read more in the post:Combinatorial Stable Marriages for Semantic Search 💍User-Defined FunctionsWhile most vector search packages concentrate on just a few metrics - "Inner Product distance" and "Euclidean distance," USearch extends this list to include any user-defined metrics.
This flexibility allows you to customize your search for various applications, from computing geospatial coordinates with the rareHaversinedistance to creating custom metrics for composite embeddings from multiple AI models.Unlike older approaches indexing high-dimensional spaces, like KD-Trees and Locality Sensitive Hashing, HNSW doesn't require vectors to be identical in length.
They only have to be comparable.
So you can apply it inobscureapplications, like searching for similar sets or fuzzy text matching, usingGZipas a distance function.Read more aboutJIT and UDF in USearch Python SDK.Memory Efficiency, Downcasting, and QuantizationTraining a quantization model and dimension-reduction is a common approach to accelerate vector search.
Those, however, are only sometimes reliable, can significantly affect the statistical properties of your data, and require regular adjustments if your distribution shifts.
Instead, we have focused on high-precision arithmetic over low-precision downcasted vectors.
The same index, andaddandsearchoperations will automatically down-cast or up-cast betweenf64_t,f32_t,f16_t,i8_t, and single-bit representations.
You can use the following command to check, if hardware acceleration is enabled:$python-c'from usearch.index import Index; print(Index(ndim=768, metric="cos", dtype="f16").hardware_acceleration)'>avx512+f16
$python-c'from usearch.index import Index; print(Index(ndim=166, metric="tanimoto").hardware_acceleration)'>avx512+popcntUsing smaller numeric types will save you RAM needed to store the vectors, but you can also compress the neighbors lists forming our proximity graphs.
By default, 32-bituint32_tis used to enumerate those, which is not enough if you need to address over 4 Billion entries.
For such cases we provide a customuint40_ttype, that will still be 37.5% more space-efficient than the commonly used 8-byte integers, and will scale up to 1 Trillion entries.FunctionalityBy now, the core functionality is supported across all bindings.
Broader functionality is ported per request.
In some cases, like Batch operations, feature parity is meaningless, as the host language has full multi-threading capabilities and the USearch index structure is concurrent by design, so the users can implement batching/scheduling/load-balancing in the most optimal way for their applications.C++ 11Python 3C 99JavaJavaScriptRustGoLangSwiftAdd, search, remove✅✅✅✅✅✅✅✅Save, load, view✅✅✅✅✅✅✅✅User-defined metrics✅✅✅❌❌❌❌❌Batch operations❌✅❌❌✅❌❌❌Joins✅✅❌❌❌❌❌❌Variable-length vectors✅❌❌❌❌❌❌❌4B+ capacities✅❌❌❌❌❌❌❌Application ExamplesUSearch + AI = Multi-Modal Semantic SearchAI has a growing number of applications, but one of the coolest classic ideas is to use it for Semantic Search.
One can take an encoder model, like the multi-modalUForm, and a web-programming framework, like UCall, and build a text-to-image search platform in just 20 lines of Python.importucallimportuformimportusearchimportnumpyasnpimportPILaspilserver=ucall.Server()model=uform.get_model('unum-cloud/uform-vl-multilingual')index=usearch.index.Index(ndim=256)@serverdefadd(key:int,photo:pil.Image.Image):image=model.preprocess_image(photo)vector=model.encode_image(image).detach().numpy()index.add(key,vector.flatten(),copy=True)@serverdefsearch(query:str)->np.ndarray:tokens=model.preprocess_text(query)vector=model.encode_text(tokens).detach().numpy()matches=index.search(vector.flatten(),3)returnmatches.keysserver.run()A more completedemo with Streamlit is available on GitHub.
We have pre-processed some commonly used datasets, cleaned the images, produced the vectors, and pre-built the index.DatasetModalitiesImagesDownloadUnsplashImages & Descriptions25 KHuggingFace / UnumConceptual CaptionsImages & Descriptions3 MHuggingFace / UnumArxivTitles & Abstracts2 MHuggingFace / UnumUSearch + RDKit = Molecular SearchComparing molecule graphs and searching for similar structures is expensive and slow.
It can be seen as a special case of the NP-Complete Subgraph Isomorphism problem.
Luckily, domain-specific approximate methods exist.
The one commonly used in Chemistry is to generate structures fromSMILESand later hash them into binary fingerprints.
The latter are searchable with binary similarity metrics, like the Tanimoto coefficient.
Below is an example using the RDKit package.fromusearch.indeximportIndex,MetricKindfromrdkitimportChemfromrdkit.ChemimportAllChemimportnumpyasnpmolecules=[Chem.MolFromSmiles('CCOC'),Chem.MolFromSmiles('CCO')]encoder=AllChem.GetRDKitFPGenerator()fingerprints=np.vstack([encoder.GetFingerprint(x)forxinmolecules])fingerprints=np.packbits(fingerprints,axis=1)index=Index(ndim=2048,metric=MetricKind.Tanimoto)keys=np.arange(len(molecules))index.add(keys,fingerprints)matches=index.search(fingerprints,10)That method was used to build the"USearch Molecules", one of the largest Chem-Informatics datasets, containing 7 billion small molecules and 28 billion fingerprints.USearch + POI Coordinates = GIS Applications... on iOS?With Objective-C and Swift iOS bindings, USearch can be easily used in mobile applications.
TheSwiftVectorSearchproject illustrates how to build a dynamic, real-time search system on iOS.
In this example, we use 2-dimensional vectors—encoded as latitude and longitude—to find the closest Points of Interest (POIs) on a map.
The search is based on the Haversine distance metric but can easily be extended to support high-dimensional vectors.IntegrationsGPTCache:Python.LangChain:PythonandJavaScript.ClickHouse:C++.Microsoft Semantic Kernel:Pythonand C#.LanternDB:C++andRust.Citations@software{Vardanian_USearch_2023,
doi = {10.5281/zenodo.7949416},
author = {Vardanian, Ash},
title = {{USearch by Unum Cloud}},
url = {https://github.com/unum-cloud/usearch},
version = {2.9.1},
year = {2023},
month = oct,
}