Files

CLI: english_card_cli.py

End-to-end CLI for the English vocabulary card pipeline: text prompt → generated scene → Florence-2 detection → annotated image.

Uses ComfyUI's WebSocket API. PEP 723 inline dependencies, so uv run sets up the venv automatically.

Run

Free detection (Florence-2 picks what it sees):

uv run english_card_cli.py \
    "flat vector illustration of a tidy classroom: desk, chair, blackboard, books, pencil, backpack, clock, globe, computer" \
    --ip 10.8.0.12 --steps 25

Fixed vocabulary (uses caption_to_phrase_grounding — most reliable for daily card pipelines):

uv run english_card_cli.py \
    "a sunny kitchen scene, flat vector illustration" \
    --words "apple,banana,knife,cutting board,bowl,kettle,faucet,refrigerator" \
    --ip 10.8.0.12

Arguments

Arg Default Purpose
prompt (required) Scene prompt
--words — Comma-separated target words; switches Florence-2 to caption_to_phrase_grounding
--ckpt sd_xl_base_1.0.safetensors Checkpoint filename in models/checkpoints/
--width / --height 1024 / 1024 Output dimensions
--steps 25 Sampler steps
--cfg 6.0 CFG scale
--seed (timestamp) Sampler seed
--florence2-model microsoft/Florence-2-large HF model id
--florence2-precision fp16 fp16 / bf16 / fp32
--font-size 36 Label text size
--box-width 4 Box outline width
--ip / --port 127.0.0.1 / 8188 ComfyUI server
--server — Full host:port (overrides --ip/--port)
--out ./out Output directory
--dump-workflow — Save generated API workflow JSON for debugging
--timeout 600 Seconds before giving up

Debugging

Dump the workflow JSON, then inspect or replay:

./english_card_cli.py "scene prompt" --dump-workflow /tmp/wf.json

# 1. Load /tmp/wf.json in the ComfyUI UI (Workflow → Load (API Format)) to inspect
# 2. Or POST it directly:
curl -X POST -H "Content-Type: application/json" \
    -d "$(jq -n --slurpfile p /tmp/wf.json '{prompt: $p[0]}')" \
    http://10.8.0.12:8188/prompt

Inspect the latest history (to see actual node output shapes):

curl -s http://10.8.0.12:8188/history | python3 -c "
import json, sys
h = json.load(sys.stdin)
last = sorted(h)[-1]
print(json.dumps(h[last]['outputs'], indent=2, default=str)[:1500])
"

Common adjustments

  • BBOX index mismatch — if Florence-2 returns bboxes at a different output index, edit the annotate node in build_workflow():
    "bboxes": ["f2_run", 2],   # try 1, 2, or 3 depending on Florence2 version
    "labels": ["f2_run", 3],
    
  • Z-Image-Turbo — set --steps 4 --cfg 1.0 and use the turbo checkpoint name.
  • Flux — adjust sampler_name / scheduler in build_workflow() accordingly.