Nodes/ComfyUI-PromptEngine/Step 2: Clustering Analysis
ComfyUI Node

Step 2: Clustering Analysis

Group your prompt phrases by meaning, not spelling

By aiimagestudio·Created 6 months ago·Updated 5 months ago· 4
Step 2: Clustering Analysis
    • summary
    • cluster_dir
    input_jsondata/02_merged_normal_20260211_001-026.json
    enable_noise_reclustertrue
    primary_min_cluster_size6
    primary_min_samples3
    noise_min_cluster_size4
    noise_min_samples2

    Step 2: Clustering Analysis is where your prompt data stops being a heap of near-duplicate phrases and becomes organized groups. It takes the JSON from Step 1, and for every dimension it embeds the extracted phrases, reduces them, and clusters them with HDBSCAN so "soft film grain texture", "film-like texture with subtle grain", and "natural film grain" all end up in one pile. Then Step 3 turns each pile into a dictionary entry.

    If you only use the prompt composition nodes, you never touch this one. It exists purely for people building their own dictionaries - and it's the one node in the pack with real hardware and download requirements, so read this before you run it.

    How it works

    The pipeline is the classic embedding-clustering stack, straight from the source (tools/step2_clustering.py):

    1. Each dimension's extracted phrases are deduplicated.
    2. Every unique phrase is embedded with BAAI/bge-small-en-v1.5, a small sentence-transformer. On first run it's downloaded from Hugging Face into your ComfyUI models folder if it isn't already there - this is the step that needs network access.
    3. Embeddings are reduced with UMAP (cosine metric), then clustered with HDBSCAN (leaf selection method).
    4. Whatever HDBSCAN marks as noise gets a second, looser clustering pass if there's enough of it (≥10 noise items) - that's the "noise recluster" toggle.
    5. Results are written per dimension to output/step2_clusters/<dim>/<dim>_clusters.json.

    Everything runs on your machine - CPU works but it's slow; the code prefers CUDA automatically if torch sees a GPU.

    The inputs that matter

    • input_json - the path to a Step 1 JSON file. Note the default in the schema points at a bundled data/02_merged_normal_*.json from the author's own workflow, so change it to your actual Step 1 output.
    • enable_noise_recluster - leave it on. Without it, all the oddball phrases HDBSCAN couldn't fit sit in a "noise" bucket and become useless.
    • primary_min_cluster_size / primary_min_samples - how big and how dense a cluster has to be to count. Defaults are 6 and 3. If your output is nothing but noise, raise... actually lower min_cluster_size to let smaller groups form; if everything collapses into one blob, raise it.
    • noise_min_cluster_size / noise_min_samples - the looser settings for that second pass (defaults 4 and 2).

    Outputs are summary (a markdown table with per-dimension cluster counts, noise rates, and timings) and cluster_dir, the folder Step 3 reads.

    Install and the dependency warning

    cd ComfyUI/custom_nodes
    git clone https://github.com/jinxishe/ComfyUI-PromptEngine
    pip install -r requirements.txt
    

    That requirements.txt is where it gets real. The composition nodes only need openai and tqdm, but Step 2 additionally pulls in sentence-transformers, umap-learn, hdbscan, numpy, and torch. If you already run ComfyUI you have torch; the rest are small. The model download on first run is a few hundred MB.

    Gotchas

    • First run needs internet to fetch the embedding model; after that it's loaded from local_files_only.
    • Small datasets behave oddly: under a size threshold the node gives up and dumps everything into a single cluster rather than forcing splits. If you're clustering a handful of prompts, expect one sad bucket per dimension.
    • It's a background job, not a live thing. Large corpora mean minutes of UMAP/HDBSCAN churn with a progress bar, so run it once per batch rather than fiddling live.
    CategoryPromptEngine/Tools

    Inputs (6)

    NameTypeDefaultDescription
    input_jsonSTRINGdata/02_merged_normal_20260211_001-026.json
    enable_noise_reclusteroptBOOLEANtrue
    primary_min_cluster_sizeoptINT62–20
    primary_min_samplesoptINT31–20
    noise_min_cluster_sizeoptINT42–10
    noise_min_samplesoptINT21–10

    Outputs (2)

    NameTypeDescription
    summarySTRING
    cluster_dirSTRING