metta-faiss 0.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,33 @@
1
+ Metadata-Version: 2.4
2
+ Name: metta-faiss
3
+ Version: 0.9.0
4
+ Summary: faiss as a nearest-neighbour backend for a MeTTa embedding store
5
+ License-Expression: MIT
6
+ Classifier: Development Status :: 3 - Alpha
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Intended Audience :: Science/Research
9
+ Requires-Python: >=3.12
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: pymetta==0.8.0
12
+ Requires-Dist: faiss-cpu
13
+ Requires-Dist: numpy
14
+
15
+ # metta-faiss
16
+
17
+ faiss as a nearest-neighbour backend for a MeTTa embedding store.
18
+
19
+ `pymetta` names no third-party library. This package is one row against the `index` point, and the seat
20
+ finds it exactly as it finds a package written by somebody else: through the
21
+ `metta.extensions` entry point, loaded at the first dispatch that has no answer
22
+ without it, or through `import metta_faiss`, whose module body registers the same
23
+ rows.
24
+
25
+ ```sh
26
+ pip install metta-faiss # or: pip install 'pymetta[arrays]'
27
+ ```
28
+
29
+ Its tests are in `tests/`, and they run in the workspace suite:
30
+
31
+ ```sh
32
+ sh extensions/python/test.sh ext/metta-faiss
33
+ ```
@@ -0,0 +1,6 @@
1
+ metta_faiss.py,sha256=FeiZpH0fmb9SRYwEEBsf6x1LCLp75E9wR8GO62zbFfU,3083
2
+ metta_faiss-0.9.0.dist-info/METADATA,sha256=s0oNkR9k-VqcUu4feX6oa6XKgc4hiud16KrwQ8fAmXk,1068
3
+ metta_faiss-0.9.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
4
+ metta_faiss-0.9.0.dist-info/entry_points.txt,sha256=ahP6XClBTPiBWg6Mbx8bsxg6CXRcAB9sCXBtgGKh3OA,45
5
+ metta_faiss-0.9.0.dist-info/top_level.txt,sha256=tM7Yb1N2mt3vDHsqEMiUG4kM4gxcl-Cw6W7pTX7Bi3M,12
6
+ metta_faiss-0.9.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [metta.extensions]
2
+ metta-faiss = metta_faiss
@@ -0,0 +1 @@
1
+ metta_faiss
metta_faiss.py ADDED
@@ -0,0 +1,86 @@
1
+ """Purpose: faiss as a nearest-neighbour backend of the MeTTa Python seat.
2
+
3
+ One row against the seat's `index` point, so an embedding store searches
4
+ through faiss when this package is installed. The row is NOT a fallback, which
5
+ is what makes `backend="auto"` prefer it over the generic Array API path
6
+ whatever order the two distributions loaded in; entry-point order is not
7
+ something a package can arrange.
8
+
9
+ NumPy is a dependency here and is not an integration: faiss' own interface
10
+ takes contiguous float32 NumPy arrays for `add` and `search`, so staging one is
11
+ part of calling faiss at all, and faiss-cpu depends on NumPy itself.
12
+
13
+ Assumes:
14
+ - a normalized matrix, which is the `index` point's contract: the backend
15
+ searches inner products and the store normalizes before it gets here
16
+ Guarantees:
17
+ - `available()` answers False rather than raising when faiss is absent, so
18
+ an embedding store falls through to the next backend instead of failing
19
+ [tested: tests/test_faiss.py::test_an_absent_faiss_declines_rather_than_raising;
20
+ commit=94057a0f073c0fab0a35c42beff2c324d8a0addd]
21
+ - faiss wins `backend="auto"` over the Array API fallback in either load
22
+ order [tested: tests/test_faiss.py::test_faiss_wins_auto_over_the_array_api_fallback;
23
+ commit=94057a0f073c0fab0a35c42beff2c324d8a0addd]
24
+ Open Obligations:
25
+ To Do: None
26
+ Hacks: None
27
+ Future Enhancements: None
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ from typing import Any, Final
33
+
34
+ from metta import seam
35
+
36
+ _MISSING: Final = (
37
+ "the faiss embedding backend needs faiss-cpu; install pymetta[arrays]"
38
+ )
39
+ _NUMPY_MISSING: Final = (
40
+ "the faiss embedding backend stages its matrix as a contiguous float32 "
41
+ "NumPy array, which is faiss' own interface, and NumPy is not installed; "
42
+ "install pymetta[arrays]"
43
+ )
44
+
45
+ require_module = seam.at("module").call()
46
+ optional_module = seam.at("optional-module").call()
47
+
48
+
49
+ def _available() -> bool:
50
+ """Whether faiss can run here."""
51
+ return optional_module("faiss") is not None
52
+
53
+
54
+ def _build(matrix: Any) -> Any:
55
+ """An exact inner-product index over the normalized matrix."""
56
+ faiss = require_module("faiss", _MISSING)
57
+ numpy = require_module("numpy", _NUMPY_MISSING)
58
+ staged = numpy.ascontiguousarray(numpy.asarray(matrix, dtype=numpy.float32))
59
+ index = faiss.IndexFlatIP(staged.shape[1])
60
+ index.add(staged)
61
+ return index
62
+
63
+
64
+ def _search(index: Any, query: Any, count: int) -> list[tuple[int, float]]:
65
+ """(row, score) pairs best first, from the built index."""
66
+ numpy = require_module("numpy", _NUMPY_MISSING)
67
+ probe = numpy.ascontiguousarray(numpy.asarray(query, dtype=numpy.float32).reshape(1, -1))
68
+ scores, indexes = index.search(probe, count)
69
+ return [
70
+ (int(index), float(score))
71
+ for score, index in zip(scores[0], indexes[0], strict=True)
72
+ ]
73
+
74
+
75
+ def register() -> None:
76
+ """This package's one row, against the seat's `index` point."""
77
+ seam.index.register(
78
+ "faiss",
79
+ available=_available,
80
+ build=_build,
81
+ search=_search,
82
+ missing=_MISSING,
83
+ )
84
+
85
+
86
+ register()