Remove Background
Cut any subject out in one step — and it ships with ComfyUI
- bg_removal_model
- image
- mask
You've generated a great shot and the background is killing it. Or you have a product photo with a horrible floor, a character you want to move somewhere else, or a batch of images that all need the same treatment. RemoveBackground is the node that makes that a two-click affair - and unlike the removbg sites everyone used in 2023, it runs entirely on your own GPU, no API key, no upload, no per-image pricing.
It landed in ComfyUI core in May 2026, bundled with a loader and a built-in BiRefNet model, which means the most commoditized operation in this ecosystem finally has a first-class home instead of a pile of custom nodes. The name is a small lie, though: this node doesn't remove anything. It produces a mask, which you then feed into whatever wants a mask. That turns out to be the useful half, because the mask is the part you can reuse.
How it works
You need two nodes together. LoadBackgroundRemovalModel (under model/loaders) picks the model file; RemoveBackground takes that model plus your image and runs it. Internally the image is resized to 1024×1024 - BiRefNet's native resolution - the model predicts a foreground probability per pixel, and the result is resized back to your original size with a sigmoid in between. What comes out is a MASK tensor the same size as your image, where bright = subject.
The model file is birefnet.safetensors (~444MB) and it goes in ComfyUI/models/background_removal/. ComfyUI usually offers to fetch it when you add the loader for the first time; if not, grab it from the Comfy-Org/BiRefNet repo on Hugging Face and drop it in that folder. The loader lists whatever's in there, but it only accepts the stock BiRefNet weight layout - try to sneak an InSPyReNet or u2net file in and you get the loader's blunt error: "background model file is invalid and does not contain a valid background removal model."
The two inputs and the one output
That's the whole schema: bg_removal_model (the loaded model) and image. You don't tune anything - no thresholds, no size knobs. The output is a single mask. Keep in mind it's the foreground mask (subject = white). If you actually want a transparent PNG, the official blueprint shows the standard wiring: invert the mask, then feed it into JoinImageWithAlpha. Or skip the PNG entirely and use the mask where masks live - SetLatentNoiseMask for local img2img redraws, inpainting, or compositing nodes like PorterDuffImageComposite to drop the subject onto a new scene.
Where people get burned
The mask comes from a 1024-resolution pass even on a 4K input, then gets upscaled to match. Feed it a huge image and the edges soften - not because BiRefNet is bad, but because you're looking at an upsampled 1024-grade mask. The HR weights exist and are sharper, but this loader won't run them, so for big files you're stuck with the built-in model or a custom node.
Bigger trap: this is a segmentation model, so it labels every pixel foreground-or-background. Hair flyaways, veils, glass, smoke - anything genuinely semi-transparent gets flattened into a hard decision, and the cutout looks fine against grey but wrong against a coloured background. That's not a bug in the node; it's the output type. If you need true partial alpha you need a matting model, which this doesn't do.
One more, borrowed from the training folks: don't batch-remove backgrounds to clean up a LoRA dataset. It teaches the model to draw blank backgrounds. Keep the originals.
The good news is the built-in model is fast - tens of milliseconds per 1024 image on a decent GPU - and once you've got the mask, everything downstream is just normal ComfyUI.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| bg_removal_model | BACKGROUND_REMOVAL | Background removal model used to generate the mask | |
| image | IMAGE | Input image to remove the background from |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| mask | MASK | Generated foreground mask |