Qwen 2.1 Prompt Enhancer Rewrite
It thinks out loud, then hands you JSON
- qwen_pe_model
- image_1
- image_2
- image_3
- image_4
- image_5
- image_6
- image_7
- image_8
- image_9
- positive_prompt
- wh_ratio
- ratio_follow
- thinking
Type A dog wearing sunglasses in a cyberpunk city, hit queue, and a while later a small novel comes out the other end. That's the deal with this node: it's a reasoning model, so it writes a long <think> block before the answer, and if you don't know the JSON is buried in there you'll read the scratch work and conclude it's broken.
What it is
The Rewrite node is the working half of the pack. It takes the QWEN_PE_MODEL handle from the Loader and runs a fine-tuned Qwen3.5-VL 9B prompt rewriter: on t2i it expands a short request in any language into a detailed English prompt plus a recommended aspect ratio, and on edit it turns a vague edit instruction plus reference images into something precise enough to feed an image editor. Uncensored, offline and free per call - the usual reasons to keep this local instead of calling an API.
How it works
It builds a chat message: your system prompt, then the images (edit only), then your text. apply_chat_template runs with thinking enabled, so generation opens with a reasoning block that ends at </think>, and everything after that is a JSON object:
{"rewritten_prompt": "<long detailed English prompt>", "wh_ratio": "16:9"}
The node splits the thinking off, walks the answer for the last balanced {...} span, tries json.loads and falls back to json_repair if the model fumbled the syntax. Then it reads rewritten_prompt, wh_ratio and ratio_follow. If nothing parses, you don't get an error - you get the raw answer text as positive_prompt with the ratio fields blank. That's the single most important thing to know here, because raw chat prose in your conditioning is worse than no enhancer at all.
The inputs that matter
qwen_pe_model is the Loader output. task is t2i or edit - edit is what activates the image sockets, and a t2i run ignores images you connected. prompt is your short idea, multiline, in whatever language.
system_prompt_file is where this node lives or dies, and it's the one thing the README doesn't spell out. It's a dropdown of *.txt files in ComfyUI/models/LLM/prompts/. The built-in default is a five-word stub (You are a prompt enhancer...), and the bundled example workflows ask for system_prompt_t2i.txt and system_prompt_edit.txt - files that don't ship with the pack. The real template ships with the model, as system_prompt.txt sitting next to config.json. Copy it in, rename it to match, then restart ComfyUI so the dropdown re-scans:
mkdir -p ComfyUI/models/LLM/prompts
cp ComfyUI/models/LLM/Qwen-Image-2.1-PE-T2I/system_prompt.txt \
ComfyUI/models/LLM/prompts/system_prompt_t2i.txt
Same for the I2I folder. The abliterated repo ships no template at all, so borrow the official I2I one.
The sampling knobs are the model card's own defaults: temperature 1.0, top_p 0.95, top_k 20, seed 42. Temperature 0 goes greedy and deterministic. presence_penalty defaults to 1.5, but the author's example workflows run it at 0.0 - it's implemented as a logits processor that subtracts the penalty from every token already generated, which on a 16k-token reasoning output is a lot of suppression. Start at 0.0, raise it only if you see loops. max_new_tokens defaults to 16256 for a reason: the thinking block eats most of it, and cutting it down gives you truncated reasoning and no JSON.
The images
image_1 through image_9 are optional and edit-only, and the UI grows them as you connect - connect image_1 and a second socket appears, up to nine. Batches get split frame by frame, and anything over ~1 megapixel is downscaled before the model sees it, so 4K references buy you nothing. The model refers to them positionally as <image1>, <image2>, so phrase it literally: Place <image1>'s subject into <image2>'s scene.
What the outputs are for
positive_prompt goes to your text encoder or prompt box. wh_ratio is not decoration - Qwen's own card maps those strings to render sizes (1:1 → 2048×2048, 16:9 → 2752×1536, 3:2 → 2528×1696, 9:16 → 1536×2752) - so wire it into whatever sets your resolution, or read it off a Show Text node and set your latent size to match. ratio_follow is edit-only and names which reference image the result should follow in aspect, e.g. <image1>. thinking is the debug channel: when positive_prompt comes back as rambling prose, wire it to Show Text and read what the model actually did.
Troubleshooting
Your output is chatty text with a preamble. The system prompt isn't the official template, json_repair couldn't save the parse, and you're now piping the model's conversational habits into your conditioning. Fix the prompts file first.
The dropdown only offers default. No .txt in ComfyUI/models/LLM/prompts/, or you added one after startup - restart so the node definitions re-scan.
It looks frozen. The console prints Qwen 2.1 Prompt Enhancer is Thinking... and the progress bar advances one tick per generated token against a 16k-ish maximum, so it crawls and then finishes at once. Normal.
The prompt keeps growing detail you never asked for - extra characters, extra clothing, extra narrative. Subject drift is the built-in failure mode of every enhancer: it earns its name by adding detail, including detail that wasn't your idea. Lower the temperature, tighten the system prompt, and treat the output as a suggestion you're allowed to edit.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| qwen_pe_model | QWEN_PE_MODEL | Connect the loaded model from Qwen2.1 PE Loader. | |
| task | COMBO | t2i | Task type: 't2i' for text-to-image expansion, 'edit' for image-based rewriting, 'caption' for reverse engineering image to prompt. |
| system_prompt_file | COMBO | System prompt template file located in ComfyUI/models/LLM/prompts/. | |
| prompt | STRING | Enter the short prompt or instruction you want to enhance. (For 'caption', this can be left empty or set to 'Reverse engineer this image'.) | |
| temperature | FLOAT | 1.000–2 | Controls randomness. Lower values make output more deterministic, higher values increase creativity. |
| top_p | FLOAT | 0.950–1 | Nucleus sampling threshold. Restricts the vocabulary selection range. |
| top_k | INT | 200–100 | Limits vocabulary to the top K most likely tokens. |
| presence_penalty | FLOAT | 1.500–2 | Penalizes repeated words. Higher values prevent the model from getting stuck in loops. |
| max_new_tokens | INT | 162561–32768 | Max generation length. Keep this large because the model outputs a long <think> reasoning process. |
| seed | INT | 420–18446744073709550000 | Random seed. Fixed seeds produce identical deterministic results. |
| image_1opt | IMAGE | — | |
| image_2opt | IMAGE | — | |
| image_3opt | IMAGE | — | |
| image_4opt | IMAGE | — | |
| image_5opt | IMAGE | — | |
| image_6opt | IMAGE | — | |
| image_7opt | IMAGE | — | |
| image_8opt | IMAGE | — | |
| image_9opt | IMAGE | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| positive_prompt | STRING | — |
| wh_ratio | STRING | — |
| ratio_follow | STRING | — |
| thinking | STRING | — |