Nodes/crypswolfy69 nodes/✦ ALCHEMIST // DATASET CAPTIONER
ComfyUI Node

✦ ALCHEMIST // DATASET CAPTIONER

Caption 500 Images Overnight, and Pay for Every Single One

By babydjac·Created 25 days ago·Updated 8 days ago· 1
✦ ALCHEMIST // DATASET CAPTIONER
    • report
    • captioned
    • skipped
    • failed
    ◄actionidle►
    ◄folder/workspace/Pawg TS►
    ◄providerxAI / Grok►
    ◄modelgrok-4.20-non-reasoning►
    ◄reasoningminimal►
    ◄lora_kindbody concept►
    ◄trigger_word►
    ◄dry_runtrue►
    ◄limit0►
    ◄overwritefalse►
    ◄nsfwtrue►
    ◄caption_words45►
    ◄omit_terms►
    ◄extra_direction►
    ◄api_key►
    ◄temperature0.70►
    ◄custom_base_url►

    Captioning a LoRA dataset by hand is the difference between a LoRA that works and a LoRA that quietly baked your kitchen into a character. It's also 500 files' worth of typing. DATASET CAPTIONER is the node that says "fine, I'll write them" - it walks a folder, captions every image with the same Krea 2 training recipe the LORA CAPTION node uses, and writes a .txt sidecar next to each one.

    This is the node in the pack that spends real money, so read the dry-run section before you point it at a folder.

    How it works

    It runs server-side, on the machine ComfyUI is on. You give it a folder; it lists the images in that folder, sorts them by filename, and works out what's left to do: by default, any image that doesn't already have a same-stem .txt beside it. overwrite flips that to "redo everything", and limit caps how many it touches this run.

    For each image it reads the file, sends it to the vision LLM along with the LoRA-caption system prompt - where lora_kind decides what the caption deliberately stays silent about, so the thing you're training binds to trigger_word instead of staying promptable - and writes the returned text to <image>.txt. The caption is collapsed to a single line, because a trainer reads a sidecar as one string.

    Outputs are report, captioned, skipped, failed. The report is the useful one: a header with the folder, how many images there are, how many need captioning, the provider and model, and whether this was a dry run - then one line per image with its word count and the caption, or a FAIL/REFUSED line saying what went wrong.

    reasoning defaults to minimal here, and the tooltip says why: you're paying per image. That's a speed knob on the interactive nodes; on a 400-image folder it's a line on the bill.

    The dry run is not optional (for your wallet)

    dry_run is on by default, and it does exactly what it says: it runs the whole thing, prints the report, writes nothing. The intended sequence is:

    1. limit = 3, dry_run on. Read three captions. This costs three calls.
    2. Satisfied? dry_run off, overwrite off, limit = 0. It fills in the missing sidecars and skips everything already captioned.
    3. Hated it? Fix lora_kind, omit_terms or extra_direction and re-run. With overwrite off, nothing already written gets touched, so gaps only ever get filled.

    That third point is where the design saves you money: a run that dies at image 280 leaves 279 finished sidecars, and the next run skips them.

    Inputs worth knowing

    folder must be a path the ComfyUI process can see - the default is a /workspace/... path, which tells you what kind of box this was built on. Absolute paths, and mind the escaping on Windows.

    Beyond provider, model, lora_kind, trigger_word and nsfw, you get caption_words (20–70, default 45), omit_terms for things that must never appear in a caption, extra_direction for tone, and the usual api_key / custom_base_url / temperature. The action widget is the same browser-side helper the other Alchemist nodes have - vaulting a key, listing models, a no-queue preview - and the captioning itself happens when you queue the graph.

    Install

    ComfyUI Manager, search crypswolf69. Or:

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

    Restart, hard-refresh, paste a key into api_key and run the action widget to vault it - or set XAI_API_KEY and skip the vault. aiohttp is the entire dependency list, and there's nothing to download; the "model" is whatever LLM you point it at.

    Where people get burned

    It does not recurse. One folder, flat, no subdirectories. If your dataset is train/charA, train/charB, you get two runs, one per folder.

    Only certain extensions count - png, jpg, jpeg, webp, bmp. A stray .tiff is invisible to it, which is better than crashing but worth knowing when the count looks short.

    "No images in folder" / "Not a folder". Both are hard errors, and both are almost always the path being wrong from the server's point of view rather than yours - in a Docker container or on a RunPod volume, your desktop path means nothing to ComfyUI.

    Provider choice bites here more than anywhere. OpenAI, Anthropic and Google refuse explicit content, and refusals are counted as failed - so a stack of them at the end of the report is a provider problem, not a bad dataset. xAI/Grok is the default and the loosest of the hosted options; Groq is very fast and the author flags it for bulk captioning. Free and unfiltered means a local Ollama or vLLM server: slower and less articulate per caption, but 500 images at zero marginal cost, and a decent first pass to edit by hand.

    The honesty bit. Any VLM still mixes up who's wearing what when there are two people in frame, and a wrong caption is a wrong training signal. Auto-caption for volume; hand-audit the set that has to be right.

    Categoryprompting/alchemist

    Inputs (17)

    NameTypeDefaultDescription
    actionCOMBOidleRuns in the browser and resets to idle. Never queues a generation.
    folderSTRING/workspace/Pawg TSFolder of images. Captions land next to them as .txt.
    providerCOMBOxAI / GrokWhich LLM answers. Use FETCH MODELS after switching.
    modelCOMBOgrok-4.20-non-reasoningModel id. FETCH MODELS repopulates this from the live API.
    reasoningCOMBOminimalPaid per image here, so keep it low.
    lora_kindCOMBObody concept4 options: character, body concept, style, clothing or object
    trigger_wordSTRING—
    dry_runBOOLEANtrue—
    limitINT00–50000 = no cap. Set 3 for a cheap sanity check first.
    overwriteBOOLEANfalse—
    nsfwBOOLEANtrueNSFW allows all explicit adult content. SFW keeps it non-explicit.
    caption_wordsoptINT4520–70—
    omit_termsoptSTRING—
    extra_directionoptSTRING—
    api_keyoptSTRING—
    temperatureoptFLOAT0.700–2—
    custom_base_urloptSTRING—

    Outputs (4)

    NameTypeDescription
    reportSTRING—
    captionedINT—
    skippedINT—
    failedINT—