ONNX export of facebook/sapiens2-pretrain-0.1b, a vision transformer pretrained on 1 billion human images, packaged for browser inference via onnxruntime-web.
File
Size
Use
sapiens2_0.1b_int8.onnx
116 MB
Browser (recommended)
sapiens2_0.1b_fp32.onnx
458 MB
Server-side / higher precision
example_embeddings.js
—
Drop-in browser ES module
Output: a (batch, 768) float32 vector per image (CLS token).
What are embeddings?
The model encodes an image into a 768-dimensional vector that captures human-centric semantics — pose, body shape, clothing, and identity. Two images with similar people in similar poses will have embeddings close together in this space. Common uses:
Similarity search — find the most similar person/pose in a collection
Clustering — group images by pose, clothing, or activity
Classification — train a lightweight head on top of frozen embeddings
Retrieval — image → nearest-neighbor lookup in a vector database
Browser quick start
npm install onnxruntime-web
js
1import*as ortfrom"onnxruntime-web";23// Point WASM binaries at the CDN build4ort.env.wasm.wasmPaths="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/";56constMODEL_URL=7"https://huggingface.co/barakplasma/sapiens2-onnx/resolve/main/sapiens2_0.1b_int8.onnx";89constH=1024,W=768;10constMEAN=[0.485,0.456,0.406];11constSTD=[0.229,0.224,0.225];1213// Load once; reuse for all images. ~1-2 s cold start.14exportasyncfunctionloadModel(){15return ort.InferenceSession.create(MODEL_URL,{16executionProviders:["webgpu","wasm"],// WebGPU ~1-3 s/img, WASM ~20-60 s/img17graphOptimizationLevel:"all",18});19}2021// Accepts any <img>, <canvas>, ImageBitmap, or VideoFrame22functionimageToTensor(source){23const canvas =document.createElement("canvas");24 canvas.width=W;25 canvas.height=H;26 canvas.getContext("2d").drawImage(source,0,0,W,H);27const{ data }= canvas.getContext("2d").getImageData(0,0,W,H);// RGBA uint82829const t =newFloat32Array(3*H*W);30for(let i =0; i <H*W; i++){31 t[i]=(data[i *4]/255-MEAN[0])/STD[0];// R32 t[H*W+ i]=(data[i *4+1]/255-MEAN[1])/STD[1];// G33 t[2*H*W+ i]=(data[i *4+2]/255-MEAN[2])/STD[2];// B34}35returnnewort.Tensor("float32", t,[1,3,H,W]);36}3738// Returns a Float32Array of length 76839exportasyncfunctionembed(session, imageSource){40const{ embedding }=await session.run({pixel_values:imageToTensor(imageSource)});41return embedding.data;42}4344// Cosine similarity: 1 = identical direction, 0 = orthogonal, -1 = opposite45exportfunctioncosineSimilarity(a, b){46let dot =0, normA =0, normB =0;47for(let i =0; i < a.length; i++){48 dot += a[i]* b[i];49 normA += a[i]* a[i];50 normB += b[i]* b[i];51}52return dot /(Math.sqrt(normA)*Math.sqrt(normB));53}
Caching in IndexedDB
The INT8 model is 116 MB. After the first load, store it in IndexedDB so repeat
visits skip the download entirely:
See example_embeddings.js — a self-contained ES module
you can drop into any browser project. It exports loadModelCached, embed,
cosineSimilarity, l2Normalize, and findMostSimilar.
Usage example (assumes an <input type="file"> and two <img> elements):
1@article{khirodkarsapiens2,
2 title = {Sapiens2},
3 author = {Khirodkar, Rawal and Wen, He and Martinez, Julieta and Dong, Yuan and Su, Zhaoen and Saito, Shunsuke},
4 journal = {arXiv preprint arXiv:2604.21681},
5 year = {2026}
6}