Ask ChatGPT for an image and watch what happens: you type "a cat wearing glasses" and back comes an illustration with lighting, style, framing and a background you never asked for. That is not the image model being generous.
📚 Series "Build Your Own ChatGPT" — 9 parts
1. What's inside · 2. The brain · 3. The eyes (OCR) · 4. The memory (documents) · 5. Images ← you are here · 6. Video · 7. Voice · 8. Tools and agents · 9. Putting it together
Does the brain draw? No. It rewrites.
Between your request and the image model there is an invisible stage: the text model rewrites your request into a detailed prompt. "A cat wearing glasses" becomes something like "photograph of a ginger cat wearing round-framed glasses, soft window light, blurred background, 50mm, high detail".
That stage accounts for much of the quality gap between using ChatGPT and running the same open model on your own machine with the raw text. Image models respond far better to rich description than to three words.
💡 The cheapest piece of your image product
The rewrite is a text call of roughly 200 input and 150 output tokens. On the economy model that costs R$ 0.00026 — a quarter of a thousandth of a real.
For essentially nothing you buy the quality jump that makes users think your generator is better than the competitor's. It is the best cost-to-benefit ratio in this entire series.
Which open model to use
| Family | Best at | Typical VRAM | Note |
|---|---|---|---|
| FLUX | Realism, prompt adherence, text inside the image | 16–24 GB | The open reference of 2026; check the licence of the exact variant |
| Qwen-Image | Text in images, including non-Latin scripts, and editing | 16–24 GB | Deploys in one click inside ComfyUI |
| SDXL and derivatives | A vast ecosystem of styles and fine-tunes | 10–16 GB | Older, but unbeatable for ready-made style variety |
| Distilled variants ("turbo", "schnell") | High volume at low cost | 10–16 GB | 4 to 8 steps instead of 40; cost per image collapses |
The engine tying it together is ComfyUI: it loads the model, exposes an API and lets you build the flow (generate, upscale, remove background, apply style) as a graph. One-click deploy on a card from R$ 2.78 per hour.
The architecture nobody warns you is mandatory
Generating an image takes 2 to 15 seconds. That is an eternity for an HTTP request: the user's browser hangs, the load balancer drops the connection at 30 seconds, and two simultaneous requests queue up invisibly.
The image piece must be asynchronous:
- The user requests. You write the job to a queue and return an id immediately.
- A worker consumes the queue, calls ComfyUI, saves the image to storage.
- The interface tracks state — polling or WebSocket — and shows the image when it is ready.
It looks like bureaucracy and it is what separates a prototype from a product. It is also what enables the next trick, which is where the money is.
⚠️ The hidden cost: a machine kept on, waiting
A card at R$ 2.78/h left running all month costs ~R$ 2,030. If your product generates 3,000 images a month, each image cost R$ 0.68 — a hundred times its real compute cost. You did not pay per image: you paid for idleness.
With a queue you can start the machine when there is work and stop it when the queue drains. The catch is start-up time: loading an image model takes 30 to 60 seconds. So keep the machine alive for a few minutes after the last job rather than stopping instantly — otherwise you pay for the cold start over and over and the user waits for it.
The full flow, in code
from openai import OpenAI
import requests, json
client = OpenAI(base_url="https://gpubrasil.com.br/v1",
api_key="gpub_live_yourkeyhere")
INSTRUCTION = """You rewrite image requests into detailed prompts, in English.
Include: subject, style, lighting, framing, level of detail.
Never invent a brand, a real person or a logo. Reply with the prompt only."""
def expand(user_request: str) -> str:
r = client.chat.completions.create(
model="gpub-fast", # the cheapest piece of the flow
messages=[{"role": "system", "content": INSTRUCTION},
{"role": "user", "content": user_request}],
max_tokens=200,
)
return r.choices[0].message.content.strip()
def generate(prompt: str, comfy="http://YOUR-IP:8188"):
flow = json.load(open("flow_txt2img.json")) # exported from ComfyUI
flow["6"]["inputs"]["text"] = prompt # positive prompt node
flow["3"]["inputs"]["steps"] = 8 # distilled model
flow["3"]["inputs"]["cfg"] = 0.0 # distilled: guidance zero
r = requests.post(f"{comfy}/prompt", json={"prompt": flow}, timeout=30)
return r.json()["prompt_id"] # track it via /history
# in your queue worker:
prompt = expand("a cat wearing glasses")
job = generate(prompt)
Generating is half of it — editing is the other half
In real assistant usage, most requests are not "create from scratch" but change this image:
- Remove or replace the background — rembg handles it, runs on a minimal card and is nearly instant. It is by far the most common request in commercial use.
- Fill a region (remove an object, change clothing, clean a photo) — the editing models of the same families do this, inside ComfyUI.
- Upscale — generating at 1024 and upscaling afterwards costs a fraction of generating at 2048 directly, with practically identical results on screen.
- Keep a visual identity — a light fine-tune trained on 20 photos of your products keeps your style across every output.
Cost per image
| Configuration | Time per image | Compute cost | Including the rewrite |
|---|---|---|---|
| Large model, 40 steps, 24 GB card | ~11 s | R$ 0.0085 | R$ 0.0088 |
| Large model, 20 steps | ~5.5 s | R$ 0.0042 | R$ 0.0045 |
| Distilled model, 8 steps | ~2.2 s | R$ 0.0017 | R$ 0.0020 |
| Distilled model, batch of 4 | ~0.9 s per image | R$ 0.0007 | R$ 0.0010 |
August 2026 prices, single GPU, no scheduled interruption. Prices are in Brazilian reais (BRL), the billing currency. The catalogue moves — check the live one before committing to a number.
Under one cent per image, even in the worst row of that table. What decides your bill is not the price of an image — it is how long the machine sat on, generating nothing. If you take one lesson from this part, take that one.
Moderation: the piece you cannot skip
An open generator on the internet will receive requests you do not want to serve. The responsible minimum, and it is cheap:
- Filter the input. One call to the economy model classifying the request before generating costs R$ 0.0002 and blocks most of the problem.
- Refuse real people explicitly. Generating an identifiable person without consent is a legal problem, not a technical one. Instruct the rewrite to refuse, and log the refusal.
- Log who asked for what. Keep the original prompt, the expanded prompt and the user. It is what saves you in a dispute.
- Check the licence. "Open" does not mean "cleared for commercial use". Verify the licence of the exact variant before billing on top of it.
Images are bursty; the brain is constant
The image card starts when there is a queue and stops when it drains. Prompt rewriting, moderation and the conversation around it are per-token calls, with no machine to administer.
See the token API →Next: the camera — video, the most expensive piece of all.
Keep reading: an image generation API · ComfyUI advanced workflows · part 6: video