Lora dataset prep
Skill shahshrey/fal-portrait-lora-skills/skills/lora-dataset-prep
Prepares portrait LoRA training datasets: face-centered 1024x1024 crops, mandatory visual QA and manual crop correction, contact sheets, ZIP packing, and descriptive [trigger] captions via Florence-2. Use when preparing images for FLUX portrait training, fal-ai/flux-lora-portrait-trainer, Kohya, or person LoRA training; or when the user mentions dataset prep, captioning training images, cropping faces for LoRA, or building training ZIP archives.From its SKILL.md
npx -y skills add shahshrey/fal-portrait-lora-skills --skill lora-dataset-prepAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 20 days oldThe repository was created 20 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
6.4 KB, ~1.5k tokens by cl100k_base, as published. Nobody here has run it
LoRA Dataset Prep
Prepare a fal/FLUX-compatible portrait LoRA dataset from a raw photo folder.
Defaults
| Setting | Default |
|---|---|
| Size | 1024×1024 JPEG |
| Trigger phrase | ohwx man (ask user; keep unique) |
| Caption identity token | [trigger] |
| Filename prefix | subject |
| Image policy | Keep user-curated images unless visual QA finds a real defect |
| ZIP layout | flat: name.jpg + matching name.txt |
Workflow
Copy and track:
Progress:
- [ ] 1. Setup env + YuNet model
- [ ] 2. Confirm trigger word + source/out paths
- [ ] 3. Crop every source + generate numbered contact sheets
- [ ] 4. Visually inspect every crop; manually correct failures
- [ ] 5. Descriptive captions with trigger
- [ ] 6. Validate pairs + build flat ZIP; report counts
Resolve skill path (project copy preferred):
SKILL_DIR=".cursor/skills/lora-dataset-prep"
[ -d "$SKILL_DIR" ] || SKILL_DIR="$HOME/.cursor/skills/lora-dataset-prep"
[ -d "$SKILL_DIR" ] || SKILL_DIR="skills/lora-dataset-prep"
1. Setup
From the project working directory:
bash "$SKILL_DIR/scripts/setup_env.sh"
Deps: Python 3, opencv-python-headless, pillow, numpy, fal-client, python-dotenv.
Auth for captioning: FAL_KEY or FAL_API_KEY in .env.
2. Confirm inputs
Ask if missing:
- Source image folder
- Output folder (default:
./prepared_dataset) - Trigger token (default:
ohwx man) - Subject filename prefix (default:
subject)
3. Crop every source
.venv/bin/python "$SKILL_DIR/scripts/prepare_all_portraits.py" \
--src "/path/to/raw_photos" \
--out "./prepared_dataset" \
--model "./models/face_detection_yunet_2023mar.onnx" \
--prefix "subject"
Produces:
prepared_dataset/images/*.jpg+[trigger]placeholder.txtprepared_dataset/contact_sheets/*.jpgprepared_dataset/manifest.json
The detector proposes crops; it does not decide whether an image is usable. Do not discard an image solely because detection fails or its face is distant.
Crops target roughly 4.2× the detected face, but never shrink below 1024 native pixels, so a distant face stays as tight as the source allows without being upscaled past 1:1. A face that still looks small after cropping means the source was low resolution, not that the crop misfired.
4. Visual QA and correction (required)
First generate advisory flags:
.venv/bin/python "$SKILL_DIR/scripts/qc_flags.py" \
--images "./prepared_dataset/images" \
--model "./models/face_detection_yunet_2023mar.onnx" \
--pattern "subject_*.jpg"
Writes prepared_dataset/qc_flags.json, including near_duplicate_of flags
for burst shots. Treat these flags as review prompts, not automatic rejection
decisions.
Then use image vision to open every file under
prepared_dataset/contact_sheets/, not only the automated flags:
- Confirm the intended subject appears correctly in every numbered crop.
- Open suspicious outputs and their source files at full resolution.
- Manually recrop wrong-subject, torso-only, clipped, or off-center outputs.
- Regenerate contact sheets and inspect the corrected cells.
- Record manual crop boxes in
manifest.json.
Apply each visually chosen square crop reproducibly:
.venv/bin/python "$SKILL_DIR/scripts/manual_recrop.py" \
--source "/path/to/raw_photos/source.jpg" \
--dataset-root "./prepared_dataset" \
--output-name "subject_068.jpg" \
--box 882 320 2422 1860
The helper replaces the crop, records manual_visual_qa in the manifest, and
regenerates all contact sheets. Reopen the affected sheet and verify it.
Never use --delete-flagged without visually confirming each deletion.
See references/qc-checklist.md.
5. Caption
Prefer descriptive per-image captions over a single shared caption.
.venv/bin/python "$SKILL_DIR/scripts/recaption_dataset.py" \
--images "./prepared_dataset/images" \
--zip "./prepared_dataset/dataset.zip" \
--trigger "ohwx man" \
--pattern "subject_*.jpg" \
--caption-mode placeholder \
--gender male \
--workers 8
Set --gender to match the subject. Florence-2 writes gendered nouns and
pronouns; the polisher rewrites them to one consistent set so the trigger
carries the identity instead of a description.
Read the printed samples. If the polish left artifacts, edit the regex rules and re-derive captions from the saved raw text instead of paying for the API again:
.venv/bin/python "$SKILL_DIR/scripts/recaption_dataset.py" \
--images "./prepared_dataset/images" \
--zip "./prepared_dataset/dataset.zip" \
--trigger "ohwx man" \
--pattern "subject_*.jpg" \
--gender male \
--reuse-report
--reuse-report re-polishes every entry in captions.json, rewrites the
.txt files, and rebuilds the ZIP. It drops entries whose image no longer
exists, so it stays correct after deletions.
Caption rules: references/caption-rules.md.
6. Deliver
Report:
- Kept / rejected counts
- Trigger word
- ZIP path
- 3–5 sample captions
Ready for fal-ai/flux-lora-portrait-trainer as images_data_url with
trigger_phrase set to the chosen trigger.
Scripts
| Script | Role |
|---|---|
scripts/setup_env.sh | venv, pip deps, download YuNet ONNX |
scripts/portrait_common.py | shared face detection, QC policy, hashing, sheets, ZIP |
scripts/prepare_all_portraits.py | crop all images + split contact sheets |
scripts/manual_recrop.py | apply visual crop + update manifest/sheets |
scripts/qc_flags.py | framing + near-duplicate flags → qc_flags.json |
scripts/recaption_dataset.py | Florence-2 captions + polish + re-zip |
Degrees of freedom
- Low: 1024 crops, visual review of every contact sheet, flat ZIP pairs,
[trigger]first in captions - Medium: crop framing and automated flag thresholds
- High: manual crop corrections and whether a visibly defective source should be excluded
What ships with it: 8 files
26.6 KB alongside SKILL.md, 6 of them executable
references/
- caption-rules.md1.2 KB
- qc-checklist.md1.2 KB
scripts/
- manual_recrop.pyruns2.6 KB
- portrait_common.pyruns4.8 KB
- prepare_all_portraits.pyruns3.2 KB
- qc_flags.pyruns2.6 KB
- recaption_dataset.pyruns10.5 KB
- setup_env.shruns625 B