BD Parts Builder 2 (Qwen 2.1)
Qwen 2.1 layer decomposition that trusts the model for *where*, not for pixels
- image
- model
- clip
- vae
- head_mask
- depth_image
- parts
- complete_parts
- base_image
- layers_preview
- report
What it's for
Take a character headshot and break it into asset layers - hair, glasses, mouth, brows, hat, whatever the closed vocabulary allowed - each on its own RGBA layer, in the right paint order, plus a version of the head with the accessories removed. Then rebuild the head from those layers and have it come back identical to the source.
That's the whole point, and it's why this is more than a segmentation wrapper: it uses no segmentation model at all. The older BrainDead parts pipeline needed SAM3 masks and an IoU dedup pass; this one asks Qwen Image 2.1 with prompts, then refuses to trust the pixels it gets back. Our 3D generation doc covers why this asset-prep layer is where the hours actually go.
How it works
Three things happen per item.
It votes. presence carries the vision model's JSON answer to the vocabulary's true/false question (or a typed list like hair, eyes, hat if you'd rather skip the VLM). Only items that came back true are ever requested - 2.1 draws anything it's asked for.
It edits. For every present item, two Qwen Image 2.1 passes at 40 steps / cfg 1: a VISIBLE edit ("extract only the X exactly where it is", RGBA), trusted for where the item is and not for how it looks; and a COMPLETE edit ("decompose the head into layers, output only the X layer") covering the whole object including the parts you can't see, split afterwards into a front piece and a _back piece depending on whether it sits over bare skin or behind the head.
It resolves the pixels from the source. Each source pixel goes to whichever edit "explains" it (colours within explained_max, default 60 levels), and the visible layer is built out of the source's own pixels. An edit only owns pixels if at least fidelity_min (0.5) of its own match the source; an item that came back hidden or restyled owns nothing and survives only as a complete layer. So the visible layers rebuild the source by construction, which is why a comparison pass afterwards lands near zero.
Paint order is read off the source too: where two complete layers overlap, whichever one the source actually shows is in front. The optional depth_image (a Lotus-2 map or raw_linear, brighter = nearer) only breaks ties, and head-worn items are forced in front of hair since the overlap vote flips on near-ties.
The inputs and outputs that matter
Wire model (Qwen Image 2.1 through QwenImage21Cache), clip (qwen3vl_8b, CLIPLoader type qwen_image) and vae (the 2.1 RGBA VAE). image is the headshot, used as given. presence and vocabulary come from the VLM vote and BD Parts Vocabulary. head_mask (optional) is where the head is - the shipped workflow inverts the image alpha into it. Then the sampler block: seed, steps 40, cfg 1, euler, simple.
Of the switches, make_complete and make_base are the ones you'll touch: complete off for a faster run, base off if you don't need the accessory-free head. colour_retry gives a failed accessory edit one more go with its measured colour named ("the white sunglasses") - never for hair, brows, eyes or mouth, where that measured colour is the accessory's.
Outputs: parts and complete_parts (two PARTS_BUNDLEs), base_image, layers_preview, report. Send parts plus base_image to BD Parts Export for the PSD that rebuilds the source; send complete_parts on to BD Parts Builder 2 Plates and BD Parts Builder 2 Assemble. Read report - it carries the vote, the paint order and its evidence, and per-item fidelity.
Installing it
ComfyUI Manager → search "BrainDead" → install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/BizaNator/ComfyUI-BrainDead
cd ComfyUI-BrainDead && pip install -r requirements.txt
You need a ComfyUI new enough to have the core Qwen Image 2.1 nodes (TextEncodeQwenImage21, QwenImage21Cache) - this imports them directly and tells you at run time if they're missing. Models: Qwen Image 2.1 unet, qwen3vl_8b text encoder, 2.1 VAE, plus a vision model for the vote (AILab_QwenVL with Qwen3-VL-8B-Instruct) and optionally Lotus-2 for the depth tie-break.
Where people get burned
These aren't folklore; they're in the node's own source comments, each bought with a run.
Never feed a later stage 2.1's raw output. The author measured background noise amplifying 0.9 → 5.4 → 48.8 across chained stages. Everything downstream cuts onto pure white first, and there are at most two generations away from the source - a third turns skin into "crinkled foil". That's why the plates are built from the bald, and the bald from the source.
Don't ask for items the vote didn't find, and don't write framing instructions like "head only, no neck" where the frame has to hold: it recomposes the shot.
Budget the runtime. Each present item is two edits plus retries, plus the base image - a six-item head is thirteen 40-step passes before the plates even start.
One oddity in the logs: every edit runs with ComfyUI's cuDNN SDPA backend suspended, to dodge a "cuDNN Frontend error: No valid execution plans built" failure seen when this shares a process with Lotus-2's FLUX and Qwen3-VL. Same mask, a little slower.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Headshot (e.g. HeadMasters MASTER 1). Its RGB is used as given. | |
| model | MODEL | Qwen Image 2.1 through QwenImage21Cache. | |
| clip | CLIP | qwen3vl_8b, CLIPLoader type qwen_image. | |
| vae | VAE | Qwen Image 2.1 VAE (RGBA). | |
| presence | STRING | The vision model's JSON answer (AILab_QwenVL with BD Parts Vocabulary's vlm_prompt), or a typed list: 'hair, eyes, mouth, hat'. | |
| vocabulary | STRING | hair | hair | hair | no eyebrows | eyebrows | eyebrows | no eyes | eyes | eyes | no mouth | mouth | mouth and lips | no beard | beard | beard | no moustache | moustache | moustache | no glasses | glasses | glasses | yes sunglasses | sunglasses | sunglasses | yes hat | hat or cap | hat | yes helmet | helmet | helmet | yes headband | headband or bandana | headband or bandana | yes headphones | headphones | headphones | yes earrings | earrings | earrings | yes piercings | piercings | piercings | yes | From BD Parts Vocabulary. key | ask | noun | accessory. |
| seed | INT | 202609310–18446744073709550000 | Every edit uses this seed; a frame-proof retry uses seed+1, seed+2 ... |
| steps | INT | 401–200 | Qwen Image 2.1 model card: 40 for edits. |
| cfg | FLOAT | 1.00–20 | — |
| sampler_name | COMBO | euler | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 |
| scheduler | COMBO | simple | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 |
| make_complete | BOOLEAN | true | Also make the COMPLETE layers. |
| make_base | BOOLEAN | true | Also make the head without items. |
| colour_retry | BOOLEAN | true | One retry with the measured colour named ('the white sunglasses') for an ACCESSORY whose edit does not match the source. Never for hair/brows/eyes/mouth: next to an accessory their measured colour is the accessory's. |
| base_attempts | INT | 31–8 | Head without items: seeds tried (seed, seed+1, ...) until it is frame-true. |
| fidelity_min | FLOAT | 0.500–1 | Share of an edit's pixels that must match the source (< 40 levels) for it to own pixels. |
| explained_max | FLOAT | 601–255 | A pixel is explained by an edit when their colours are within this many levels. |
| head_maskopt | MASK | Where the head is (1 = head), e.g. the image's alpha. None: non-white pixels. | |
| depth_imageopt | IMAGE | BD Lotus2 Predict map or raw_linear - BRIGHTER = NEARER. Breaks paint-order ties only. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| parts | PARTS_BUNDLE | — |
| complete_parts | PARTS_BUNDLE | — |
| base_image | IMAGE | — |
| layers_preview | IMAGE | — |
| report | STRING | — |