Batch_API_caption☀
Caption a whole dataset folder, in parallel, while you sleep
- log
- save_path
If you've ever labeled a dataset by hand, you know why this node exists. Batch_API_caption takes a folder of images, sends each one to a multimodal API in parallel, and writes a .txt caption next to it - same basename, one file per image. It's the batch version of API_caption, and it's aimed squarely at the people whose bottleneck is "a thousand images, no captions."
For LoRA training specifically, captions are the highest-leverage part of dataset prep for the current LLM-encoder models: describe what should stay changeable, leave what should stay fixed undescribed. A tool that does this at folder scale is the difference between a weekend project and a real training run.
How it works
Give it an input directory, and it lists every .jpg/.jpeg/.png/.bmp/.webp, then fans them out across a thread pool (default 6 workers, up to 32). Each worker base64-embeds the file's raw bytes (no re-encoding - it ships the original file, so no quality loss from a resize pass), POSTs to the same OpenAI-style endpoint the other API nodes use, and writes the returned text to <output_dir>/<basename>.txt. It only writes a file on success, so failures don't leave empty or half-written captions. It retries once on transient errors, strips <think> blocks, and at the end returns a JSON log with total, succeeded, failed, and the first error if any.
Inputs
- input_dir - required, must exist.
- output_dir - where captions go; if empty, it defaults to
input_dir. - api_type / api_url / API_Key / model_name - same provider map as the other API nodes (Siliconflow default, T8zhenzhen, OpenRouter, Other). Default model
Qwen/Qwen3-VL-32B-Instruct. - prompt - the system instruction (default: detailed Chinese description, 800-word cap).
- output_language - Chinese or English.
- thinking_mode, temperature, max_tokens - shared knobs.
- concurrency - 1 to 32, default 6. Be careful: this multiplies your token spend and the provider's rate limits.
Outputs: log (the JSON summary string) and save_path (where the .txt files went).
Gotchas
- Mind your concurrency and rate limits. 32 parallel calls to a free-tier key is a fast way to get 429s. Start at 6, raise only if the provider is happy.
- It's a blocking node. The workflow sits in "running" while the folder processes. A thousand images at ~10s each with 6 workers is a long Queue run - budget accordingly, and don't kill ComfyUI mid-run without checking the log.
- Your key must be real. It validates that
API_Keyisn't the<your_key>placeholder and returns a clear error if it is. - A failure is survivable. Failed files just get logged and skipped; the run continues and you see the count in the JSON.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Hasasasa/ComfyUI_DashuaiTools
cd ComfyUI_DashuaiTools
pip install -r requirements.txt
then restart ComfyUI, or install via ComfyUI Manager. Needs requests.
For dataset labeling at any real scale, this is the pack's workhorse - and if you pair it with LoadTextList on the output folder, you've closed the loop between "images" and "prompts with matching filenames."
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| input_dir | STRING | — | |
| output_dir | STRING | — | |
| api_type | COMBO | Siliconflow | 4 options: Siliconflow, T8zhenzhen, OpenRouter, Other |
| api_url | STRING | <url> | — |
| API_Key | STRING | <your_key> | — |
| model_name | STRING | Qwen/Qwen3-VL-32B-Instruct | — |
| prompt | STRING | You are a professional AI image generation prompt engineer. Please describe in detail the main body, foreground, mid-ground, background, composition, visual guidance, color tone, and light and shadow atmosphere of this image, and create an image prompt with depth, atmosphere, and artistic appeal. Requirements: Chinese prompt, no description of image watermark, no irrelevant words or symbols, no summary, limited to 800 words. | — |
| output_language | COMBO | Chinese | 2 options: Chinese, English |
| thinking_mode | BOOLEAN | false | — |
| temperature | FLOAT | 0.500–2 | — |
| max_tokens | INT | 258125–4096 | — |
| concurrency | INT | 61–32 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| log | STRING | — |
| save_path | STRING | — |