Skip to content

Configuration

Configuration options for HNSW index.

Attributes:

Name Type Description
max_connections int

Maximum connections per node (M parameter). Higher = better recall, more memory. Default: 16

ef_construction int

Construction quality parameter. Higher = better index quality, slower build. Default: 200

ef_search int

Search quality parameter. Higher = better search quality, slower search. Default: 50

metric str

"euclidean" (L2) or "cosine" (1 - cosine similarity; vectors are stored at unit length and zero vectors are rejected). Fixed when the index is created. Default: "euclidean"

precision str

"full" keeps each component of a vector as a 32-bit float, "half" as a 16-bit float: half the file and half the memory, each component rounded to about three decimal digits, and a vector with a component of 65,520 or more in magnitude refused. Fixed when the index is created; a read-only index takes it from the file. Default: "full"

huge_pages bool

Ask the operating system to keep the vectors on huge pages. On an index too large for the CPU's caches, searches are up to a quarter faster. Only on Linux, and only where the kernel and filesystem keep files on huge pages (ext4 on Linux 6.17 does); elsewhere it does nothing. With it a page not yet in memory is read 2 MB at a time, which an index much larger than memory pays for on every miss. Default: False

warm bool

Read the whole index into memory on another thread from the moment it is opened, so that searches stop waiting for the disk one page at a time. For an index that fits in memory. It takes Linux 5.14 or macOS: an older Linux reads only some of the index, and Windows none. Default: False

Source code in chassisdb/index.py
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
@dataclass
class IndexOptions:
    """Configuration options for HNSW index.

    Attributes:
        max_connections: Maximum connections per node (M parameter).
            Higher = better recall, more memory. Default: 16
        ef_construction: Construction quality parameter.
            Higher = better index quality, slower build. Default: 200
        ef_search: Search quality parameter.
            Higher = better search quality, slower search. Default: 50
        metric: "euclidean" (L2) or "cosine" (1 - cosine similarity; vectors
            are stored at unit length and zero vectors are rejected). Fixed
            when the index is created. Default: "euclidean"
        precision: "full" keeps each component of a vector as a 32-bit float,
            "half" as a 16-bit float: half the file and half the memory, each
            component rounded to about three decimal digits, and a vector with
            a component of 65,520 or more in magnitude refused. Fixed when the
            index is created; a read-only index takes it from the file.
            Default: "full"
        huge_pages: Ask the operating system to keep the vectors on huge
            pages. On an index too large for the CPU's caches, searches are
            up to a quarter faster. Only on Linux, and only where the kernel and
            filesystem keep files on huge pages (ext4 on Linux 6.17 does);
            elsewhere it does nothing. With it a page not yet in memory is
            read 2 MB at a time, which an index much larger than memory pays
            for on every miss. Default: False
        warm: Read the whole index into memory on another thread from the
            moment it is opened, so that searches stop waiting for the disk
            one page at a time. For an index that fits in memory. It takes
            Linux 5.14 or macOS: an older Linux reads only some of the
            index, and Windows none. Default: False
    """

    max_connections: int = 16
    ef_construction: int = 200
    ef_search: int = 50
    metric: str = "euclidean"
    precision: str = "full"
    huge_pages: bool = False
    warm: bool = False

    def validate(self) -> None:
        """Check the options, and spell metric and precision as Chassis does:
        "L2" becomes "euclidean" and "float16" becomes "half".

        Raises:
            InvalidArgumentError: If an option is out of range or unknown
            TypeError: If an option has the wrong type
        """
        for name in ("max_connections", "ef_construction", "ef_search"):
            _check_int(name, getattr(self, name))
        if not 2 <= self.max_connections <= 32767:
            raise InvalidArgumentError(
                f"max_connections is {self.max_connections}, but has to be between 2 and "
                "32,767\nhelp: 16 suits most indexes; 32 gives higher recall for more memory"
            )
        for name in ("ef_construction", "ef_search"):
            if getattr(self, name) < 1:
                raise InvalidArgumentError(
                    f"{name} is {getattr(self, name)}, but has to be at least 1\nhelp: higher "
                    f"finds more of the true nearest for more time; the default is "
                    f"{getattr(IndexOptions(), name)}"
                )
        self.metric = _named("metric", self.metric, _METRICS, _METRIC_NAMES)
        self.precision = _named("precision", self.precision, _PRECISIONS, _PRECISION_NAMES)

validate()

Check the options, and spell metric and precision as Chassis does: "L2" becomes "euclidean" and "float16" becomes "half".

Raises:

Type Description
InvalidArgumentError

If an option is out of range or unknown

TypeError

If an option has the wrong type

Source code in chassisdb/index.py
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
def validate(self) -> None:
    """Check the options, and spell metric and precision as Chassis does:
    "L2" becomes "euclidean" and "float16" becomes "half".

    Raises:
        InvalidArgumentError: If an option is out of range or unknown
        TypeError: If an option has the wrong type
    """
    for name in ("max_connections", "ef_construction", "ef_search"):
        _check_int(name, getattr(self, name))
    if not 2 <= self.max_connections <= 32767:
        raise InvalidArgumentError(
            f"max_connections is {self.max_connections}, but has to be between 2 and "
            "32,767\nhelp: 16 suits most indexes; 32 gives higher recall for more memory"
        )
    for name in ("ef_construction", "ef_search"):
        if getattr(self, name) < 1:
            raise InvalidArgumentError(
                f"{name} is {getattr(self, name)}, but has to be at least 1\nhelp: higher "
                f"finds more of the true nearest for more time; the default is "
                f"{getattr(IndexOptions(), name)}"
            )
    self.metric = _named("metric", self.metric, _METRICS, _METRIC_NAMES)
    self.precision = _named("precision", self.precision, _PRECISIONS, _PRECISION_NAMES)

A single search result.

Attributes:

Name Type Description
id int

Vector ID in the index

distance float

Distance to the query vector (lower is closer)

Source code in chassisdb/index.py
152
153
154
155
156
157
158
159
160
161
162
163
164
165
@dataclass
class SearchResult:
    """A single search result.

    Attributes:
        id: Vector ID in the index
        distance: Distance to the query vector (lower is closer)
    """

    id: int
    distance: float

    def __repr__(self) -> str:
        return f"SearchResult(id={self.id}, distance={self.distance:.6f})"