From 1a60dfde4b8510fd7ddab0ecafa1357caa0eabea Mon Sep 17 00:00:00 2001 From: GenorTG Date: Thu, 12 Nov 2026 13:16:01 +0100 Subject: [PATCH] PromptForge 1.29.8 --- .comfyignore | 4 + .gitignore | 75 + H3_QUALITY_NOTES.md | 49 + LICENSE | 21 + README.md | 366 ++++ __init__.py | 2965 ++++++++++++++++++++++++++++++ autotune.py | 80 + banner.png | Bin 0 -> 23748 bytes catalog/models.json | 460 +++++ empty_latent.py | 144 ++ families.py | 184 ++ frame_interpolation.py | 114 ++ gguf_native/LICENSE-ComfyUI-GGUF | 201 ++ gguf_native/__init__.py | 168 ++ gguf_native/dequant.py | 301 +++ gguf_native/loader.py | 506 +++++ gguf_native/ops.py | 281 +++ gguf_native/tools/__init__.py | 0 gguf_native/tools/convert.py | 365 ++++ h3_actions.py | 329 ++++ h3_generate.py | 742 ++++++++ h3_ideas.py | 98 + h3_settings.py | 411 +++++ h3_upscaler.py | 47 + icon.png | Bin 0 -> 6430 bytes image_actions.py | 311 ++++ image_actions_node.py | 44 + image_library.py | 435 +++++ load_audio.py | 42 + load_image.py | 143 ++ load_video.py | 55 + lora_loader.py | 357 ++++ minimax_decode.py | 191 ++ moss_nodes.py | 317 ++++ presets/promptforge_presets.json | 78 + preview_decoder.py | 78 + preview_override.py | 201 ++ pyproject.toml | 30 + quantize_model.py | 240 +++ sampler.py | 206 +++ sampler_defaults.py | 82 + unified_loader.py | 207 +++ video_save.py | 276 +++ web/promptforge.js | 97 + web/promptforge_action.js | 46 + web/promptforge_h3.js | 668 +++++++ web/promptforge_image.js | 170 ++ web/promptforge_latent.js | 60 + web/promptforge_library.js | 250 +++ web/promptforge_loader.js | 97 + web/promptforge_lora.js | 342 ++++ web/promptforge_preview.js | 61 + web/promptforge_sampler.js | 84 + web/promptforge_upload.js | 38 + web/promptforge_video.js | 53 + 55 files changed, 13170 insertions(+) create mode 100644 .comfyignore create mode 100644 .gitignore create mode 100644 H3_QUALITY_NOTES.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 __init__.py create mode 100644 autotune.py create mode 100644 banner.png create mode 100644 catalog/models.json create mode 100644 empty_latent.py create mode 100644 families.py create mode 100644 frame_interpolation.py create mode 100644 gguf_native/LICENSE-ComfyUI-GGUF create mode 100644 gguf_native/__init__.py create mode 100644 gguf_native/dequant.py create mode 100644 gguf_native/loader.py create mode 100644 gguf_native/ops.py create mode 100644 gguf_native/tools/__init__.py create mode 100644 gguf_native/tools/convert.py create mode 100644 h3_actions.py create mode 100644 h3_generate.py create mode 100644 h3_ideas.py create mode 100644 h3_settings.py create mode 100644 h3_upscaler.py create mode 100644 icon.png create mode 100644 image_actions.py create mode 100644 image_actions_node.py create mode 100644 image_library.py create mode 100644 load_audio.py create mode 100644 load_image.py create mode 100644 load_video.py create mode 100644 lora_loader.py create mode 100644 minimax_decode.py create mode 100644 moss_nodes.py create mode 100644 presets/promptforge_presets.json create mode 100644 preview_decoder.py create mode 100644 preview_override.py create mode 100644 pyproject.toml create mode 100644 quantize_model.py create mode 100644 sampler.py create mode 100644 sampler_defaults.py create mode 100644 unified_loader.py create mode 100644 video_save.py create mode 100644 web/promptforge.js create mode 100644 web/promptforge_action.js create mode 100644 web/promptforge_h3.js create mode 100644 web/promptforge_image.js create mode 100644 web/promptforge_latent.js create mode 100644 web/promptforge_library.js create mode 100644 web/promptforge_loader.js create mode 100644 web/promptforge_lora.js create mode 100644 web/promptforge_preview.js create mode 100644 web/promptforge_sampler.js create mode 100644 web/promptforge_upload.js create mode 100644 web/promptforge_video.js diff --git a/.comfyignore b/.comfyignore new file mode 100644 index 0000000..19db262 --- /dev/null +++ b/.comfyignore @@ -0,0 +1,4 @@ +.env +node.zip +__pycache__/ +workflows/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7ba97b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,75 @@ +# ComfyUI PromptForge Git Ignore File + +__pycache__/ +*.py[cod] +*.pyc +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# Virtual environments +venv/ +env/ +ENV/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Logs +*.log +logs/ + +# ComfyUI specific +models/ +input/ +output/ +temp/ +*.jpg +*.jpeg +*.gif +*.webp +*.mp4 +*.avi +*.mov +*.webm + +# Local caches +.cache/ +.huggingface/ +prompt_cache.json + +# Garage-synced preset mirror +presets_remote/ +autotune.json +node.zip +.env + +workflows/ diff --git a/H3_QUALITY_NOTES.md b/H3_QUALITY_NOTES.md new file mode 100644 index 0000000..0e95469 --- /dev/null +++ b/H3_QUALITY_NOTES.md @@ -0,0 +1,49 @@ +# MiniMax H3 quality and memory notes + +These settings are what the working two-pass workflow uses. They were isolated by A/B runs on the same +checkpoint, seed and prompt. + +## Keep + +- First pass: `euler` / `beta57`, 8 steps, cfg 1, shifts `0 / 0`. +- Second pass: fp32 `minimax_h3_latent_upscaler_3d_conv_v1_fp32.pth`, 1 MP, 3 steps, start sigma 0.9035, `er_sde`. +- Performance: `comfy kitchen attention`, `ffn_chunks` 2, sparse attention off. +- Save: NVENC `slow`, quality, CQ 19, 8-bit, 48 fps. +- Loader: `quality`, explicit `minimax` clip type. +- LoRAs: free to toggle. The reference stack is Realism 1.5, Age -0.5, Flat Chested 0.75, + Ref2VA Motion 0.75, GalaxyAce 1.0, Moawxx audio 1.0, SexGod 1.0. + +## What makes it worse + +| Setting | Effect | +|---|---| +| `er_sde` + `simple` | Coloured chroma speckle over skin and flat surfaces | +| fp16 latent upscaler | Washed contrast, low skin texture, plastic look | +| sparse attention on | Smeared fine detail | +| `ffn_chunks` 1 | Second-stage out-of-memory on 16 GB | +| NVENC fastest/fast/balanced | Bands on gradients and flat walls | +| shift 12/3 at 8 steps | Harsher, less stable result | + +## Memory + +More enabled LoRAs use more VRAM. If the second stage OOMs, raise `ffn_chunks` to 3 or 4. Do not turn on +sparse attention as the first fix; it costs detail. The node also unloads everything between the first and +second pass and decodes the first pass only after both sampling passes. + +## Headless + +Use `PromptForge_H3_AllInOne_Modes_v5.api.json`. It is already in `/prompt` format. The normal workflow +file stores the image picker as an extra leading widget on Load Image; order-based converters that ignore +that read the filename as the description and send no picture. + +## Text writer sampling (Qwen3-VL) + +Use the model card values: temperature 0.7, top_p 0.8, top_k 20, repetition_penalty 1.0, presence_penalty 1.0-1.5. +Thinking mode would be 0.6 / 0.95 / 20 / 1.0, but the writer runs with thinking off. + +Bad: temperature near 0 or greedy, no_repeat_ngram_size 4 forced on, repetition penalty above 1.15, top_p above +0.95 for long structured prompts, and stopping the sampler on the first repeated phrase. Those cause the +"starts fine, then rambles and never ends" failure. + +Presence 1.5 is the Qwen serving value, but HF counts the whole prompt as "seen", so on very long prompts it +can be too strong. 1.0 is the default here; drop to 0.5 or 0 if the prose starts sounding forced. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d0290dc --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 GenorTG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..81105a6 --- /dev/null +++ b/README.md @@ -0,0 +1,366 @@ +# ComfyUI PromptForge + +A full model workflow suite, not just a prompt enhancer: load the model, encode the prompt and references, +generate, upscale and save. It covers **Krea 2**, **MOSS Image**, **Qwen Image**, **Anima**, **MiniMax H3** and +other families, plus shared loader, sampler, latent, action, prompt and save tooling. + +- **Loading** — one loader for checkpoints, diffusion models and GGUF, with quant, context and GPU-layer planning; LoRA loader, and image / video / audio loaders with a picker and library. +- **Encoding** — family-aware text encoding, edit encoders for Krea and MOSS, VAE encode, and reference conditioning. +- **Prompting** — the Prompt Enhancer with per-family presets, the Action libraries, and the H3 Idea / Parts nodes. +- **Generating** — family-aware sampler with saved presets, empty latent with aspect and size presets, preview override, frame interpolation. +- **Saving** — image and video savers with codec control, plus batch and upscale helpers. + +The sections below cover the three main families and their workflows, then the shared node reference. + +## Krea 2 + +Required extras: `comfyui-krea2edit`, `krea2-nag` (only for the transfer workflow) and the Krea 2 models you +own. The LoRA node starts with the identity LoRA selected in the edit workflow. + +### Workflows + +- `KREA2_T2I_v2.json` — text to image at 1.5 MP. Write in `prompt_text`, pick an action or switch `use_action` + off, then queue. +- `KREA2_EDIT_v8 AAAA.json` — identity edit from `LoadImage`; the person comes from the picture and is cloned + into the scene you write. The sampler and the patched target use an empty latent; only `source_latent` and + `source_image` get the encoded picture. +- `KREA TRANSFER.json` — face transfer between a source and a target picture. + +### Face mask and reference position + +Edit ships a face/hair/neck mask into the patch `ref_boost_mask` with `ref_boost` 3, so identity is pulled from the face instead of the whole picture, and `ref_position = beside` lets the pose move away from the source layout. Both servers run ComfyUI with `--use-pytorch-cross-attention`, needed for masked reference attention on RTX 50. + +### Settings + +Use the `Krea` presets in the sampler list: FinePorn 8-10 steps, cfg 1, `euler`/`simple`; turbo checkpoints +8 steps. Krea edit keeps identity best at 8-10 steps because the identity LoRA does the work, not more steps. + +### Negative prompts at cfg 1 + +The NAG switch is `use_nag` on the model patch: `PromptForge Krea NAG` (text-to-image) and +`PromptForge Krea Edit Model Patch` (edit and transfer). Off passes the model through; on applies normalized +attention guidance from the negative prompt at cfg 1, without changing cfg. The encoders always encode the +negative, which costs nothing when NAG is off. + +## MOSS Image + +Required extras: ComfyUI with MOSS support, `ComfyUI-MOSS-Toolkit`, `moss_image_edit_lora_rank_64_bf16.safetensors` +for edit, and the MOSS models. Edit always keeps one reference image, `Moss-Image-Edit` and `denoise 1`: the image is +VAE-encoded into reference latents at t = 0, not used as an img2img latent, so the sampler redraws the same frame. + +### Workflows + +- `MOSS_T2I_v2.json` — text to image at 1.5 MP. +- `MOSS_EDIT_v4.json` — reference edit; pick the picture in `LoadImage`, write the change. + +### Settings and DMD + +Use the `MOSS` presets, matched to the model. Editing runs at 1 MP with the target size taken from the +scaled source image (Empty Latent `res_mode = custom`, WIDTH/HEIGHT from Image Scale), 30 steps, cfg 4, +`euler`/`normal`, `image_strength` 1.0. Below cfg 4 the negative branch stops holding and accessories appear. +Use the `MOSS Image Edit` prompt preset (short "Change only X to Y. Keep the character, face, hair, pose, +background and composition unchanged."). + +MOSS alone holds the face only on small attribute edits; a new pose or scene redraws it. The edit workflow +ships a bypassed optional face transplant (`Forbidden Vision` Face Edit Prep / Face Edit Merge) for when the +face must match: Ctrl+B on **Face Transplant** turns it on. It scores 0.91-0.95 by face embedding, but reads +as a pasted face; left off, the scene looks cleaner and the face drifts. Crop the source at the chin +(`ImageCrop`) when it is on, so the collar and background do not come along. The DMD LoRAs (`lodestones-8-steps`, `sft-4-steps`) run at 8 steps, cfg 1, +`er_sde`/`simple`; on PrimeLust use 12 steps and cfg 1.5. A denoise below 0.8 tiles the edit result. + +## MiniMax H3 + +Required extras: the H3 model, its VAE and an audio VAE. The `PromptForge_H3_AllInOne_Modes_v6.json` workflow +covers all modes; switch them in the Modes node. Everything changed often (mode, action, idea, writer, format, sampling, LoRA, generate) sits in one row next to each other. The v5 file is left untouched. + +### Action node and roles + +85 acts, each with an explicit who-is-where description, the orifice for sex acts (vagina or anus, never swapped), and a 9:16 or 16:9 frame. The camera list is filtered per act and puts POV of one named person first; a POV line is enforced as that person's eyes for the whole clip, their face never shown, the other person always in frame. Every role has +its own picture picker (Woman, Man, Partner): choose the reference slot, the first frame, none and only a +description, or `disabled`. Subject 3 defaults to `disabled`; pictures left unassigned become anatomy/detail +references, not extra people. See the [H3 Action reference](#promptforge-h3-action-adult-presets). + +### Writer and API + +The writer settings (template, style, sampling, retries) are described under the +[Prompt Enhancer](#promptforge-enhancer-promptforge_promptenhancer). For headless use, +`PromptForge_H3_AllInOne_Modes_v5.api.json` is already in `/prompt` format; the normal workflow stores the +image picker as an extra leading widget, which order-based converters must skip. + +## Shared node reference + +### PromptForge Model (`PROMPTFORGE_Model`) + +Owns model choice and runtime configuration; outputs a `MODEL` bundle and a `REPORT` string. + +- **Model picker**: one list split into two sections — **local models (on disk, ready)** first, then **not downloaded (fetched on first use)**. Every entry is tagged: `[LOCAL Q4/Q8]` names the GGUF quant files present, `[VISION]`/`[TEXT]` says whether a matching mmproj exists (`[VISION dl]` = catalog mmproj not downloaded), `[LOCAL]` marks a cached or scanned model, `[DOWNLOAD]` marks a catalog model that is not on this machine yet (the Model node prints that warning before loading). The console prints a one-line count of local vs. downloadable models at startup, and the Config Finder report ends with the not-downloaded count. If a requested quant is not local but another quant is, the node uses the local one and says so instead of downloading. The catalog covers Qwen3, Qwen3.5, Qwen3.6, Qwen3.8, Qwen2.5, Qwen3-VL, Qwen2.5-VL, Gemma 3/4, Llama 3, Mistral/Ministral and Phi-4 heretic/abliterated models. Local models found in the registered `text_encoders` folders (including `extra_model_paths.yaml`) and the `LLM`, `llm`, `gguf` … subfolders of `models/` are listed by their path relative to `models/`, so a workflow saved on one machine resolves on another with the same layout. Single-file encoders without token embeddings (CLIP-L/G, T5, LTX projections) are hidden because they cannot generate text. GGUF generation streams tokens into ComfyUI’s progress bar. `local_model_path` and `mmproj_path` cover anything outside the lists. The `clip` input lives here and is passed to the enhancer in the model bundle. The default is the first local GGUF when llama-cpp-python is installed. +- **Automatic runtime**: the node reads total VRAM and the selected model, then picks the best **local** GGUF quant that fits, the largest context (16k first), KV precision, GPU layers, batch sizes, windowed SWA and flash attention. For safetensors it picks bf16/fp16, q8 or q4; local HF directories get their size from the safetensors files. At run time the free VRAM is checked again: bf16/q8 drops to q4 when it does not fit, and a GGUF that fails to load retries with as many GPU layers as actually fit (the rest run on CPU). The only remaining override is `context_size` (0 = auto). +- **Quant fallback**: unsupported combinations warn and use a working option — q5/q6 on safetensors load as q8, q8/q4 on a single-file encoder load in fp16, q8 switches to q4 when free VRAM is insufficient, CPU-offloaded layers are allowed (slower) instead of raising, a missing GGUF quant falls through the available files, and an incompatible KV/flash/SWA choice is retried with the safe value. The report re-checks local availability at run time, so stale `[AVAILABLE]` widget labels still show `[LOCAL]`. + + +### PromptForge Action (`PROMPTFORGE_ImageAction`) + +A pose library for any image model: 90 named actions (portraits, SFW solo and couple poses, nude and +explicit solo sets, sex positions, oral, hands and explicit detail), 29 places, 27 cameras (framing, +angles, POV of either person, over the shoulder, handheld, locked off), 12 light +setups, 15 outfits and 9 styles. Aspect ratio stays with the Empty Latent / resolution node. Category filters the action list; every action states the exact body +arrangement, hands, legs, face and camera so there is no ambiguity. `source` switches between keeping +the person in the connected image (image-to-image) and inventing them from `subject_1` / `subject_2` +text (text-to-image). Notes and overrides are appended last. The enhancer has `use_action`; turn it off to ignore the action for a fully custom prompt without disconnecting the node. Output connects to the enhancer's `action` input; while `use_action` is on the brief replaces the enhancer prompt, and the `instructions` field carries custom additions. + +### PromptForge Enhancer (`PROMPTFORGE_PromptEnhancer`) + +Takes the `MODEL` bundle and writes the prompt. Only generation inputs live here. + +- **Request fidelity**: every preset treats the user's text as the authority on subject, acts, intensity and tone. Hardcore, explicit or intense requests are written directly and specifically, without sanitizing, softening, euphemizing or fading to black. +- **Prompt input**: free-form text box — loose natural language, random ideas, keyword piles, detailed descriptions; the model always expands to a proper prompt for the target mode/model. With `use_action` on, this text is ignored and the Action brief drives the prompt; custom additions go in the Action node's `instructions` field. +- **Modes**: `text_only` (ignore media) or `inputs` (use every connected image from `image` / `image2` / `image3` plus frames sampled from `video` via `frame_count`). The prompt is told exactly which inputs arrived: bypassed or missing sockets are never mentioned, and the model is told not to invent extra images, references, video or frames. +- **Preset**: `auto` or any bundled preset (Krea 2 T2I / Edit, MOSS Image T2I / Edit, Qwen Image T2I / Edit, MiniMax H3, Anima, ACE-Step, generic styles…). With a Loader PIPE connected and the preset on `auto`, the family's preset is used, and its edit preset when an image is connected. +- **MiniMax inputs**: the MiniMax H3 presets (T2VA, I2VA, L2VA, FL2VA, Ref2VA) get an authoritative list of what is connected. Labels follow the H3 encoder: ``, ``, `` for the connected images in order with gaps closed up (only `image2` connected makes it ``), and `