HSWQ SAM3 Detect
Type a word, get masks, boxes and your image back
- model
- image
- conditioning
- bboxes
- masks
- bboxes
- image
The payoff node
SAM3 detects by concept. Type "person" and it returns a mask for every person in the frame in one pass - no GroundingDINO box-then-SAM-mask two-step, no trained YOLO for something nobody has weights for. That's why it became the assumed masking engine inside most 2026 ComfyUI mask editors.
This node is the business end of it. Type "her left hand", get a mask, send it to a detailer - a promptable segmenter is a detector like any other.
The inputs you'll actually touch
Required: model (a SAM3 MODEL, from the HSWQ SAM3 loader or CheckpointLoaderSimple), image, threshold (default 0.50), refine_iterations (default 2), individual_masks (default false).
thresholdonly bites on the text path: detector scores are sigmoid'd and anything under it is dropped. 0.5 keeps junk on a busy frame; 0.7 is where I'd start for "person".refine_iterationsis the SAM mask decoder passes per detection.0gives the raw detector mask upscaled - fast, blobby, fine for seeding an inpaint.2is the default for a reason: it's what snaps a box to an edge.individual_masksflips between one union mask per image and one mask per object - also your fix when a single mask swallows two subjects.
Optional, and this is where the interesting prompts live: conditioning (your CLIPTextEncode("person")), bboxes (boxes to segment within, or an exemplar), and positive_coords / negative_coords, which take JSON point prompts in pixel coordinates:
[{"x": 512, "y": 300}, {"x": 700, "y": 410}]
Those two are declared force_input, so there's no widget to type into; wire a string node in. That's the first thing people trip on.
Outputs
masks (MASK) → MaskPreview, an inpaint conditioning node, SetLatentNoiseMask, or a SEGS path into a detailer. bboxes (BBOXES) → the newer boxes type, for logging scores or chaining into another Detect node. image (IMAGE) → your input straight through, unchanged, so LoadImage → Detect → PreviewImage keeps the graph linear. Resizing happens on an internal copy; you get your resolution back.
One shape caveat: individual_masks on gives you every object concatenated into one flat batch, so per-frame grouping is lost - per-object masks on a batch is a case for one image at a time.
How it works
The image is resized to 1008×1008 internally (bilinear, no crop) - SAM3's working resolution. Three prompt channels feed the model:
- Points.
positive_coordssend label 1,negative_coordslabel 0; the node runsforward_segmentwith those points, looping the decoderrefine_iterationstimes. - Boxes. With no text prompt, each box becomes a SAM box prompt the same way. With a text prompt present, boxes go to the detector as exemplars instead.
- Text. The detector runs on the frame, scores are sigmoid'd and thresholded, then sorted and cut to
max_detections(1 for a plainCLIPTextEncode). Each survivor is refined: crop the box plus 10% padding, upscale to 1008, run the decoderrefine_iterationstimes, scale back, and union with the coarse mask - refinement can only add pixels, never punch a hole in a good mask.
Worth knowing on the INT8 story: the node's runtime weight guard dequantizes INT8 layers back to float16 before the forward pass, deliberately, to keep the SAM3 decoder off kernel and DynamicVRAM bugs - so masks are equivalent on fp16 and INT8 checkpoints, and INT8 buys load footprint here, not speed.
Install
One install for the whole pack - ComfyUI Manager, search ComfyUI-HSWQ-Loader-and-Tools, or:
cd ComfyUI/custom_nodes
git clone https://github.com/ussoewwin/ComfyUI-HSWQ-Loader-and-Tools
# restart ComfyUI
It lives under HSWQ/Detection, searchable as sam3, segment anything, open vocabulary. You need a SAM3 checkpoint in diffusion_models, sams, detection or checkpoints, plus the same file through CheckpointLoaderSimple if you want the text-encoder half for conditioning.
And the pack's universal rule: put General Purge VRAM V2 (ComfyUI-DistorchMemoryManager) at the end of the workflow with the HSWQ toggle on, or HSWQ's residual GPU state will bite you on the second run.
Troubleshooting
- Empty masks on a text prompt. On older pack versions, pre-split
language_backbonekeys in the INT8 checkpoint couldn't be remapped, so text embeddings were corrupt and the detector found nothing. Fixed by the SAM3 CLIP remap patch - update the pack. - Nothing detected with only
modelandimagewired. There's no prompt. No text, boxes or points means no detections, and you get a zero mask. - Small objects missed. That internal 1008×1008 resize is the constraint - a face filling 2% of a 4K frame is a handful of pixels. Crop first, or prompt something bigger.
Buffer too smallon a DynamicVRAM (--fast-style) build. The weight guard strips stale vbar attributes after dequantizing, so the cast path won't reuse an INT8-sized buffer for fp16 weights. If it still fires, it doesn't recognise your build.- Alternatives. ComfyUI-RMBG bundles SAM3 with GroundingDINO behind one node set (GPL-3.0, wants Triton). For plain background removal neither is the right tool - BiRefNet is.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| image | IMAGE | — | |
| threshold | FLOAT | 0.500–1 | — |
| refine_iterations | INT | 20–5 | — |
| individual_masks | BOOLEAN | false | — |
| conditioningopt | CONDITIONING | — | |
| bboxesopt | BBOXES | — | |
| positive_coordsopt | STRING | — | |
| negative_coordsopt | STRING | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| masks | MASK | — |
| bboxes | BBOXES | — |
| image | IMAGE | — |