U2-Net-p background removal (rembg)
u2netp@cd3a3d67 fp32 vetted · active onnxruntime-web ≥ 1.17.0 wasmwebgpu
Downloads 4.4 MB once from models.skillsafe.ai, then stays cached for every
SkillSafe app that uses it. Inference runs on your device; nothing you enter is uploaded to load it. Licensed
Apache-2.0 · source Hugging Face tomjackson2023/rembg at cd3a3d6767a7.
See it working
Public apps that declare this model. Open one and the download you see is this file.
- BG Studio — on-device background removerOpen app
Remove or replace image backgrounds with AI that runs 100% in your browser — photos are never uploaded. Replace with colors, gradients, your own image or a blurred original; refine with erase/restore brushes; auto color enhance; export PNG/JPEG/WebP. Free and unlimited. Built on U2-Net (Qin et al., Apache-2.0), onnxruntime-web (Microsoft, MIT) and rembg's ONNX export (MIT).
Files
Every file is served at an immutable URL; the canonical form is the SHA-256 itself. Tokenizer and config JSON are not here by design — they ship in your app bundle.
| Path | Format | Size | SHA-256 | |
|---|---|---|---|---|
u2netp.onnx | onnx | 4.4 MB | 309c8469258d…f4ddd8 |
Signature
Graph inputs and outputs read from the ONNX bytes at vetting — these are the tensor names your session.run() call feeds and reads. Symbolic dimensions are shown by name.
Inputs
input.1float32 [1, 3, 320, 320]
Outputs
1959float32 [1, 1, 320, 320]1960float32 [1, 1, 320, 320]1961float32 [Sigmoid1961_dim_0, Sigmoid1961_dim_1, Sigmoid1961_dim_2, Sigmoid1961_dim_3]1962float32 [Sigmoid1962_dim_0, Sigmoid1962_dim_1, Sigmoid1962_dim_2, Sigmoid1962_dim_3]1963float32 [Sigmoid1963_dim_0, Sigmoid1963_dim_1, Sigmoid1963_dim_2, Sigmoid1963_dim_3]1964float32 [Sigmoid1964_dim_0, Sigmoid1964_dim_1, Sigmoid1964_dim_2, Sigmoid1964_dim_3]1965float32 [Sigmoid1965_dim_0, Sigmoid1965_dim_1, Sigmoid1965_dim_2, Sigmoid1965_dim_3]
How to use it
Three steps: declare the model on your release, load it through the SDK (verified and cached), hand the bytes to the runtime. The examples below are generated from this entry, so ids, paths and tensor names are exact.
Add to the body of POST /v1/apps/{slug}/releases (or a release session). An unknown or withdrawn model is refused with a 400 naming it; the app page then shows "downloads 4.4 MB · runs on your device" and /models.txt carries the attribution.
{
"models": [
{
"id": "u2netp",
"revision": "cd3a3d67"
}
]
} Streams with progress, verifies the SHA-256 against the catalogue, keeps a durable copy in the app's Cache API and reports whether the bytes came from cache or the network.
<script src="/sdk.js"></script> <!-- vendored from https://skillsafe.ai/apps-sdk/v1.js -->
const ss = SkillSafe.init({ slug: "your-app" });
const caps = await ss.models.capabilities(); // { webgpu, wasm, wasmSimd, storage }
const bytes = await ss.models.load("u2netp@cd3a3d67", "u2netp.onnx", {
onProgress: (p) => (bar.style.width = Math.round(p.ratio * 100) + "%"),
}); // ArrayBuffer — SHA-256 verified, cached
// Later visits: await ss.models.status("u2netp@cd3a3d67") → { cached: [...], missing: [] }
// Background prefetch on a landing page: ss.models.warm("u2netp@cd3a3d67") The runtime itself ships in your bundle as a vetted {path, sha256} reference — only the weights come from the registry. Pass the bytes in; do not re-fetch by URL.
// onnxruntime-web 1.17.0 ships in your bundle as a vetted {path, sha256} reference —
// dist/ort.wasm.bundle.min.mjs + dist/ort-wasm-simd-threaded.wasm (or the .jsep pair for WebGPU).
import * as ort from "./ort.wasm.bundle.min.mjs";
ort.env.wasm.wasmPaths = { wasm: "/ort-wasm-simd-threaded.wasm" }; // object form, never a prefix string
ort.env.wasm.numThreads = 1; // app hosts have no COOP/COEP
const bytes = await ss.models.load("u2netp@cd3a3d67", "u2netp.onnx", { onProgress });
const session = await ort.InferenceSession.create(new Uint8Array(bytes), {
executionProviders: ["wasm", "webgpu"],
});
// Feeds are named after the graph inputs (read from the file, see the signature above):
const feeds = {
"input.1": new ort.Tensor("float32", new Float32Array(n), [1, 3, 320, 320]),
};
const out = await session.run(feeds);
const 1959 = out["1959"].data; // float32 [1, 1, 320, 320]
const 1960 = out["1960"].data; // float32 [1, 1, 320, 320]
const 1961 = out["1961"].data; // float32 [Sigmoid1961_dim_0, Sigmoid1961_dim_1, Sigmoid1961_dim_2, Sigmoid1961_dim_3]
const 1962 = out["1962"].data; // float32 [Sigmoid1962_dim_0, Sigmoid1962_dim_1, Sigmoid1962_dim_2, Sigmoid1962_dim_3]
const 1963 = out["1963"].data; // float32 [Sigmoid1963_dim_0, Sigmoid1963_dim_1, Sigmoid1963_dim_2, Sigmoid1963_dim_3]
const 1964 = out["1964"].data; // float32 [Sigmoid1964_dim_0, Sigmoid1964_dim_1, Sigmoid1964_dim_2, Sigmoid1964_dim_3]
const 1965 = out["1965"].data; // float32 [Sigmoid1965_dim_0, Sigmoid1965_dim_1, Sigmoid1965_dim_2, Sigmoid1965_dim_3] Immutable, credential-free, Access-Control-Allow-Origin: *, range requests honoured. The host refuses requests carrying a foreign Origin; a plain curl is fine.
https://models.skillsafe.ai/u2netp@cd3a3d67/u2netp.onnx curl -sSL -o u2netp.onnx "https://models.skillsafe.ai/u2netp@cd3a3d67/u2netp.onnx"
shasum -a 256 u2netp.onnx # 309c8469258dda742793dce0ebea8e6dd393174f89934733ecc8b14c76f4ddd8 Licence & attribution
Apache-2.0 · licence text · notice
U2-Net: Going Deeper with Nested U-Structure for Salient Object Detection (Qin et al.), lightweight u2netp weights as distributed by rembg; mirrored on Hugging Face by tomjackson2023. Licensed under the Apache License 2.0.
Apps that declare this model get this text in their generated /models.txt, so a licence that requires a notice always carries one.