Nodes/comfyui-fvmtools/Reality Check (LM Studio)
ComfyUI Node

Reality Check (LM Studio)

A small vision model can't judge anatomy, but it can count

By ping1979ping·Created 7 months ago·Updated about 10 hours ago· 3
Reality Check (LM Studio)
  • image
  • passed
  • failed
  • score
  • report
  • json
  • image
◄base_urlhttp://localhost:1234/v1►
◄model►
◄expected_people1►
◄threshold0.50►
◄passes1►
◄temperature0.10►
◄aggregationmedian►
◄check_partstrue►
◄check_peopletrue►
◄check_landmarkstrue►
◄check_handsfalse►
◄check_physicsfalse►
◄check_textfalse►
◄max_image_size1024►
◄timeout120►
◄seed0►
◄on_errorpass►
◄system_prompt►

Ask an 8B vision model "is this pose anatomically impossible?" and it will tell you no. Every time. Including a torso rotated through 180 degrees. This node exists because the author measured that, then built the version that works: don't ask a small model to judge - ask it perception questions with closed answers and do the inferring in Python.

How it works

The model gets asked things like how many heads, arms, hands, legs and feet it can see, whether two bodies look fused, whether front-of-body and back-of-body landmarks appear in the same figure, whether it can see breasts and shoulder blades. Each answer is scored, contradictions between answers become findings, and the worst weighted finding is compared to threshold (default 0.5, and findings land near 1.0, so it's a wide margin rather than a knife edge). One node, one image, passed / failed.

The defaults come from an acceptance run over a 17-image set with eight known-broken pictures: all eight broken ones caught, all eight good ones kept, twice, with different seeds. That's the kind of number that makes a filter usable instead of decorative.

Inputs

  • image, base_url (http://localhost:1234/v1, LM Studio's OpenAI-compatible endpoint), model - the vision model id. Leave it empty and you get whatever LM Studio has loaded, which is a coin flip; a text-only model answers nonsense.
  • expected_people (default 1) - more heads or limbs than this allows counts as a defect.
  • The six probe toggles. check_parts, check_people and check_landmarks are on; check_hands and check_physics are off on purpose. They measured worse than useless: they never fired on a genuinely broken picture and occasionally fired on a clean one. An 8B model can't resolve fingers at any sane resolution, and it reads a compressed mattress as a body sinking through it. check_text is off unless you're rendering scenes with signage.
  • max_image_size (1024) - below about 900 the giveaways blur away, which is a nice way of saying the check that catches extra limbs depends on actually being able to see them.
  • passes + temperature + aggregation - run the probes several times and reduce with median, majority, mean or max. At temperature 0.1 repeated passes give identical answers, so raise both or leave both alone.
  • on_error - the important one. Default pass: if the model can't be reached, the picture survives and the report says why. An inspector that can't see should never silently reject a batch.
  • system_prompt overrides the tuned instrument prompt; empty uses the calibrated one.

Outputs are passed, failed, score, report (human-readable), json (the raw verdict) and image, passed straight through so you can chain this between the loader and the router.

Install

No Python dependencies at all - it's an HTTP client. What it needs is LM Studio running with a vision model loaded and its local server started.

cd ComfyUI/custom_nodes
git clone https://github.com/ping1979ping/comfyui-FVMtools

Restart ComfyUI, or install via Manager with comfyui-fvmtools. Then point base_url at LM Studio and name the model. Pair it with Reality Check Probe before you queue 300 runs.

Where people get burned

Censored models. Measured on an abliterated Qwen3-VL build. A stock instruct model refuses on lingerie or nude material, refuses silently, and every picture in the batch comes back as unavailable - which looks exactly like an endpoint problem. Use an uncensored build for that content.

VRAM. You're now running a VLM and a diffusion model on one card. Load a 4B vision model, not the 32B, and expect the reality check to be the slow step in the loop.

Wrong model name. LM Studio lists models it hasn't loaded, and a call to an unloaded model returns nothing useful. Start the server, load the model, check with the probe node, then queue.

Judging the judges. This node is deliberately narrow: it catches anatomical absurdity and fused bodies. It does not know whether your composition is boring, whether the prompt was followed, or whether the LoRA looks like the person. Use it as a gate in the sorting pipeline - it's a bouncer, not an art director.

CategoryFVM Tools/Batch

Inputs (19)

NameTypeDefaultDescription
imageIMAGE—
base_urlSTRINGhttp://localhost:1234/v1LM Studio's OpenAI-compatible endpoint.
modelSTRINGVision model id. Empty uses whatever LM Studio has loaded. Needs a VLM — a text-only model answers nonsense.
expected_peopleINT11–10How many people the picture should show. More heads or limbs than this allows is a defect.
thresholdFLOAT0.500–1Fail when the worst weighted finding reaches this. Findings score ~1.0, so 0.5 is a wide margin.
passesINT11–9Runs per probe. At temperature 0.1 repeats give identical answers — raise both together, or leave at 1.
temperatureFLOAT0.100–2—
aggregationCOMBOmedianHow repeated passes are reduced. Only matters when passes > 1.
check_partsBOOLEANtrueCount heads, arms, hands, legs, feet — catches duplicated bodies and extra limbs.
check_peopleBOOLEANtrueCount people and spot merged bodies.
check_landmarksBOOLEANtrueFront-of-body and back-of-body landmarks seen at once — catches impossible torso twists.
check_handsBOOLEANfalseFinger counts. Off by default: small models cannot resolve fingers and raise false alarms.
check_physicsBOOLEANfalseFloating bodies and limbs through furniture. Off by default: reads a compressed mattress as a body sinking through it.
check_textBOOLEANfalseGarbled lettering. Worth turning on for scenes with signage.
max_image_sizeINT1024256–2048Long edge sent to the model. Below ~900 the giveaways blur away.
timeoutINT1205–900—
seedINT00–18446744073709550000—
on_errorCOMBOpassWhat to answer when the model cannot be reached. pass: keep the picture and say so — an inspector that cannot see should not reject a batch.
system_promptoptSTRINGOverrides the built-in instrument prompt. Empty uses the calibrated one.

Outputs (6)

NameTypeDescription
passedBOOLEAN—
failedBOOLEAN—
scoreFLOAT—
reportSTRING—
jsonSTRING—
imageIMAGE—