arkennemasis fal · Flux 2 Klein 4B · $0.005/MP
Half a cent per megapixel for the Apache-licensed one
- images
- image_paths
- timings
- has_nsfw_concepts
- seed
- prompt
- info
Klein is what happened after Black Forest Labs shipped a 32B model nobody could run and then fixed it properly. "Klein" is German for small, and the 4B distilled variant is the interesting one: Apache 2.0 weights, four-step sampling, runs on an 8GB card locally, and it does text-to-image and editing in the same model. On fal this node drives it for $0.005 per megapixel - half a cent for a 1024×1024 image. That's cheap enough that batching four to pick one is the sane default.
It's also, per the knowledge base, "very slept on" - people assume small means weak, then find it handling virtual try-on with three references at close to a 100% hit rate.
What you're actually running
The distilled 4B: 4 inference steps, and guidance baked into the weights instead of applied at sample time. That second part is why this node has no guidance_scale field and no negative_prompt field - that's not the pack dropping inputs, that's the model. There's no unconditional pass for a negative prompt to steer, so the box would be a lie.
The price of that shortcut is anatomy. Extra fingers and the occasional third limb are the documented, unfixed complaint about Klein, and on four steps you'll hit them at volume. The community's fix, which works, is worth stealing: run 8 steps instead of 4. The launch-week report was blunt - 8 steps with guidance nudged slightly above 1 fixes "body horror", finger counts and text. There's no guidance field here, but num_inference_steps is right there, and fal bills per megapixel, not per step. Two extra runs' worth of wall time, zero extra dollars.
The inputs
prompt - Klein's encoder is a Qwen3 LLM wrapped in a chat template. It reads sentences, not tags. Prompt weighting is disabled for this text encoder, so ((face:1.4)) does exactly nothing; what works is plain language with clear ownership: "A realistic photo of a woman sitting on a beach. She is looking at the camera." Structured JSON-ish prompts reportedly do well too, because you're talking to an LLM.
num_inference_steps - 4 by default. Try 8.
image_size - landscape_4_3 by default, or custom with image_size_width / image_size_height.
num_images - the cost multiplier, and at this price the right way to work. Four 1MP renders is two cents.
output_format - png, jpeg or webp.
enable_safety_checker - on. A flagged render comes back as a black square; disabling it requires account authorization on fal, and unauthorised requests get checked anyway.
Outputs
images is the IMAGE output (batched if you asked for several) - into SaveImage, an upscaler, or a contact sheet. image_paths is where they landed as a STRING, timings is fal's timing JSON, has_nsfw_concepts tells you what the checker thought, seed is an INT to lock a good one, prompt echoes what the model received, and info is JSON with the request id, cost estimate, saved files and fal's full answer.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Hishamahmer/comfyui-arkennemasis
Restart ComfyUI and it's under arkennemasis → fal → Image → Flux. ComfyUI-Manager → Install via Git URL also works. The pack's only declared dependency is httpx, for its ChatGPT/Codex nodes; the fal provider uses Python's standard library, so the install is the clone and nothing else.
Key, one line in the .env by run_nvidia_gpu.bat:
FAL_KEY=your-key-from-fal.ai/dashboard/keys
Where people get burned
Anatomy, again. No prompt fixes it - the failure is baked in during the first couple of steps, which is why the mitigation is steps and batching rather than wording. Batch four, pick the best, inpaint the hand.
Signature hallucination. Klein base likes to drop a mark in the bottom-right of stylised images, and with no negative prompt at CFG 1 there's nothing to argue with. Crop or inpaint if it lands somewhere ugly.
Cached reruns. reuse_identical_run is on by default, so the same settings plus the same files in output/fal returns the previous result without charging. Turn it off for variation. And if a job dies after leaving fal's side, the pack's free Recover Result node collects it by request id from output/fal/_requests.jsonl instead of you paying twice.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | The prompt to generate an image from. | |
| seed | INT | -1-1–2147483647 | The seed to use for the generation. If not provided, a random seed will be used. -1 leaves it to the model. |
| num_inference_steps | INT | 44–8 | The number of inference steps to perform. |
| image_size | COMBO | landscape_4_3 | The size of the image to generate. 'custom' uses the width and height below. |
| image_size_width | INT | 102416–14142 | Width in pixels when image_size is 'custom'. |
| image_size_height | INT | 102416–14142 | Height in pixels when image_size is 'custom'. |
| num_images | INT | 11–4 | The number of images to generate. |
| enable_safety_checker | BOOLEAN | true | If set to true, the safety checker will be enabled. Disabling it requires account authorization; unauthorized requests are always checked, and images flagged as unsafe are returned as black images. |
| output_format | COMBO | png | The format of the generated image. |
| max_cost_usdopt | FLOAT | 20.00–100000 | Safety cap. If the estimated cost of this run is above this many US dollars the node stops BEFORE sending anything to fal. 0 = no cap. |
| reuse_identical_runopt | BOOLEAN | true | If these exact inputs (the settings AND the same pictures/clips/audio) were already paid for and the files are still in output/fal, return them instead of paying again - also after a ComfyUI restart. Turn off for a fresh take with the same settings. |
| extra_jsonopt | STRING | Advanced: a JSON object merged into the request last, for any fal field this node has no box for. Example: {"seed": 7}. Leave empty normally. | |
| max_concurrentopt | INT | 11–32 | How many paid fal calls may run at the same time in one run, across every fal node. 1 (default) = one after another. This node starts its paid part only while fewer than this many fal calls are running. Once any fal node fails, the ones still waiting are not started, so nothing more is billed. |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| image_paths | STRING | — |
| timings | STRING | — |
| has_nsfw_concepts | STRING | — |
| seed | INT | — |
| prompt | STRING | — |
| info | STRING | JSON: request id, cost estimate, saved files and fal's full answer. |