Fal AI fal-ai/seedvr/upscale/image
SeedVR-class upscaling on fal.ai's servers β no GPU, and some oddly named inputs
- text
- API_JSON
SeedVR2 is the upscaler the community has basically crowned as "more detail" champ - the KB's upscaling essay calls it "the incumbent since late 2025 and still it," and roughly one upscaling thread in three mentions it. The catch has always been hardware: even the 3B model wants a GPU, and if you're running ComfyUI on a CPU-only VM, the whole family is off the table. That's the gap this node fills. It's fal.ai's hosted fal-ai/seedvr/upscale/image endpoint, so the upscaling happens on their servers and your box just sends pixels and gets pixels back. Same quality family, zero local VRAM.
Here's the honest catch before you wire anything: the auto-generated input names on this node are a mess. This pack builds its nodes from API schemas, and for this particular endpoint the mapping flattened the real parameters into generic slots. The shipped schema file shows what the API actually accepts - upscale_factor (2), upscale_mode ("factor" or "target"), target_resolution, noise_scale (0.1), output_format - but on the node itself you'll see generic INT, STRING, FLOAT, and BOOLEAN widgets in a fixed order instead of friendly names. The FLOAT slot (default 2) is your upscale factor; the BOOLEAN toggles related options.
Two things in the required inputs will trip you up specifically:
- The
IMAGEinput here is not an IMAGE tensor - it's aSTRINGfield where you paste an image URL (or a base64 data URI). You cannot drag a wire from Load Image into it. This is the biggest "wait, what?" and it's a schema artifact, not a bug. sync_mode(default false). Off, fal returns a URL to the result; on, it returns the media as a data URI directly. If you want to feed the result back into another node that expects inline data, flip it on.
Outputs are text (a STRING - the result URL, or data URI in sync mode) and API_JSON (the payload that was sent). Note there's no IMAGE tensor output on this particular node; you get a string and you take it from there (fetch the URL, save it, or feed a URL-accepting node).
Given the anonymous slots, the two features the pack gives every schema node become your lifeline: dry_run skips the actual call and returns a mock plus the exact JSON that would have been sent, and the API_JSON output shows you that payload after every run. When the slot order is ambiguous, dry-run and read the JSON. That's not a workaround - it's the intended debug flow, and the pack ships a DEBUG_API_TRUSTYPANGOLIN=true env var that makes the node print even more detail to the console.
Install via ComfyUI Manager (search ComfyUI-API-DockerCPU) or:
cd ComfyUI/custom_nodes
git clone https://github.com/trustypangolin/ComfyUI-API-DockerCPU
cd ComfyUI-API-DockerCPU
pip install -r requirements.txt
Set FAL_KEY (required) and restart. It lives under π¨ DockerCPU API/π¨ FalAi.
The money is real here - fal charges per upscale, and megapixels matter, so a 2x on a big image costs more than a 2x on a thumbnail. And before you judge SeedVR on this node's output, remember the KB's warning: people who call SeedVR "smoothed out" are usually running a broken quant or a wrong setting, not the model. Check upscale_mode/noise_scale in that API_JSON before you blame the upscaler.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| dry_run | BOOLEAN | false | β |
| sync_mode | BOOLEAN | false | β |
| IMAGE | STRING | β | |
| INT | INT | 0 | β |
| STRING | STRING | β | |
| BOOLEANopt | BOOLEAN | false | β |
| FLOATopt | FLOAT | 2.001β10 | β |
| INTopt | INT | 0 | β |
| STRINGopt | STRING | β |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| text | STRING | β |
| API_JSON | STRING | β |