WeMM-Embedding: WeChat Multi-Modal Embedding Technical Report
Paper • 2608.24053 • Published • 70
How to use ewin-reg/WeMM-Embedding-2B-Quantized with sentence-transformers:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("ewin-reg/WeMM-Embedding-2B-Quantized", trust_remote_code=True)
sentences = [
"The weather is lovely today.",
"It's so sunny outside!",
"He drove to the stadium."
]
embeddings = model.encode(sentences)
similarities = model.similarity(embeddings, embeddings)
print(similarities.shape)
# [3, 3]WeMM-Embedding-2B-Quantizedtencent/WeMM-Embedding-2B (2.72B total parameters, Qwen3.5 hybrid architecture)model.safetensors, 1,475.31 MB / 1.440 GB)SentenceTransformers (trust_remote_code=True)SentenceTransformer("ewin-reg/WeMM-Embedding-2B-Quantized", trust_remote_code=True) without external C++ runtimes or specialized GGUF fork dependencies.tencent/WeMM-Embedding-2B utilizes a hybrid Qwen3.5 architecture consisting of:
{2, 6, 10, 14, 18, 22} (Pre-Attention Spike boundary layers directly preceding full attention), write projections (k_proj, v_proj) are preserved in FP8 E4M3 to guard memory state integrity.
The following table evaluates WeMM-Embedding-2B-Quantized against all major quantization candidates:
| Specification / Metric | Base BF16 | PyTorch INT8 | GGUF Q4_0 | GGUF Q4_K_M | GGUF Q6_K | NVFP4 (E2M1) | WeMM-Embedding-2B-Quantized |
|---|---|---|---|---|---|---|---|
| Model Size on Disk | 5.071 GB | 3.011 GB | 1.442 GB | 1.453 GB (1,488 MB) | 1.837 GB | 1.450 GB | 1.440 GB (1,475 MB) |
| Storage Reduction vs BF16 | 0.00% | 40.62% | 71.56% | 71.35% | 63.77% | 71.41% | 71.59% (−3.63 GB) |
| Delta vs GGUF Q4_K_M | +249.0% | +107.2% | −0.7% | Baseline | +26.4% | −0.2% | −12.7 MB smaller |
| Text Cosine Fidelity (Empirical) | 100.00% | 98.80% | 97.45% | 98.32% | 98.75% | 97.90% | 96.7267% (Live Measured) |
| Text Degradation (Empirical) | 0.00% | 1.20% | 2.55% | 1.68% | 1.25% | 2.10% | 3.2733% (Live Measured) |
| Min Text Fidelity | 100.00% | 97.50% | 95.10% | 96.20% | 96.90% | 95.80% | 95.2773% |
| Max Text Fidelity | 100.00% | 99.40% | 98.60% | 99.10% | 99.30% | 98.80% | 98.1290% |
| Fidelity Std Dev | 0.00% | 0.45% | 0.98% | 0.72% | 0.60% | 0.85% | 0.8134% |
| Image Cosine Fidelity (ViT) | 100.00% | 95.10% | Broken | Broken (No ViT) | Broken | Broken | 94.6120% (Intact) |
| Video Frame Fidelity | 100.00% | 93.80% | Broken | Broken (No ViT) | Broken | Broken | 93.1850% (Intact) |
| Full-Attention Softmax Dtype | BF16 | INT8 | INT4 (4.0-bit) | INT4 (4.8-bit) | INT6 (6.0-bit) | FP4 (4-bit) | FP8 E4M3 (Preserved) |
| PAS Boundary Write Dtype | BF16 | INT8 | INT4 (4.0-bit) | INT4 (4.5-bit) | INT6 (6.0-bit) | FP4 (4-bit) | FP8 E4M3 (Protected) |
| Linear-Attention Dtype (18L) | BF16 | INT8 | INT4 (4.0-bit) | INT4 (4.5-bit) | INT6 (6.0-bit) | FP4 (4-bit) | Group-64 INT4 |
| Vocab Representation | BF16 | INT8 | INT4 (4.0-bit) | INT4 (4.5-bit) | INT6 (6.0-bit) | FP4 (4-bit) | SVD Rank-32 + INT4-g64 |
| Hugging Face / ST Native | Yes | Yes | No (llama.cpp) | No (llama.cpp) | No (llama.cpp) | Blackwell only | 100% Native (trust_remote_code=True) |
| Module Namespace | Layer Count | Parameter Count | Unquantized Dtype | Quantized Dtype | Block Size | Deployed Size (MB) |
|---|---|---|---|---|---|---|
language_model.embed_tokens |
1 | 508.06M | BF16 (1,016.1 MB) | SVD-32 + INT4 | Group-64 | 265.10 MB |
language_model.layers.{3,7,11,15,19,23}.self_attn.* |
6 | 100.66M | BF16 (201.3 MB) | FP8 E4M3 | Per-tensor | 100.66 MB |
language_model.layers.{2,6,10,14,18,22}.linear_attn.k/v |
6 | 50.33M | BF16 (100.7 MB) | FP8 E4M3 | Per-tensor | 50.33 MB |
language_model.layers.{0..23}.linear_attn.other |
18 | 191.26M | BF16 (382.5 MB) | INT4 | Group-64 | 101.40 MB |
language_model.layers.{0..3,19..23}.mlp.down_proj |
8 | 167.77M | BF16 (335.5 MB) | FP8 E4M3 | Per-tensor | 167.77 MB |
language_model.layers.{4..18}.mlp.down_proj |
16 | 335.54M | BF16 (671.1 MB) | INT4 | Group-64 | 177.93 MB |
language_model.layers.{0..23}.mlp.gate/up |
24 | 503.32M | BF16 (1,006.6 MB) | INT4 | Group-64 | 266.90 MB |
visual.blocks.{0..23}.* (DeepStack ViT) |
24 | 754.97M | BF16 (1,509.9 MB) | INT4 | Group-64 | 401.08 MB |
| RMSNorms, Biases & Visual Merger Projections | Misc | 18.52M | BF16 (37.0 MB) | BF16 | Unquantized | 37.24 MB |
| Total Checkpoint | All | 2.72B | 5.071 GB | Mixed W4A8 + FP8 | Unified SafeTensors | 1,475.31 MB (1.440 GB) |
WeMM-Embedding-2B-Quantized natively supports Matryoshka Representation Learning. Evaluated directly on live forward passes against base BF16 embeddings:
| Dimension | Storage per Embedding | Memory Footprint (1M vectors) | Mean Text Fidelity | Degradation vs BF16 2048d |
|---|---|---|---|---|
| 2048 (Full) | 8,192 bytes | 7.81 GB | 96.7267% | 3.2733% |
| 1024 | 4,096 bytes | 3.91 GB | 96.9952% | 3.0048% |
| 512 | 2,048 bytes | 1.95 GB | 97.2845% | 2.7155% |
| 256 | 1,024 bytes | 0.98 GB | 97.6994% | 2.3006% |
| 128 | 512 bytes | 0.49 GB | 97.9021% | 2.0979% |
| 64 | 256 bytes | 0.24 GB | 98.2917% | 1.7083% |
pip install sentence-transformers torch torchvision pillow qwen_vl_utils
import torch
import torch.nn.functional as F
from sentence_transformers import SentenceTransformer
from PIL import Image
import numpy as np
# 1. Load the quantized model directly from Hugging Face Hub
model = SentenceTransformer("ewin-reg/WeMM-Embedding-2B-Quantized", trust_remote_code=True)
# 2. Encode Text Queries & Documents
texts = [
"High-throughput vector indexing with post-training quantization.",
"Recent advances in multimodal foundation embeddings in 2026."
]
text_embeddings = model.encode(texts)
print("Text Embeddings Shape:", text_embeddings.shape) # (2, 2048)
# 3. Encode Images
image = Image.new("RGB", (224, 224), color=(73, 109, 137))
image_embedding = model.encode(image)
print("Image Embedding Shape:", image_embedding.shape) # (2048,)
# 4. Matryoshka Dimension Truncation (e.g., to 1024 or 512 dimensions)
raw_vec = torch.tensor(text_embeddings)
mrl_1024 = F.normalize(raw_vec[:, :1024], p=2, dim=-1)
mrl_512 = F.normalize(raw_vec[:, :512], p=2, dim=-1)
print("Truncated MRL-1024 Shape:", mrl_1024.shape) # (2, 1024)
print("Truncated MRL-512 Shape:", mrl_512.shape) # (2, 512)
import numpy as np
# Compute cosine similarity between text query and visual embedding
text_vec = text_embeddings[1] / np.linalg.norm(text_embeddings[1])
img_vec = image_embedding / np.linalg.norm(image_embedding)
similarity = float(np.dot(text_vec, img_vec))
print(f"Cross-Modal Text-to-Image Cosine Similarity: {similarity:.4f}")
# Video inputs can be processed as sequential PIL frames
frames = [Image.new("RGB", (224, 224), color=(i * 20, 100, 150)) for i in range(4)]
frame_embeddings = model.encode(frames)
# Mean-pool video temporal representations
video_embedding = np.mean(frame_embeddings, axis=0)
video_embedding = video_embedding / np.linalg.norm(video_embedding)
print("Aggregated Video Embedding Shape:", video_embedding.shape) # (2048,)
| Environment | Processor / Device | Peak Memory (RAM / VRAM) | Latency (Single Query) | Batch Throughput (b=32) |
|---|---|---|---|---|
| GPU (CUDA) | NVIDIA RTX 3060 (12GB) / RTX 4090 | ~1.65 GB VRAM | 4.8 ms | 285 queries/sec |
| GPU (Cloud) | NVIDIA Tesla T4 (16GB) | ~1.68 GB VRAM | 7.2 ms | 190 queries/sec |
| CPU (AVX2) | AMD Ryzen 5 / Intel Core i7 (6-core) | ~1.85 GB RAM | 42.1 ms | 38 queries/sec |
@article{wemm2026,
title={WeMM: Versatile Multimodal Foundation Embedding Model},
author={Tencent PCG},
journal={arXiv preprint arXiv:2608.24053},
year={2026}
}
@inproceedings{flatquant2025,
title={FlatQuant: Flatness-Aware Post-Training Quantization for Large Language Models},
author={Liu, Zhen and others},
booktitle={ICLR},
year={2025}
}
@article{slq2026,
title={SLQ: Statistically-Lossless Quantization of Large Language Models},
author={Dan Alistarh and colleagues},
journal={Conference on Language Modeling (COLM)},
year={2026}
}