Instructions to use facebook/meta-encoder-v1 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use facebook/meta-encoder-v1 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("feature-extraction", model="facebook/meta-encoder-v1")# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModel processor = AutoProcessor.from_pretrained("facebook/meta-encoder-v1") model = AutoModel.from_pretrained("facebook/meta-encoder-v1", device_map="auto") - Notebooks
- Google Colab
- Kaggle
MetaEncoder v1
Usage
Requires transformers>=5.15 (the first release with muse_glimmer); see requirements.txt. One 80 GB GPU holds
the model in bf16.
from modeling_metaencoder import MetaEncoder
model = MetaEncoder.from_pretrained("facebook/meta-encoder-v1")
MetaEncoder has three calls. Callers pass content and task descriptions; the wrapper writes every prompt itself, in
the layout the encoder was trained on (see Prompt formatting).
| Call | Use it to | Returns |
|---|---|---|
encode(inputs, instruction=None) |
embed inputs to store, cluster or compare | (n, 6656) float32 tensor, L2-normalised |
retrieve(query, corpus, top_k=None, query_instruction=None, corpus_instruction=None) |
rank a corpus against a query | list[Hit], best first |
decide(state, questions, images=None, video=None) |
answer Jev-style questions about a state | Jev answers with probabilities |
Inputs
encode and retrieve take items. An item is a string, a PIL image, or a dict with any of text, image,
images, video (a list of frames) and instruction. The instruction says what the embedding is for, e.g.
"Represent the given image." or "Find a document image that matches the given query."; the same input embeds
differently under different instructions, and queries and documents usually take different ones.
1. Encode
from PIL import Image
docs = model.encode([{"image": Image.open("chart.png")}, {"image": Image.open("slide.png")}],
instruction="Understand the content of the provided document image.")
MetaEncoder.similarity(docs, docs) # cosine similarity matrix
inputs is one item or a list of them; instruction applies to the items that carry none of their own.
2. Retrieve
hits = model.retrieve("Which quarter had the highest revenue?", docs, top_k=1,
query_instruction="Find a document image that matches the given query.")
hits[0].index, hits[0].score, hits[0].item # position in the corpus, cosine similarity, the corpus item
corpus is a list of items, or the tensor encode returned for them: encode a large corpus once and search the
tensor repeatedly.
3. Decide
decide takes a Jev decision request, a state and named questions, and answers each question:
result = model.decide(
{"query": "used iphone 15"},
{
"shopping": {"type": "noul", "instructions": "Is the user shopping for a product?"},
"topic": {"type": "choice", "instructions": "Which topic is the query about?",
"criteria": {"electronics": "", "food": "", "travel": "", "other": ""}},
"intent": {"type": "score", "instructions": "How strong is the purchase intent?",
"criteria": ["none", "weak", "moderate", "strong"]},
},
)
result["questions"]["shopping"] # {"value": True, "probabilities": {"false": 0.016, "true": 0.984},
# "confidence": 0.881, "scores": {...}}
result["questions"]["topic"]["value"], result["questions"]["intent"]["value"] # "electronics", 1.89
state: what the questions are about. A string, or any JSON value (an object of fields, a list of records).images,video: the state's media: a PIL image or a list of them, and a list of video frames.questions:{name: {"type", "instructions", "criteria"}}, withinstructionsthe question itself:
type |
criteria |
value |
probabilities keys |
|---|---|---|---|
noul |
optional {"true": ..., "false": ...} descriptions |
True / False |
"false", "true" |
choice |
{option: description}, 2 to 26 options; descriptions may be empty |
the chosen option | the options |
score |
the ordered list of level labels, e.g. ["none", "weak", "strong"] |
expected level index (float) | "0" .. "n-1" |
Each answer also has confidence (1 minus the normalised entropy of probabilities) and scores (the raw cosine
similarities). Questions are answered independently; for a question that only applies given another's answer,
decide the first and ignore the second as needed.
decide_batch(states, questions, images=None, video=None) answers the same questions for many states (one
images / video entry per state).
Probabilities are softmax(score / 0.02), the contrastive training temperature. To fit the temperature to your
data, decide a labelled set and call model.calibrate(answers, labels) with the per-question answers
(result["questions"][name]) and their correct keys (the option, True/False, or the level index); later
decide calls use the fitted temperature.
Prompt formatting
The wrapper formats every input as in training, so callers never write prompts:
- System turn (
chat_template.jinja): the fixed header ending in "Represent the user's input.", then the item's instruction after a blank line when it has one. The date line is fixed, so an input embeds the same on any day. - User turn: images and video frames first, then the text. Images keep their native resolution, snapped to a 28-pixel grid, up to 4096 merged tokens. Video is encoded frame by frame; more than 8 frames are subsampled uniformly to 8, as in training.
- Pooling: the last position, the user turn's
<|eot|>, with left padding. Inputs are never truncated (that would drop the pooled token); training sequences were at most 16,384 tokens.
decide turns each question into a closed-set decision row of training, scored as retrieval over its options:
| Part | Rendered as |
|---|---|
| query text | the state, a blank line, Task: {instructions}, then the options: Options: a, b, c, or one - option per line when an option is long or punctuated |
| state | a string as is; a JSON value with json.dumps |
| query instruction | "Read the task definition and select the option it calls for." for a string state; "Answer the question about the scenario by selecting the correct option." for a JSON state |
| options | noul: No, Yes; choice: the criteria keys; score: the level labels |
| candidates | one per option: the option, then its description (if any) on the next line |
| candidate instruction | Option for the task: {instructions} when every option is a short label (at most 5 words), else none |
Option descriptions are optional. The yes/no, choice and score rows of training used bare option labels; candidate descriptions were trained only as records of the entities that options name.
Without the wrapper
modeling_metaencoder.py only formats the prompt and pools; the same embedding with public classes directly:
import torch, torch.nn.functional as F
from safetensors.torch import load_file
from transformers import AutoModel, AutoProcessor
model = AutoModel.from_pretrained(repo, dtype=torch.bfloat16, device_map="auto").eval() # MuseGlimmerModel
processor = AutoProcessor.from_pretrained(repo)
processor.tokenizer.padding_side = "left"
head = load_file(f"{repo}/embedding_head.safetensors")["embedding_head.weight"].to(model.device, torch.bfloat16)
messages = [{"role": "system", "content": "Represent the given image."}, # optional instruction
{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": "a dog"}]}]
text = processor.apply_chat_template(messages, tokenize=False)
inputs = processor(text=[text], images=[image], add_special_tokens=False, max_image_tokens=4096,
return_tensors="pt").to(model.device)
with torch.no_grad():
hidden = model(**inputs).last_hidden_state[:, -1]
embedding = F.normalize((hidden @ head.T).float(), dim=-1)
- Downloads last month
- -
