Skip to content

Latest commit

 

History

History
323 lines (240 loc) · 10.3 KB

README_FR.md

File metadata and controls

323 lines (240 loc) · 10.3 KB

Hora

[Homepage] [Document] [Examples]

Hora Search Everywhere!

Hora est un algorithme de recherche du voisin le plus proche approximatif (wiki). Nous implémentons tout le code dans Rust🦀 pour une fiabilité, une abstraction de haut niveau et des vitesses élevées comparables à C++.

Hora, 「ほら」 en japonais, sonne comme [hōlə], et signifie Wow, Vous voyez ! ou Regardez ça !. Le nom est inspiré d'une célèbre chanson japonaise 「小さな恋のうた」.

Démos

👩 Face-Match [online demo], Essaye!

🍷 Recherche de commentaires sur le vin de rêve [online demo], Essaye!

Principales caractéristiques

  • Performant ⚡️

    • SIMD-Accelerated (packed_simd)
    • Implémentation d'algorithme stable
    • Multiple threads design
  • Prend en charge plusieurs langages de programmation Lib ☄️

    • Python
    • Javascript
    • Java
    • Go (WIP)
    • Ruby (WIP)
    • Swift (WIP)
    • R (WIP)
    • Julia (WIP)
    • Peut également être utilisé comme un service
  • Prend en charge plusieurs index 🚀

    • Hierarchical Navigable Small World Graph Index (HNSWIndex) (details)
    • Satellite System Graph (SSGIndex) (details)
    • Product Quantization Inverted File(PQIVFIndex) (details)
    • Random Projection Tree(RPTIndex) (LSH, WIP)
    • BruteForce (BruteForceIndex) (naive implementation with SIMD)
  • Portable 💼

    • Supports WebAssembly
    • Supports Windows, Linux and OS X
    • Supports IOS and Android (WIP)
    • Supports no_std (WIP, partial)
    • Pas de dépendances lourdes, telles que BLAS
  • Fiabilité 🔒

    • Le compilateur Rust sécurise tout le code
    • Mémoire gérée par Rust pour toutes les bibliothèques de langage telles que Python's
    • Large couverture de test
  • Prend en charge plusieurs distances 🧮

    • Distance du produit de point
      • equation
    • Distance euclidienne
      • equation
    • Distance de Manhattan
      • equation
    • Similitude de cosinus
      • equation
  • Productive

    • Bien documenté
    • API élégante, simple et facile à apprendre

Installation

Rust

in Cargo.toml

[dependencies]
hora = "0.1.1"

Python

$ pip install horapy

Javascript (WebAssembly)

$ npm i horajs

Building from source

$ git clone https://github.com/hora-search/hora
$ cargo build

Repères

by aws t2.medium (CPU: Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz) more information

Exemples

Rust exemple [more info]

use hora::core::ann_index::ANNIndex;
use rand::{thread_rng, Rng};
use rand_distr::{Distribution, Normal};

pub fn demo() {
    let n = 1000;
    let dimension = 64;

    // make sample points
    let mut samples = Vec::with_capacity(n);
    let normal = Normal::new(0.0, 10.0).unwrap();
    for _i in 0..n {
        let mut sample = Vec::with_capacity(dimension);
        for _j in 0..dimension {
            sample.push(normal.sample(&mut rand::thread_rng()));
        }
        samples.push(sample);
    }

    // init index
    let mut index = hora::index::hnsw_idx::HNSWIndex::<f32, usize>::new(
        dimension,
        &hora::index::hnsw_params::HNSWParams::<f32>::default(),
    );
    for (i, sample) in samples.iter().enumerate().take(n) {
        // add point
        index.add(sample, i).unwrap();
    }
    index.build(hora::core::metrics::Metric::Euclidean).unwrap();

    let mut rng = thread_rng();
    let target: usize = rng.gen_range(0..n);
    // 523 has neighbors: [523, 762, 364, 268, 561, 231, 380, 817, 331, 246]
    println!(
        "{:?} has neighbors: {:?}",
        target,
        index.search(&samples[target], 10) // search for k nearest neighbors
    );
}

merci @vaaaaanquish pour cette recherche complète d'images de rouille pure [exemple] (https://github.com/vaaaaanquish/rust-ann-search-example), Pour plus d'informations sur cet exemple, veuillez cliquer sur Pure Rustな近似最近傍 horaを用いた画像検索を実装する

Python exemple [more info]

import numpy as np
from horapy import HNSWIndex

dimension = 50
n = 1000

# init index instance
index = HNSWIndex(dimension, "usize")

samples = np.float32(np.random.rand(n, dimension))
for i in range(0, len(samples)):
    # add node
    index.add(np.float32(samples[i]), i)

index.build("euclidean")  # build index

target = np.random.randint(0, n)
# 410 in Hora ANNIndex <HNSWIndexUsize> (dimension: 50, dtype: usize, max_item: 1000000, n_neigh: 32, n_neigh0: 64, ef_build: 20, ef_search: 500, has_deletion: False)
# has neighbors: [410, 736, 65, 36, 631, 83, 111, 254, 990, 161]
print("{} in {} \nhas neighbors: {}".format(
    target, index, index.search(samples[target], 10)))  # search

JavaScript exemple [more info]

import * as horajs from "horajs";

const demo = () => {
    const dimension = 50;
    var bf_idx = horajs.BruteForceIndexUsize.new(dimension);
    // var hnsw_idx = horajs.HNSWIndexUsize.new(dimension, 1000000, 32, 64, 20, 500, 16, false);
    for (var i = 0; i < 1000; i++) {
        var feature = [];
        for (var j = 0; j < dimension; j++) {
            feature.push(Math.random());
        }
        bf_idx.add(feature, i); // add point
    }
    bf_idx.build("euclidean"); // build index
    var feature = [];
    for (var j = 0; j < dimension; j++) {
        feature.push(Math.random());
    }
    console.log("bf result", bf_idx.search(feature, 10)); //bf result Uint32Array(10) [704, 113, 358, 835, 408, 379, 117, 414, 808, 826]
}

(async () => {
    await horajs.default();
    await horajs.init_env();
    demo();
})();

Java exemple [more info]

public void demo() {
    final int dimension = 2;
    final float variance = 2.0f;
    Random fRandom = new Random();

    BruteForceIndex bruteforce_idx = new BruteForceIndex(dimension); // init index instance

    List<float[]> tmp = new ArrayList<>();
    for (int i = 0; i < 5; i++) {
        for (int p = 0; p < 10; p++) {
            float[] features = new float[dimension];
            for (int j = 0; j < dimension; j++) {
                features[j] = getGaussian(fRandom, (float) (i * 10), variance);
            }
            bruteforce_idx.add("bf", features, i * 10 + p); // add point
            tmp.add(features);
          }
    }
    bruteforce_idx.build("bf", "euclidean"); // build index

    int search_index = fRandom.nextInt(tmp.size());
    // nearest neighbor search
    int[] result = bruteforce_idx.search("bf", 10, tmp.get(search_index));
    // [main] INFO com.hora.app.ANNIndexTest  - demo bruteforce_idx[7, 8, 0, 5, 3, 9, 1, 6, 4, 2]
    log.info("demo bruteforce_idx" + Arrays.toString(result));
}

private static float getGaussian(Random fRandom, float aMean, float variance) {
    float r = (float) fRandom.nextGaussian();
    return aMean + r * variance;
}

Feuille de route

  • Couverture complète des tests
  • Implémentez l'algorithme EFANNA pour obtenir une création de graphes KNN plus rapide
  • Prise en charge Swift et exemple de déploiement iOS/macOS
  • Support R
  • support mmap

Projets connexes et comparaison

  • Faiss, Annoy, ScaNN:

    • L'implémentation de Hora est fortement inspirée de ces bibliothèques.
    • Faiss se concentre davantage sur la scène GPU, et Hora est plus léger que Faiss (pas de dépendances lourdes).
    • Hora s'attend à prendre en charge plus de langues, et tout ce qui concerne les performances sera implémenté par Rust🦀.
    • Annoy ne prend en charge que l'algorithme LSH (Random Projection).
    • ScaNN et Faiss sont moins conviviaux (par exemple, manque de documentation).
    • Hora is ALL IN RUST 🦀.
  • Milvus, Vald, Jina AI

    • Milvus et Vald prennent également en charge plusieurs langues, mais servent de service au lieu d'une bibliothèque
    • Milvus est construit sur certaines bibliothèques telles que Faiss, tandis que Hora est une bibliothèque avec tous les algorithmes implémentés elle-même

Contribute

Nous apprécions votre aide!

Nous sommes ravis de votre participation, toutes les contributions sont les bienvenues, y compris les documentations et les tests. Vous pouvez créer une Pull Request ou un Issue sur GitHub, et nous l'examinerons dès que possible.

Nous utilisons les problèmes GitHub pour suivre les suggestions et les bogues.

Clone the repo

git clone https://github.com/hora-search/hora

Build

cargo build

Test

cargo test --lib

Try the changes

cd examples
cargo run

License

The entire repository is licensed under the Apache License.