tencent/WeMM-Embedding-9B

Model

126

stars

17

commits

1

repos using this model

1

linked in READMEs

Sep 3, 2026

updated

custom_code
endpoints_compatible
feature-extraction
image-embedding
image-text-to-text
mrl
multimodal-embedding
qwen3_5
safetensors
sentence-transformers
text-embedding
transformers
video-embedding
Browse cluster: Dense Vector Embeddings & Feature Extraction

README

WeMM-Embedding-9B

Hugging Face Technical Report GitHub

WeMM-Embedding-9B is a universal multimodal embedding model built on Qwen3.5. It accepts text, images, videos, visual documents, and interleaved multimodal inputs, and returns a 4,096-dimensional L2-normalized embedding. Audio input is not supported.

Installation

pip install torch transformers==5.2.0 "qwen-vl-utils[decord]==0.0.14" \
  "sentence-transformers>=5.7.0" "accelerate>=1.1.0"

Transformers

import torch
from qwen_vl_utils import process_vision_info
from transformers import AutoModel, AutoProcessor

model_id = "tencent/WeMM-Embedding-9B"
processor = AutoProcessor.from_pretrained(model_id, trust_remote_code=True)
model = AutoModel.from_pretrained(
    model_id, trust_remote_code=True, dtype=torch.bfloat16
).cuda().eval()

messages = [{"role": "user", "content": [
    {"type": "image", "image": "/path/to/image.jpg"},
    {"type": "video", "video": "/path/to/video.mp4"},
    {"type": "text", "text": "This can be any text input."},
]}]
text = processor.apply_chat_template(
    messages, tokenize=False, add_generation_prompt=False
)
images, videos, video_kwargs = process_vision_info(
    messages,
    image_patch_size=16,
    return_video_kwargs=True,
    return_video_metadata=True,
)
if videos is not None:
    videos, video_metadata = zip(*videos)
    videos, video_metadata = list(videos), list(video_metadata)
else:
    video_metadata = None
inputs = processor(
    text=text,
    images=images,
    videos=videos,
    video_metadata=video_metadata,
    return_tensors="pt",
    **video_kwargs,
).to("cuda")

with torch.inference_mode():
    embedding = model.embedding(**inputs)

Use any subset of the content items to encode text, image, or video independently.

Sentence Transformers

from sentence_transformers import SentenceTransformer

model_id = "tencent/WeMM-Embedding-9B"
model = SentenceTransformer(model_id, trust_remote_code=True)

queries = [
    "Which Llama 4 model variants are available?",
    "How is mapo tofu prepared?",
]
documents = [
    "Mapo tofu is a Sichuan dish of soft tofu simmered in a spicy, numbing sauce of chili bean paste and Sichuan peppercorn.",
    {
        "image": "https://huggingface.co/datasets/sentence-transformers/example-documents/resolve/main/llama4_hgf.png",
    },
    {
        "video": "https://huggingface.co/datasets/sentence-transformers/example-documents/resolve/main/mapo_tofu.mp4",
    },
]

query_embeddings = model.encode_query(queries)
document_embeddings = model.encode_document(documents)
print(query_embeddings.shape, document_embeddings.shape)
# (2, 4096) (3, 4096)

similarities = model.similarity(query_embeddings, document_embeddings)
print(similarities)
# tensor([[0.2144, 0.6000, 0.1522],
#         [0.7648, 0.2622, 0.5298]])

Each input is a string, a URL or path, a PIL.Image, or a dict combining image, video, and text keys. Chat messages such as {"role": "user", "content": [{"type": "image", "image": ...}, {"type": "text", "text": ...}]} are also accepted, which is the way to interleave several images or videos in one input.

Matryoshka Embeddings

d = 256
embedding_d = torch.nn.functional.normalize(embedding[..., :d], dim=-1)

With Sentence Transformers, pass truncate_dim and let it renormalize:

embeddings_d = model.encode_document(documents, truncate_dim=d, normalize_embeddings=True)

Use a dimension listed in model.config.matryoshka_dimensions.

Serving

vLLM 0.27.0:

MODEL_PATH=/path/to/WeMM-Embedding-9B
vllm serve "$MODEL_PATH" \
  --runner pooling \
  --chat-template "$MODEL_PATH/embedding_chat_template.jinja"

SGLang 0.5.9:

MODEL_PATH=/path/to/WeMM-Embedding-9B
python patch_sglang_video.py
python -m sglang.launch_server \
  --model-path "$MODEL_PATH" \
  --is-embedding \
  --enable-precise-embedding-interpolation

Evaluation

MMEB-v2

Results on 78 datasets from Table 1 of the technical report. Image and video tasks use Hit@1, while visual-document tasks use NDCG@5. Higher is better.

ModelSizeAVGImageVideoVisDoc
VLM2Vec2B47.859.729.044.0
GME2B55.451.933.976.8
VLM2Vec-V22B59.364.934.969.2
Qwen3-VL-Embedding2B73.275.061.979.2
DME-Small†2B74.875.965.679.9
WeMM-Embedding2B77.979.670.880.7
WeMM-Embedding4B79.280.872.182.0
VLM2Vec8B53.265.534.049.1
GME8B59.256.038.679.3
Qwen3-VL-Embedding8B77.880.167.182.4
DME-Medium†9B78.479.870.882.0
WeMM-Embedding9B80.681.974.383.3

† Closed-source leaderboard submission without publicly released model weights or a public inference endpoint.

MMEB-v3

Results on all 190 tasks from Table 2 of the technical report. V3-All includes the 78 MMEB-v2 tasks, 53 text tasks, 47 agent tasks, 11 audio tasks, and MCMR. Unsupported tasks are assigned a score of zero.

ModelSizeV3-AllTextAgentMCMRAudio
VLM2Vec-V22B38.324.528.74.10.0
Omni-Embed-Nemotron3B43.539.236.526.136.5
E5-Omni3B44.626.736.931.930.8
Qwen3-VL-Embedding2B50.939.239.342.00.0
WeMM-Embedding2B56.045.345.142.50.0
WeMM-Embedding4B58.247.949.041.90.0
WAVE7B26.313.711.38.931.8
VLM2Vec8B32.922.219.70.90.0
LCO-Embedding-Omni7B40.632.427.820.043.2
GME8B43.637.135.627.30.0
E5-Omni7B47.126.936.741.143.0
Tianmu-Emb-Uni8B53.343.639.438.838.9
Qwen3-VL-Embedding8B53.542.538.438.00.0
WeMM-Embedding9B59.548.851.049.30.0

Text results use NDCG@5; agent, MCMR, and audio results use Hit@1.

Citation

If you find this repository useful, please consider giving a star ⭐ and citation

@article{wemm-embedding,
      title={WeMM-Embedding: WeChat Multi-Modal Embedding Technical Report}, 
      author={Junjie Zhou and Ke Mei and Lei Li and Tianyi Wang and Fengyun Rao and Jing Lyu},
      year={2026},
      eprint={2608.24053},
      archivePrefix={arXiv},
      primaryClass={cs.CV},
      url={https://arxiv.org/abs/2608.24053}, 
}

License

WeMM-Embedding-9B, including the code, model parameters, and weights made publicly available by Tencent, is licensed under the Apache License 2.0. Third-party components remain subject to their respective original licenses.

Contributors

JUNJIE99

10 commits

kekekeke

5 commits

TencentOpen

1 commits

tomaarsen

1 commits

tencent/WeMM-Embedding-9B

Model

126

stars

17

commits

1

repos using this model

1

linked in READMEs

Sep 3, 2026

updated

custom_code
endpoints_compatible
feature-extraction
image-embedding
image-text-to-text
mrl
multimodal-embedding
qwen3_5
safetensors
sentence-transformers
text-embedding
transformers
video-embedding
Browse cluster: Dense Vector Embeddings & Feature Extraction

README

WeMM-Embedding-9B

Hugging Face Technical Report GitHub

WeMM-Embedding-9B is a universal multimodal embedding model built on Qwen3.5. It accepts text, images, videos, visual documents, and interleaved multimodal inputs, and returns a 4,096-dimensional L2-normalized embedding. Audio input is not supported.

Installation

pip install torch transformers==5.2.0 "qwen-vl-utils[decord]==0.0.14" \
  "sentence-transformers>=5.7.0" "accelerate>=1.1.0"

Transformers

import torch
from qwen_vl_utils import process_vision_info
from transformers import AutoModel, AutoProcessor

model_id = "tencent/WeMM-Embedding-9B"
processor = AutoProcessor.from_pretrained(model_id, trust_remote_code=True)
model = AutoModel.from_pretrained(
    model_id, trust_remote_code=True, dtype=torch.bfloat16
).cuda().eval()

messages = [{"role": "user", "content": [
    {"type": "image", "image": "/path/to/image.jpg"},
    {"type": "video", "video": "/path/to/video.mp4"},
    {"type": "text", "text": "This can be any text input."},
]}]
text = processor.apply_chat_template(
    messages, tokenize=False, add_generation_prompt=False
)
images, videos, video_kwargs = process_vision_info(
    messages,
    image_patch_size=16,
    return_video_kwargs=True,
    return_video_metadata=True,
)
if videos is not None:
    videos, video_metadata = zip(*videos)
    videos, video_metadata = list(videos), list(video_metadata)
else:
    video_metadata = None
inputs = processor(
    text=text,
    images=images,
    videos=videos,
    video_metadata=video_metadata,
    return_tensors="pt",
    **video_kwargs,
).to("cuda")

with torch.inference_mode():
    embedding = model.embedding(**inputs)

Use any subset of the content items to encode text, image, or video independently.

Sentence Transformers

from sentence_transformers import SentenceTransformer

model_id = "tencent/WeMM-Embedding-9B"
model = SentenceTransformer(model_id, trust_remote_code=True)

queries = [
    "Which Llama 4 model variants are available?",
    "How is mapo tofu prepared?",
]
documents = [
    "Mapo tofu is a Sichuan dish of soft tofu simmered in a spicy, numbing sauce of chili bean paste and Sichuan peppercorn.",
    {
        "image": "https://huggingface.co/datasets/sentence-transformers/example-documents/resolve/main/llama4_hgf.png",
    },
    {
        "video": "https://huggingface.co/datasets/sentence-transformers/example-documents/resolve/main/mapo_tofu.mp4",
    },
]

query_embeddings = model.encode_query(queries)
document_embeddings = model.encode_document(documents)
print(query_embeddings.shape, document_embeddings.shape)
# (2, 4096) (3, 4096)

similarities = model.similarity(query_embeddings, document_embeddings)
print(similarities)
# tensor([[0.2144, 0.6000, 0.1522],
#         [0.7648, 0.2622, 0.5298]])

Each input is a string, a URL or path, a PIL.Image, or a dict combining image, video, and text keys. Chat messages such as {"role": "user", "content": [{"type": "image", "image": ...}, {"type": "text", "text": ...}]} are also accepted, which is the way to interleave several images or videos in one input.

Matryoshka Embeddings

d = 256
embedding_d = torch.nn.functional.normalize(embedding[..., :d], dim=-1)

With Sentence Transformers, pass truncate_dim and let it renormalize:

embeddings_d = model.encode_document(documents, truncate_dim=d, normalize_embeddings=True)

Use a dimension listed in model.config.matryoshka_dimensions.

Serving

vLLM 0.27.0:

MODEL_PATH=/path/to/WeMM-Embedding-9B
vllm serve "$MODEL_PATH" \
  --runner pooling \
  --chat-template "$MODEL_PATH/embedding_chat_template.jinja"

SGLang 0.5.9:

MODEL_PATH=/path/to/WeMM-Embedding-9B
python patch_sglang_video.py
python -m sglang.launch_server \
  --model-path "$MODEL_PATH" \
  --is-embedding \
  --enable-precise-embedding-interpolation

Evaluation

MMEB-v2

Results on 78 datasets from Table 1 of the technical report. Image and video tasks use Hit@1, while visual-document tasks use NDCG@5. Higher is better.

ModelSizeAVGImageVideoVisDoc
VLM2Vec2B47.859.729.044.0
GME2B55.451.933.976.8
VLM2Vec-V22B59.364.934.969.2
Qwen3-VL-Embedding2B73.275.061.979.2
DME-Small†2B74.875.965.679.9
WeMM-Embedding2B77.979.670.880.7
WeMM-Embedding4B79.280.872.182.0
VLM2Vec8B53.265.534.049.1
GME8B59.256.038.679.3
Qwen3-VL-Embedding8B77.880.167.182.4
DME-Medium†9B78.479.870.882.0
WeMM-Embedding9B80.681.974.383.3

† Closed-source leaderboard submission without publicly released model weights or a public inference endpoint.

MMEB-v3

Results on all 190 tasks from Table 2 of the technical report. V3-All includes the 78 MMEB-v2 tasks, 53 text tasks, 47 agent tasks, 11 audio tasks, and MCMR. Unsupported tasks are assigned a score of zero.

ModelSizeV3-AllTextAgentMCMRAudio
VLM2Vec-V22B38.324.528.74.10.0
Omni-Embed-Nemotron3B43.539.236.526.136.5
E5-Omni3B44.626.736.931.930.8
Qwen3-VL-Embedding2B50.939.239.342.00.0
WeMM-Embedding2B56.045.345.142.50.0
WeMM-Embedding4B58.247.949.041.90.0
WAVE7B26.313.711.38.931.8
VLM2Vec8B32.922.219.70.90.0
LCO-Embedding-Omni7B40.632.427.820.043.2
GME8B43.637.135.627.30.0
E5-Omni7B47.126.936.741.143.0
Tianmu-Emb-Uni8B53.343.639.438.838.9
Qwen3-VL-Embedding8B53.542.538.438.00.0
WeMM-Embedding9B59.548.851.049.30.0

Text results use NDCG@5; agent, MCMR, and audio results use Hit@1.

Citation

If you find this repository useful, please consider giving a star ⭐ and citation

@article{wemm-embedding,
      title={WeMM-Embedding: WeChat Multi-Modal Embedding Technical Report}, 
      author={Junjie Zhou and Ke Mei and Lei Li and Tianyi Wang and Fengyun Rao and Jing Lyu},
      year={2026},
      eprint={2608.24053},
      archivePrefix={arXiv},
      primaryClass={cs.CV},
      url={https://arxiv.org/abs/2608.24053}, 
}

License

WeMM-Embedding-9B, including the code, model parameters, and weights made publicly available by Tencent, is licensed under the Apache License 2.0. Third-party components remain subject to their respective original licenses.

Contributors

JUNJIE99

10 commits

kekekeke

5 commits

TencentOpen

1 commits

tomaarsen

1 commits