AgentCanvas / Pages / Developer Guide / Nodesets / Model / AIMv2 NodeSet
2026-07-08

The AIMv2 NodeSet (Aimv2NodeSet, workspace/nodesets/model/model_aimv2.py) wraps AIMv2 (Apple) as a second self-supervised per-image feature backbone alongside DINOv2. It fills the same graph role β€” a generic per-image descriptor with no language head β€” but comes from a different pre-training recipe, so its feature geometry differs and it is worth having both when a downstream head is sensitive to the backbone.

env: ac-fm Β· backend: transformers AutoModel (Aimv2VisionModel) + AutoImageProcessor Β· default model_id: apple/aimv2-large-patch14-224 (1024-d)

Primitive Purpose
model_aimv2__extract_features Mean-pooled embedding per image: list of {rgb_base64} (or raw base64) β†’ features (TEXT β€” base64-npy JSON envelope of the (N, D) float32 matrix).

1. A second self-supervised backbone

AIMv2 is trained autoregressively: a multimodal decoder predicts image patches (and text), a different objective from DINOv2's self-distillation. The two backbones therefore land in different feature spaces even though both are label-free per-image ViTs with no notion of language. Neither is universally better β€” which one transfers best depends on the downstream head β€” so the graph keeps both available and picks per experiment.

Like DINOv2, AIMv2 has no language head: it produces a visual descriptor, not a shared image–text embedding. For language-aligned embeddings (open-vocab maps, zero-shot retrieval) reach for CLIP instead.


2. Mean-pooled descriptor & envelope

The AIMv2 vision tower emits per-patch tokens (N, P, D) with no CLS / pooler token. The per-image descriptor here is therefore the mean over the patch tokens of last_hidden_state β€” the standard global-feature reduction for a CLS-less ViT:

feats = model(pixel_values=pixel_values).last_hidden_state  # (N, P, D)
feats = feats.mean(dim=1)  # (N, D)

Features are not L2-normalized β€” they are raw pooled activations. Normalize downstream if a cosine metric is wanted. The output is a TEXT JSON envelope carrying the raw C-contiguous float32 buffer base64-encoded (DINOv2/CLIP's sibling format, plus model_id + a pooled self-description):

{"shape": [N, 1024], "dtype": "float32", "b64": "<base64 of the C-contiguous float32 buffer>", "model_id": "apple/aimv2-large-patch14-224", "pooled": "mean"}

Byte-exact across the server-mode HTTP boundary β€” a plain JSON float list would round-trip every value through decimal text β€” and ~4Γ— smaller. The large default gives D = 1024.


3. Canvas Nodes

model_aimv2__extract_features

Field Detail
Inputs images (ANY β€” list of {rgb_base64} dicts or raw base64 strings)
Outputs features (TEXT β€” the Β§2 envelope; "" on degraded)
Config model_id (select β€” aimv2 large/huge/1B/3B @patch14-224)
Backend call one batched model(pixel_values) under no_grad β†’ patch-token mean β†’ (N, D) float32, input order preserved

Engines are lazy singletons in a registry keyed by model_id β€” two checkpoints coexist in one server without cross-serving features. GPU inference is single-flight per engine (one in-flight forward bounds peak VRAM under concurrent eval workers).


4. Server Mode

parallelism = "shared" (stateless extractor β€” one server across eval workers); server_python = conda_env_python("ac-fm", "AIMV2_PYTHON"). AutoModel loads the AIMv2 checkpoint as an Aimv2VisionModel, and both it and AutoImageProcessor are native to the shared ac-fm env (transformers 5.13), so no dedicated env is needed and the checkpoints are ungated. The nodeset file stays Python-3.8-parseable (an override may point at a py3.8 env). Load: POST /api/components/nodesets/model_aimv2/load?mode=server.


5. Environment Variables

VariableDefaultPurpose
AIMV2_PYTHONac-fm env pythonInterpreter for the server subprocess
AIMV2_DEVICEauto (β†’ cuda when available)Torch device for the loaded model

6. Degraded Mode

A model/processor load failure latches (_load_failed β€” no retry storm); that, or an images entry missing its base64, yields features = "". An empty envelope is a clean "no features this step" signal, never a fabricated vector β€” consumers keep their own fallback.

AgentCanvas docs