Feature Extraction
Transformers
Safetensors
muse_glimmer
metaencoder
multimodal-embedding
image-text-retrieval
video-retrieval
document-retrieval
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
|
Download README.md from facebook/meta-encoder-v1: direct link, hf CLI and curl.
- Browser
- Download file 7.93 kB
-
https://huggingface.co/facebook/meta-encoder-v1/resolve/main/README.md
- Command line
-
hf download hf://facebook/meta-encoder-v1/README.md
-
curl -L -o README.md https://huggingface.co/facebook/meta-encoder-v1/resolve/main/README.md
7.93 kB
| library_name: transformers | |
| pipeline_tag: feature-extraction | |
| tags: | |
| - metaencoder | |
| - muse_glimmer | |
| - multimodal-embedding | |
| - image-text-retrieval | |
| - video-retrieval | |
| - document-retrieval | |
| # 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. | |
| ```python | |
| 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](#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 | |
| ```python | |
| 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 | |
| ```python | |
| 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: | |
| ```python | |
| 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"}}`, with `instructions` the 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: | |
| ```python | |
| 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) | |