Extending CARA¶
CARA has two extension points, encoders and grouping methods. Each is one module, and CARA imports every module in those folders, so nothing else needs to change.
A grouping method¶
Add a module to backend/src/cara/grouping/ with one GroupingMethod subclass, decorated with @register. It needs a
method key, its settings, a label and a partition. This minimal example makes groups of a fixed size:
"""Fixed chunks: groups of `size` images, in the order of the embeddings."""
from typing import Literal
import numpy as np
import numpy.typing as npt
from pydantic import Field
from cara.grouping.base import GroupingMethod, register
@register
class Chunks(GroupingMethod):
method: Literal["chunks"]
size: int = Field(default=8, ge=2)
def label(self) -> str:
return f"chunks of {self.size}"
def partition(self, emb_nd: npt.NDArray[np.float32]) -> list[list[int]]:
rows = list(range(len(emb_nd)))
return [rows[i : i + self.size] for i in range(0, len(rows), self.size)]
A study can then use it with grouping: {method: chunks, size: 8}. CARA does the shared steps itself: it sets aside the
ungrouped images, caps each group at max_size, and orders the groups by similarity to the query.
To compare the method in the simulator as well, add its options to services/simulator/plan.py.
An encoder¶
| To add | Change |
|---|---|
| A Hugging Face model | Nothing: use encoder: hf-cls:<model id> (DINO-style) or hf-dual:<model id> (CLIP-style). |
| A short name for a Hugging Face model | A module like encoders/clip.py: a subclass of ClsEncoder or DualEncoder with name, default_model_id and @register. |
| Another family, such as timm or OpenCLIP | A module in backend/src/cara/encoders/ with one Encoder subclass and @register. It needs name and encode_images, and encode_texts if it reads text (see base.py). |
Other changes¶
| To add | Change |
|---|---|
| An export | A function in core/export.py and a branch in services/admin.py. |
| Another front end | A client for the API. Its schema is at http://localhost:8000/docs. |