M2-Encoder-0.4B is a Hugging Face export of the bilingual vision-language foundation model from the paper
M2-Encoder: Advancing Bilingual Image-Text Understanding by Large-scale Efficient Pretraining.
It supports Chinese-English image-text retrieval, zero-shot image classification, transformers remote-code loading, ONNXRuntime inference, and Hugging Face Inference Endpoints via the bundled handler.py.
This is the smallest published M2-Encoder variant and is the best starting point for CPU demos, Spaces, and lightweight retrieval services.
The original ModelScope sample computes probabilities from raw normalized embedding dot products:
1from transformers import AutoModel, AutoProcessor
2
3repo_id = "malusama/M2-Encoder-0.4B"
4
5model = AutoModel.from_pretrained(repo_id, trust_remote_code=True)
6processor = AutoProcessor.from_pretrained(repo_id, trust_remote_code=True)
7
8text_inputs = processor(
9 text=["杰尼龟", "妙蛙种子", "小火龙", "皮卡丘"],
10 return_tensors="pt",
11)
12image_inputs = processor(images="pokemon.jpeg", return_tensors="pt")
13
14text_outputs = model(**text_inputs)
15image_outputs = model(**image_inputs)
16
17probs = (image_outputs.image_embeds @ text_outputs.text_embeds.t()).softmax(dim=-1)
18print(probs)
1import importlib
2import json
3import os
4import sys
5
6import onnxruntime as ort
7from huggingface_hub import snapshot_download
8from PIL import Image
9
10repo_id = "malusama/M2-Encoder-0.4B"
11model_dir = snapshot_download(repo_id=repo_id)
12sys.path.insert(0, model_dir)
13
14tokenizer_config = json.load(open(os.path.join(model_dir, "tokenizer_config.json"), "r", encoding="utf-8"))
15GLMChineseTokenizer = importlib.import_module("tokenization_glm").GLMChineseTokenizer
16M2EncoderImageProcessor = importlib.import_module("image_processing_m2_encoder").M2EncoderImageProcessor
17
18tokenizer = GLMChineseTokenizer(
19 vocab_file=os.path.join(model_dir, "sp.model"),
20 eos_token=tokenizer_config.get("eos_token"),
21 pad_token=tokenizer_config.get("pad_token"),
22 cls_token=tokenizer_config.get("cls_token"),
23 mask_token=tokenizer_config.get("mask_token"),
24 unk_token=tokenizer_config.get("unk_token"),
25)
26image_processor = M2EncoderImageProcessor.from_pretrained(model_dir)
27
28text_inputs = tokenizer(
29 ["杰尼龟", "妙蛙种子", "小火龙", "皮卡丘"],
30 padding="max_length",
31 truncation=True,
32 max_length=52,
33 return_special_tokens_mask=True,
34 return_tensors="np",
35)
36image_inputs = image_processor(Image.open("pokemon.jpeg").convert("RGB"), return_tensors="np")
37
38text_session = ort.InferenceSession(
39 os.path.join(model_dir, "onnx", "text_encoder.onnx"),
40 providers=["CPUExecutionProvider"],
41)
42image_session = ort.InferenceSession(
43 os.path.join(model_dir, "onnx", "image_encoder.onnx"),
44 providers=["CPUExecutionProvider"],
45)
46
47text_embeds = text_session.run(
48 None,
49 {
50 "input_ids": text_inputs["input_ids"],
51 "attention_mask": text_inputs["attention_mask"],
52 },
53)[0]
54image_embeds = image_session.run(
55 None,
56 {"pixel_values": image_inputs["pixel_values"]},
57)[0]
1{
2 "inputs": {
3 "text": ["杰尼龟", "妙蛙种子", "小火龙", "皮卡丘"],
4 "image": "https://clip-cn-beijing.oss-cn-beijing.aliyuncs.com/pokemon.jpeg"
5 },
6 "parameters": {
7 "return_probs": true,
8 "return_logits": false
9 }
10}
According to the official project README and paper, the M2-Encoder series is trained on the bilingual BM-6B corpus and evaluated on:
The official project reports that the M2-Encoder family sets strong bilingual retrieval and zero-shot classification results, and that the 10B variant reaches 88.5 top-1 on ImageNet and 80.7 top-1 on ImageNet-CN in the zero-shot setting. See the paper for exact cross-variant comparisons.
1@misc{guo2024m2encoder,
2 title={M2-Encoder: Advancing Bilingual Image-Text Understanding by Large-scale Efficient Pretraining},
3 author={Qingpei Guo and Furong Xu and Hanxiao Zhang and Wang Ren and Ziping Ma and Lin Ju and Jian Wang and Jingdong Chen and Ming Yang},
4 year={2024},
5 url={https://arxiv.org/abs/2401.15896}
6}