wemm-embed: WeMM-Embedding-2B, Tencent's multimodal embedding model, planned as an API
wemm-embed is this platform's planned alias for WeMM-Embedding-2B, a universal multimodal embedding model from Tencent's WeChat team, published in August 2026. The model accepts text, images, videos, visual documents, and interleaved combinations of those. It returns one 2,048-dimension L2-normalized vector per input. Audio is not supported. The lane's row sits behind the public list in the platform's model data. Nothing answers under the alias, and no date is promised. What this page carries instead is the spec sheet read as a serving contract. It also carries the comparison block the search results lack, and the request contract the planned row will answer to. The page publishes the spec and the request contract, so client work can start now.
Last verified: 2026-09-25
What it is
WeMM-Embedding is a family of universal multimodal embedding models from Tencent's WeChat team, released in August 2026 with a technical report and downloadable weights on Hugging Face. The report covers 2B, 4B, and 9B variants. The 2B member is the one with the model card this page links. It is also the one this platform's plan names. The report describes the training as two stages. The first is a large-scale multimodal alignment stage. The second is refinement with curated data, fine-grained relevance supervision, and cross-scale knowledge transfer. It also states the deployment record in the publisher's own words. The reported gains sit across a 26-task in-house benchmark. The report also names consistent improvements across 14 online A/B tests. The report lists production use across WeChat services including Channels, Official Accounts, Moments, and e-commerce. That is the publisher's account of its own system, stated here as exactly that.
The identity facts, and who owns each number:
| Fact | Value | Who owns the number |
|---|---|---|
| Publisher | Tencent, WeChat team (authors Zhou, Mei, Li, Wang, Rao, Lyu) | technical report |
| Released | August 2026 (report submitted 25 August 2026) | arXiv page |
| Family | 2B, 4B, and 9B variants | technical report |
| Backbone | Qwen3.5-2B plus a vision tower, about 2.72B parameters at bf16 | model card (base model); total per the published spec sheet |
| Inputs | text, images, videos, visual documents, interleaved | model card |
| Not supported | audio | model card, stated in its opening paragraph |
| Output | 2,048 dimensions, L2-normalized | model card |
| Context | 262,144 positions | model config (max_position_embeddings) |
| Matryoshka steps | 64, 128, 256, 512, 1024, 2048 | model config |
| Languages | Chinese and English | card language metadata |
| Evaluation axis | MMEB-v2, 78 datasets | model card |
| License | stated Apache 2.0 for code, parameters, weights; metadata tagged other | card license section and repository metadata |
| Alias on this platform | wemm-embed (planned; row behind the public list) | this platform's build plan, checked 2026-09-25 |
Read as a serving contract, four of those rows do real work.
The output is 2,048 dimensions and L2-normalized. Normalized means the vector's length is 1. So similarity is a dot product (or cosine, the same thing on unit vectors) with no client-side normalization step. The fixed full length sets storage arithmetic. That is 8 KB per vector at float32 before index overhead.
The context is 262,144 positions. That is 32 times the 8,192-token window of this platform's text-embedding model. It is the number that makes whole visual documents a single-input job rather than a chunking exercise. A scanned contract, a long slide deck page sequence, a manual chapter: the model reads the visual document as one input. It emits one vector.
The Matryoshka steps run 64 to 2,048. The vector can be truncated to any config-listed length and re-normalized without re-encoding. The card's measured cost at 256 dimensions is 98.7 percent of full-dimensional image and video performance on MMEB-v2. This is a storage and index dial, covered in the use cases below.
Audio is absent, and the publisher says so twice. The card's opening paragraph states audio input is not supported. The MMEB-v3 table scores the audio column 0.0 because unsupported tasks are assigned zero. A spec sheet that names its own boundary is a better contract. One that leaves the boundary to be discovered is worse.
One naming caution before moving on. Model directories auto-generate their pages for new releases. The directory page checked during the 2026-09-24 verification mislabels this model as a code generation model, while its own tags say feature extraction. The primary sources are the card and the report. Every number on this page comes from them or from this platform's own records.
On this platform, the lane is planned in the same set as the classification models. The embeddings category page maps the route family this row joins, and the models index shows the catalog row by row.
Use cases
The model's one idea is a shared vector space across input types. Inputs with close meanings end up close in the space. That holds whether the input was a sentence, a photograph, a clip, or a page image. From that one space, a handful of jobs follow.
- Multimodal semantic search. Text queries against image and video corpora, image queries against text, any mix, in one index. The card's worked example embeds two text queries and three documents, one text, one image, one video, in a single call and reads one similarity matrix across all of them. That matrix, at corpus scale, is the product.
- Visual-document retrieval. Scans, screenshots, and page images embed as visual documents, not as OCR afterthoughts. This pairs naturally with a parsing lane: parse pages to text with the print OCR lane for exact-string work, and embed the page images here for meaning-level work; two signals over the same corpus.
- Interleaved content as one input. Product pages, documentation, and slides mix images and text in sequence. The interleaved input class encodes the mix as one vector, preserving the layout of the content instead of flattening it into disconnected pieces.
- Video libraries. A video is one input class, so dedup, near-duplicate detection, and content search over clips become vector jobs with no frame-sampling pipeline on your side.
- Storage-tiered retrieval. The Matryoshka dial from the spec section: index at 256 dimensions for an eighth of the memory, keep the full 2,048 vectors cold, and re-truncate rather than re-embed when the trade changes.
Where it is the wrong tool: any corpus with audio, and the boundary is the model's own. Text-only corpora fit the smaller bge-m3 on the same route family, which answers at lower cost. Classification, meaning labeled category outputs, is a different model class entirely. It has its own lanes in the classification family. This model scores similarity in a shared space. It does not emit labels.
The local routes today, and what a hosted row adds
The card ships local routes with versions attached. They are transformers 5.2.0 with qwen-vl-utils for video inputs, sentence-transformers 5.7.0 or newer with its encode_query and encode_document methods, vLLM 0.27.0 in pooling mode, and SGLang 0.5.9. All four are documented on the card with runnable code.
Local makes sense when the corpus cannot leave your perimeter, or when you want to fine-tune on your own pairs. It also makes sense when the request rate is predictable enough that a GPU you already own is cheaper than any meter. What local does not carry is the operations half. That means an endpoint that stays up, a ledger that matches every bill, and keys that switch off the moment one leaks. Spend halts at a prepaid balance.
The hosted row on this platform is planned and sits behind the public list, with the rate set and no date promised. The metering plan is worth knowing now because it shapes client design. The plan is one token count per request, flat across modalities. Text, image, and video inputs meter in the same unit against the same wallet. There are no per-image or per-video surcharge units. How video inputs are counted in tokens is a build pin. It is stated as such, not guessed here. When the row joins the public list, it rides the embeddings route family. The contract is in the next section.
API usage
The planned row rides the platform's embeddings route family. That means POST /v1/embeddings, an OpenAI-compatible request shape. It takes a console-issued Bearer key in the Authorization header and the model id wemm-embed. The route family's parse law, read from the gateway's own contract source, is strict. model and input are required. input is one string or a list of strings. encoding_format and dimensions are accepted. Any other key is refused with a 400 whose error names that key. A token-array input is refused the same way, before any metering runs. Route families stay separate on this platform. This alias will not answer a chat route, and a chat alias will not answer this one.
Today the route refuses the alias, because the row sits behind the public list. The tabs below are the working contract for the day the row joins it, written against the route family's real parse law. Nothing here is a guess about the endpoint shape.
Two boundaries are stated as boundaries. First, how image and video references ride the request body on the hosted shape, a URL, a path convention, or a content block, is fixed when the row lands. The local library accepts file paths, URLs, and in-memory images. The hosted mapping is a build-time decision, not something this page guesses. Text inputs use the plain string-list shape shown. Second, the response on this route family follows the standard embeddings shape. It is a data array holding one embedding per input, in the order the inputs were sent, plus a usage block. Metering counts tokens from that usage record. The count is summed across the batch.
curl
curl -X POST "https://api.ironstratum.com/v1/embeddings" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wemm-embed",
"input": [
"A product page with three photos and a specification table.",
"A support ticket describing a checkout failure."
],
"encoding_format": "float"
}'
python
import os
import requests
resp = requests.post(
"https://api.ironstratum.com/v1/embeddings",
headers={"Authorization": "Bearer " + os.environ["KEY"]},
json={
"model": "wemm-embed",
"input": [
"A product page with three photos and a specification table.",
"A support ticket describing a checkout failure.",
],
"encoding_format": "float",
},
timeout=30,
)
resp.raise_for_status()
for item in resp.json()["data"]:
print(item["index"], len(item["embedding"]))
openai-sdk
The OpenAI SDK ships a native embeddings method, so code pointed at any OpenAI-compatible embeddings endpoint migrates by changing two things: the base URL and the model id.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.ironstratum.com/v1",
api_key=os.environ["KEY"],
)
result = client.embeddings.create(
model="wemm-embed",
input=[
"A product page with three photos and a specification table.",
"A support ticket describing a checkout failure.",
],
)
for item in result.data:
print(item.index, len(item.embedding))
At full size each embedding comes back with 2,048 floats. The usage block carries the token count that meters the request against the prepaid wallet. Requests the gateway refuses bill nothing.
Benchmarks
This platform has measured nothing on this model. No lane serves it, so there is nothing to measure. The numbers that follow are the publisher's own runs. They come from the evaluation tables on the model card (which reproduce the technical report's tables), read on 2026-09-24. When the row lands, this section gains this platform's own dated measurements. The law is the same one every other model page here follows.
MMEB-v2, the publisher's comparison axis, covers 78 datasets. Image and video tasks use Hit@1, visual-document tasks use NDCG@5, and higher is better.
| Model | Size | AVG | Image | Video | VisDoc |
|---|---|---|---|---|---|
| VLM2Vec | 2B | 47.8 | 59.7 | 29.0 | 44.0 |
| GME | 2B | 55.4 | 51.9 | 33.9 | 76.8 |
| VLM2Vec-V2 | 2B | 59.3 | 64.9 | 34.9 | 69.2 |
| Qwen3-VL-Embedding | 2B | 73.2 | 75.0 | 61.9 | 79.2 |
| DME-Small (closed submission) | 2B | 74.8 | 75.9 | 65.6 | 79.9 |
| WeMM-Embedding | 2B | 77.9 | 79.6 | 70.8 | 80.7 |
| VLM2Vec | 8B | 53.2 | 65.5 | 34.0 | 49.1 |
| GME | 8B | 59.2 | 56.0 | 38.6 | 79.3 |
| Qwen3-VL-Embedding | 8B | 77.8 | 80.1 | 67.1 | 82.4 |
| DME-Medium (closed submission) | 9B | 78.4 | 79.8 | 70.8 | 82.0 |
How to read it, with the labels on. It is a publisher-run table, so the model being released tops the open rows; that is how release tables work. The two DME rows are closed-source leaderboard submissions without released weights or a public endpoint, and the card marks them as such. They are comparison context, not deployable options. The load-bearing placement is this. At the 2B size, WeMM-Embedding averages 77.9 against 73.2 for Qwen3-VL-Embedding 2B. It also edges the open 8B class in the same table. That placement is the basis for the report's claim. The claim is that the 2B variant surpasses the previously leading 8B open-source baseline on MMEB-v2. The family's larger variants score higher still on the same table, 79.2 at 4B and 80.6 at 9B. What the table does not carry matters too. Nomic Embed Multimodal appears nowhere in it, and no MMEB-v2 number for the Nomic models exists in the sources this page records. The three-way comparison buyers actually ask for does not exist in public sources. That gap is the reason this section reads the table. It does not point past it.
One more honest row is MMEB-v3, a wider 190-task axis that includes audio tasks. On it the 2B model averages 56.0 overall with the audio column at 0.0, because unsupported tasks are scored zero. The benchmark and the card agree on the boundary.
The deployment question the search results ask about directly is what hardware it needs. It has no vendor answer anywhere today, and this page will not invent one. What arithmetic supports is this. About 2.72B parameters at bf16 is roughly 5.4 GB of weights before activations and caches. The card's local routes (transformers, sentence-transformers, vLLM, SGLang) all assume a CUDA GPU. Measured memory use on this platform's own hardware publishes with the build, dated, in this section.
Getting started
- Read the primaries. The model card is short and complete: install pins, local code for every input class, the Matryoshka guidance, and both evaluation tables. The technical report carries the training story and the deployment account.
- Try it locally if you have a CUDA GPU. The sentence-transformers route is the fastest start: load the model, call encode_query on text and encode_document on strings, image URLs, and video URLs, and read the similarity matrix.
- Write the integration against the tabs. The request shape is the route family's real parse law, so the client written now works the day the row lands by changing nothing.
- When the row lands: sign up, issue an API key, fund the wallet, and run the curl tab. The rate publishes with the row in the machine-rendered price surfaces, and this page's metadata gains its price line from the same catalog source the same day.
To watch for the row, the models index shows every row's state as rows land. The embeddings category maps the route family, with bge-m3 as the text-only answer there today. Document flows pair with the print OCR lane. The classification models in the same planned set have their own family page at classification. The exact request fields for the route family sit in the API reference.