Views
No views yet

[!WARNING] This model should be run with cuDNN > 9.20.0. Earlier versions trigger a Conv3D NVIDIA bug that significantly slows down inference or training.
encode(). All modalities produce embeddings in the same 2048-dimensional space and can be compared cross-modally.| Modality | Input type | Notes |
|---|---|---|
| Text | str | Any language; no length limit (model context is 32k tokens) |
| Image | PIL.Image.Image | Any size and aspect ratio; resized internally |
| Audio | np.ndarray, list[float], or dict with "array" (np.ndarray) and "sampling_rate" (int) | Any sample rate; resampled to 16 kHz internally via librosa |
| Mixed | list[dict] conversation (role/content) | Interleave text + image or text + audio in a single prompt — see Chat Template below |
1import numpy as np
2import PIL.Image
3from sentence_transformers import SentenceTransformer
4
5model = SentenceTransformer("BidirLM/BidirLM-Omni-2.5B-Embedding", trust_remote_code=True)
6
7# Text queries
8texts = [
9 "An image with a red background.",
10 "An image with a blue background.",
11 "A deep bass sound.",
12 "A high-pitched sound.",
13]
14
15# Images, synthetic solid-color 256x256 images
16images = [
17 PIL.Image.fromarray(np.full((256, 256, 3), (220, 30, 30), dtype=np.uint8)), # red
18 PIL.Image.fromarray(np.full((256, 256, 3), (30, 30, 220), dtype=np.uint8)), # blue
19]
20
21# Audio, synthetic sine waves at 16kHz, 2 seconds each
22sr = 16000
23t = np.linspace(0, 2.0, sr * 2, endpoint=False, dtype=np.float32)
24audios = [
25 {"array": np.sin(2 * np.pi * 80 * t), "sampling_rate": sr}, # 80 Hz — bass
26 {"array": np.sin(2 * np.pi * 7500 * t), "sampling_rate": sr}, # 7500 Hz — high
27]
28
29# Encode all modalities and compute similarities
30text_embeddings = model.encode(texts)
31image_embeddings = model.encode(images)
32audio_embeddings = model.encode(audios)
33
34# Pass a custom instruction via prompt= (applies to all items in the batch)
35# text_embeddings = model.encode(texts, prompt="Retrieve semantically similar text.")
36
37print(model.similarity(text_embeddings, image_embeddings))
38print(model.similarity(text_embeddings, audio_embeddings))
39
40# Text-Image similarity red img blue img
41# "An image with a red background." [ 0.6928, 0.3103] ← high red match
42# "An image with a blue background."[ 0.4278, 0.6436] ← high blue match
43# "A deep bass sound." [ 0.1519, 0.2272] ← low (text/image mismatch)
44# "A high-pitched sound." [ 0.1418, 0.1812] ← low (text/image mismatch)
45
46# Text-Audio similarity 80Hz bass 7500Hz high
47# "An image with a red background." [ 0.0010, 0.0410] ← low (image/audio mismatch)
48# "An image with a blue background."[ 0.0526, 0.0642] ← low (image/audio mismatch)
49# "A deep bass sound." [ 0.5456, 0.4243] ← higher bass match
50# "A high-pitched sound." [ 0.4004, 0.5177] ← higher high-pitch match1import numpy as np
2import PIL.Image
3from transformers import AutoProcessor, AutoModelForSequenceClassification, AutoModelForTokenClassification
4
5processor = AutoProcessor.from_pretrained(
6 "BidirLM/BidirLM-Omni-2.5B-Embedding", trust_remote_code=True
7)
8
9sr = 16000
10conversation = [
11 {
12 "role": "user",
13 "content": [
14 {"type": "image", "image": PIL.Image.fromarray(np.zeros((256, 256, 3), dtype=np.uint8))},
15 {"type": "audio", "audio": {"array": np.zeros(sr, dtype=np.float32), "sampling_rate": sr}},
16 {"type": "text", "text": "Your text."},
17 ],
18 }
19]
20processor.apply_chat_template(conversation, tokenize=True, add_generation_prompt=False)
21
22
23# Sequence classification (e.g., NLI)
24seq_model = AutoModelForSequenceClassification.from_pretrained(
25 "BidirLM/BidirLM-Omni-2.5B-Embedding",
26 trust_remote_code=True,
27 num_labels=3,
28)
29
30# Token classification (e.g., NER)
31tok_model = AutoModelForTokenClassification.from_pretrained(
32 "BidirLM/BidirLM-Omni-2.5B-Embedding",
33 trust_remote_code=True,
34 num_labels=7,
35)transformers>=5.5.0
sentence-transformers>=5.4.0
librosa>=0.10.0trust_remote_code=True?librosa when the source rate differs from the native 16 kHz. Three input formats are supported:np.ndarray — a 1-D float32 array of raw sampleslist[float] — a plain Python list of samplesdict with "array" (np.ndarray) and "sampling_rate" (int) — the format returned by HuggingFace datasets Audio featureslibrosa.load or soundfile.read).1@misc{boizard2026bidirlmtextomnimodalbidirectional,
2 title={BidirLM: From Text to Omnimodal Bidirectional Encoders by Adapting and Composing Causal LLMs},
3 author={Nicolas Boizard and Théo Deschamps-Berger and Hippolyte Gisserot-Boukhlef and Céline Hudelot and Pierre Colombo},
4 year={2026},
5 eprint={2604.02045},
6 archivePrefix={arXiv},
7 primaryClass={cs.CL},
8 url={https://arxiv.org/abs/2604.02045},
9}