kontextox/datasety

CLI tool for dataset preparation: resize, align, caption, shuffle, synthetic, and mask generation.

2

stars

67

commits

Python

primary language

Apr 10, 2026

updated

kontextox.github.io/datasety/
ai
align
caption
caption-generation
captioning-images
captions
dataset
fine-tuning
finetuning
mask
mask-image
resize
resize-images
shuffle
synthetic
synthetic-dataset-generation
synthetic-images

README

CLI tool for dataset preparation

PyPI License: MIT Python 3.10+

CLI tool for dataset preparation — resize, caption, align, shuffle, synthetic editing, masking, degradation, character generation, LoRA training, audio TTS datasets, upload to HuggingFace, and multi-step workflows.

Full documentation →


Installation

pip install datasety                 # core (resize, align, shuffle, degrade)
pip install datasety[caption]        # + Florence-2 captioning
pip install datasety[synthetic]      # + image editing (FLUX, Qwen, SDXL)
pip install datasety[mask]           # + segmentation masks (SAM 3, CLIPSeg)
pip install datasety[filter]         # + content filtering (CLIP, NudeNet)
pip install datasety[character]      # + character dataset generation
pip install datasety[workflow]       # + YAML workflow support
pip install datasety[train]          # + LoRA training (FLUX, Qwen) & TTS (Piper)
pip install datasety[audio]          # + TTS audio datasets (YouTube, VAD, Piper)
pip install datasety[video]          # + video datasets (same deps as audio)
pip install datasety[upload]         # + upload to HuggingFace Hub
pip install datasety[all]            # everything

Commands

resize — Resize & Crop Images

Batch resize images to exact dimensions with configurable crop positions.

datasety resize --input ./raw --output ./resized --resolution 768x1024 --crop-position top
Options
OptionDescriptionDefault
--input, -iInput directoryrequired*
--output, -oOutput directoryrequired*
--input-imageSingle input image (alternative to dir mode)
--output-imageSingle output image (use with --input-image)
--resolution, -rTarget resolution (WIDTHxHEIGHT)
--megapixelTarget megapixel count (e.g., 0.5, 1.0)
--aspect-ratioAspect ratio W:H (e.g., 1:1, 16:9)
--crop-positiontop, center, bottom, left, rightcenter
--input-formatComma-separated input formatsjpg,jpeg,png,webp
--output-formatjpg, png, webpjpg
--output-name-numbersRename output files to 1.jpg, 2.jpg, ...off
--upscaleUpscale images smaller than targetoff
--min-resolutionSkip images below this size (e.g., 256x256)
--workersParallel workers for processing1
--recursive, -RSearch input directory recursivelyoff
--progressShow tqdm progress baroff
--dry-runPreview without modifying filesoff
# Single image
datasety resize --input-image photo.jpg --output-image resized.jpg -r 512x512

# Batch with sequential numbering
datasety resize -i ./photos -o ./dataset -r 1024x1024 --output-name-numbers --crop-position top

Full documentation →


filter — Filter Dataset by Content

Filter, curate, or clean datasets based on image content. Use CLIP for arbitrary text queries or NudeNet for NSFW label detection.

datasety filter --input ./dataset --output ./rejected --query "leg,male face" --action move
Options
OptionDescriptionDefault
--input, -iInput directoryrequired
--output, -oOutput directory for matched/rejected images
--query, -qComma-separated text queries (CLIP)
--labels, -lComma-separated NudeNet labels
--modelclip, nudenetclip
--actionmove, copy, delete, keepmove
--thresholdConfidence threshold (0.0-1.0)0.5
--deviceauto, cpu, cuda, mpsauto
--confirmRequired for destructive actions (delete, keep)off
--preserve-structureKeep subfolder hierarchy in output (with --recursive)off
--invertInvert match logic (act on non-matches)off
--logWrite CSV log of all decisions to this path
--dry-runPreview detections without modifying filesoff
--recursive, -RSearch input directory recursivelyoff
--progressShow tqdm progress baroff
# Move images containing legs or male faces to a reject folder
datasety filter -i ./dataset -o ./rejected --query "leg,male face" --action move

# Delete NSFW images using NudeNet labels
datasety filter -i ./dataset --labels "FEMALE_BREAST_EXPOSED,MALE_GENITALIA_EXPOSED" \
    --action delete --model nudenet --threshold 0.6 --confirm

# Keep only images with "hat and socks", move the rest out
datasety filter -i ./dataset -o ./rejected --query "hat and socks" --action keep

# Dry-run to preview what would be filtered
datasety filter -i ./dataset --query "blurry,low quality" --action delete --dry-run -R

# Write a decision log for review
datasety filter -i ./dataset -o ./rejected --query "outdoor" --action copy --log filter_log.csv

Full documentation →


degrade — Image Degradation

Create degraded versions of images for upscale/enhance training. Pure Pillow, no extra dependencies.

datasety degrade --input ./originals --output ./dataset --type random --intensity-range 0.2-0.8 --paired
Options
OptionDescriptionDefault
--input, -iInput directoryrequired*
--output, -oOutput directoryrequired*
--input-imageSingle input image
--output-imageSingle output image
--type, -tDegradation type(s), repeatablerandom
--intensityGlobal intensity (0.0-1.0)0.5
--intensity-rangeRandom range MIN-MAX
--chainApply multiple types sequentiallyoff
--num-variantsVariants per input image1
--pairedCreate control/ + target/ subdirsoff
--seedRandom seed
--output-formatpng, jpg, webppng
--skip-existingSkip images with existing outputoff
--workersParallel workers for processing1
--progressShow tqdm progress baroff
--dry-runPreview without writing filesoff

Degradation types: lowres, oversharpen, noise, blur, jpeg, motion-blur, pixelate, color-bands, upscale-sim, random

# Chain specific degradations for paired output
datasety degrade -i ./images -o ./dataset --type jpeg --type noise --chain --paired --seed 42

# Multiple random variants per image
datasety degrade -i ./images -o ./degraded --type random --num-variants 3 --intensity-range 0.3-0.8

Full documentation →


mask — Text-Prompted Segmentation Masks

Generate binary masks from images using text keywords. Supports SAM 3, SAM 2, and CLIPSeg.

datasety mask --input ./dataset --output ./masks --keywords "face,hair" --device cuda
Options
OptionDescriptionDefault
--input, -iInput directoryrequired*
--output, -oOutput directory for masksrequired*
--input-imageSingle input image
--output-imageSingle output mask
--keywords, -kComma-separated keywordsrequired
--modelsam3, sam2, clipsegsam3
--deviceauto, cpu, cuda, mpsauto
--thresholdConfidence threshold (0.0-1.0)0.3
--paddingPixels to expand mask (dilation)0
--blurGaussian blur radius for edges0
--invertInvert mask colorsoff
--namingfolder or suffix (_mask)folder
--output-formatpng, jpg, webppng
--skip-existingSkip images with existing masksoff
--dry-runPreview detections without savingoff
--recursive, -RSearch input directory recursivelyoff
--progressShow tqdm progress baroff
# CLIPSeg (lightweight, no extra deps)
datasety mask -i ./dataset -o ./masks -k "face" --model clipseg --threshold 0.5

# SAM 2 with mask refinement
datasety mask -i ./dataset -o ./masks -k "hat,glasses" --model sam2 --padding 5 --blur 3

Full documentation →


caption — Generate Image Captions

Generate captions using Florence-2 (local) or OpenAI-compatible vision APIs.

datasety caption --input ./images --output ./captions --template "[trigger] {{caption}}"
Options
OptionDescriptionDefault
--input, -iInput directoryrequired*
--output, -oOutput directory for .txt filesrequired*
--input-imageSingle input image
--output-captionSingle output .txt path
--deviceauto, cpu, cuda, mpsauto
--templateTemplate for caption text.
--promptFlorence-2 task prompt<MORE_DETAILED_CAPTION>
--modelHF model name or API model ID
--num-beamsBeam search width (1 = greedy)3
--florence-2-baseUse Florence-2-base (0.23B, faster)default
--florence-2-largeUse Florence-2-large (0.77B, more accurate)
--llm-apiUse OpenAI-compatible vision API
--max-tokensMax response tokens (API mode)300
--temperatureTemperature (API mode)0.3
--skip-existingSkip images that already have a .txt fileoff
--appendAppend text to existing captions
--prependPrepend text to existing captions
--recursive, -RSearch input directory recursivelyoff
--progressShow tqdm progress baroff
--dry-runPreview without processingoff
# Florence-2 with template
datasety caption -i ./dataset -o ./dataset --template "photo of sks person, {{caption}}" --device cuda

# Template without placeholder (prepends text)
datasety caption -i ./dataset -o ./dataset --template "photo of sks person," --device cuda

# OpenAI vision API (supports OPENAI_MODEL env var)
datasety caption -i ./images -o ./captions --llm-api --model gpt-5-nano

Full documentation →


shuffle — Random Caption Generation

Generate random captions by picking one variant from each text group.

datasety shuffle -i ./images -o ./captions \
    --group "A photo of a person.|Portrait of someone." \
    --group "Remove the hat.|Take off the hat."
Options
OptionDescriptionDefault
--input, -iInput directory containing imagesrequired
--output, -oOutput directory for .txt filesrequired
--group, -gInline |-separated, .txt file, or URLrequired
--separatorSeparator between groups" "
--seedRandom seed for reproducibility
--dry-runPreview captions without writingoff
--show-distributionShow caption distribution after generationoff
# Mix file, URL, and inline sources
datasety shuffle -i ./images -o ./captions \
    --group subjects.txt \
    --group "ending A|ending B" \
    --seed 42 --show-distribution

Full documentation →


synthetic — Synthetic Image Editing

Generate synthetic variations using image editing models (FLUX.2-klein FP8, FLUX.2-klein-9b-kv, Qwen-Image-Edit-2511, SDXL, LongCat, HunyuanImage). The default model FLUX.2-klein-4b-fp8 requires no HuggingFace token and fits in ~5 GB VRAM.

datasety synthetic --input ./images --output ./synthetic --prompt "add a winter hat" --steps 4
Options
OptionDescriptionDefault
--input, -iInput directoryrequired*
--output, -oOutput directoryrequired*
--input-imageSingle input image
--output-imageSingle output image
--prompt, -pEdit instructionrequired
--modelModel (auto-detects family or API model)black-forest-labs/FLUX.2-klein-4b-fp8
--image-apiUse OpenAI-compatible API for generationoff
--api-aspect-ratioAspect ratio for --image-api (e.g. 16:9, 9:16, 1:1)auto
--api-image-sizeResolution for --image-api: 0.5K, 1K, 2K, 4K1K
--weightsFine-tuned weights file
--loraLoRA adapter (repeatable, :WEIGHT)
--deviceauto, cpu, cuda, mpsauto
--cpu-offloadForce CPU offloadauto
--stepsInference steps4
--cfg-scaleGuidance scale2.5
--true-cfg-scaleTrue CFG (Qwen only)4.0
--negative-promptNegative prompt" "
--num-imagesImages per input1
--seedRandom seed
--ggufGGUF path/URL for quantized loading
--strengthImg2img strength (SDXL/FLUX.2, 0.0-1.0)0.7
--recursive, -RSearch input directory recursivelyoff
--output-formatpng, jpg, webppng
--skip-existingSkip images with existing outputoff
--batch-sizeFlush GPU memory every N images0 (off)
--progressShow tqdm progress baroff
--dry-runPreview without loading modelsoff
# Single image edit
datasety synthetic --input-image photo.jpg --output-image edited.png \
    --prompt "add sunglasses" --steps 4

# Cloud API — FLUX.2-flex (no GPU needed)
OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://openrouter.ai/api/v1 \
  datasety synthetic -i ./images -o ./synthetic \
  --prompt "add a winter hat" --image-api --model black-forest-labs/flux.2-flex \
  --api-aspect-ratio 1:1

# Cloud API — Gemini 2.5 Flash (text+image, supports image-to-image)
OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://openrouter.ai/api/v1 \
  datasety synthetic -i ./images -o ./synthetic \
  --prompt "transform into oil painting style" \
  --model google/gemini-2.5-flash-image --image-api \
  --api-aspect-ratio 3:4 --api-image-size 2K

# FLUX.2-klein-9b-kv (KV-cache, faster multi-reference, ~29 GB VRAM)
datasety synthetic -i ./images -o ./synthetic \
    --model "black-forest-labs/FLUX.2-klein-9b-kv" \
    --prompt "add sunglasses" --steps 4

# Qwen-Image-Edit-2511 with LoRA
datasety synthetic -i ./dataset -o ./synthetic \
    --model "Qwen/Qwen-Image-Edit-2511" \
    --lora "adapter.safetensors:0.8" \
    --prompt "add a red scarf" --steps 40

Full documentation →


character — Character Dataset Generation

Generate character datasets using LLM-generated prompts + text-to-image (FLUX.2-klein local or cloud API).

datasety character --output ./dataset --llm-ollama qwen3.5:4b --num-images 20
Options
OptionDescriptionDefault
--reference, -rReference face image(s) (optional, prompt context)
--output, -oOutput directoryrequired
--num-images, -nNumber of images to generate10
--modelModel for generation (local HF or API model ID)black-forest-labs/FLUX.2-klein-4b-fp8
--ggufGGUF path/URL for quantized loading
--image-apiUse OpenAI-compatible API for image generationoff
--api-aspect-ratioAspect ratio for --image-api (e.g. 9:16, 1:1)derived from --width/--height
--api-image-sizeResolution for --image-api: 0.5K, 1K, 2K, 4K
--character-descriptionText description of the character
--styleStyle guidance (e.g., photorealistic)
--prompts-onlyOnly generate prompts, skip imagesoff
--prompts-fileLoad prompts from file instead of LLM
--llm-apiUse OpenAI-compatible API for prompts
--llm-ollama MODELUse local Ollama server for prompts
--llm-gguf PATHUse local GGUF model for prompts
--llm-model REPOUse HuggingFace model for prompts
--deviceauto, cpu, cuda, mpsauto
--stepsInference steps4
--cfg-scaleGuidance scale4.0
--seedRandom seed
--heightOutput image height1024
--widthOutput image width1024
--output-formatpng, jpg, webppng
--batch-sizeFlush GPU memory every N images0 (off)
--dry-runPreview prompts without generating imagesoff
# Generate with local pipeline + Ollama prompts
datasety character -o ./dataset --llm-ollama qwen3.5:4b --num-images 20

# Cloud API for images (no GPU needed)
OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://openrouter.ai/api/v1 \
  datasety character -o ./dataset --prompts-file prompts.txt \
  --image-api --model black-forest-labs/flux.2-flex --api-aspect-ratio 2:3

# Preview prompts only
datasety character -o ./dataset --llm-api --prompts-only

Full documentation →


audio — Build TTS Audio Datasets

Build TTS (Text-to-Speech) audio datasets from video or audio files. Supports YouTube URLs, direct media URLs, local files, and text files containing lists of paths. Extracts audio, transcribes with faster-whisper, performs deep text cleaning, and outputs paired .wav + .txt files, or LJSpeech-compatible format with --metadata.

datasety audio --input ./video.mp4 --output ./dataset
datasety audio --input ./clips/ --output ./dataset
datasety audio --input "https://www.youtube.com/watch?v=..." --output ./dataset --language uk
Options
OptionDescriptionDefault
--input, -iInput: local file, URL, dir, or .txt list. Append ?start=X&end=Y to slicerequired
--output, -oOutput directory for the datasetrequired
--sample-rateOutput audio sample rate in Hz22050
--metadataOutput LJSpeech/Piper format with metadata.csv + wavs/ (default: flat pairs)false
--demucsEnable Demucs vocal isolationfalse
--demucs-modelDemucs model namehtdemucs
--whisper-modelFaster-Whisper model: tiny, base, small, medium, large-v3base
--languageLanguage code (e.g., en, es, fr, uk). Auto-detected if omitted(auto)
--deviceDevice: auto, cpu, cuda, mpsauto
--vadEnable voice activity detection (VAD) to filter non-speechfalse
--min-durationMinimum segment duration in seconds1.5
--max-durationMaximum segment duration in seconds30.0
--merge-gapMerge segments closer than this many seconds0.0 (off)
--normalize-numbersExpand digits into wordsfalse
--no-clean-textDisable special character strippingfalse
--phoneme-mapPath to config.json/phonemes.json to filter bad text (with --metadata)
--workersNumber of parallel file workers (default: 1)1
--keep-tempKeep temporary audio files at this path
--resumeResume a previous run (skip existing chunks, append to CSV)false
--overwriteOverwrite existing output directoryfalse
--dry-runPrint pipeline steps without executingfalse
--verbose, -VPrint detailed progress messagesfalse
# Default: flat .wav/.txt pairs with timestamp-based naming
datasety audio --input ./video.mp4 --output ./dataset

# LJSpeech/Piper format with metadata.csv + wavs/
datasety audio --input ./video.mp4 --output ./dataset --metadata

# Extract a specific 40-second slice from a YouTube video
datasety audio --input "https://youtube.com/watch?v=...?start=50&end=90" -o ./dataset

# Local video with vocal isolation and high-quality transcription
datasety audio --input ./video.mp4 --output ./dataset --demucs --whisper-model large-v3

# Parallel processing of multiple files
datasety audio --input ./videos/ --output ./dataset --workers 4

Full documentation →


video — Build Video Datasets

Build video datasets from video files. Extracts video segments based on speech transcription and outputs paired .mp4 + .txt files.

datasety video --input ./video.mp4 --output ./dataset
datasety video --input ./clips/ --output ./dataset
datasety video --input "https://www.youtube.com/watch?v=..." --output ./dataset --language en
Options
OptionDescriptionDefault
--input, -iInput: local file, URL, dir, or .txt list. Append ?start=X&end=Y to slicerequired
--output, -oOutput directory for the datasetrequired
--demucsEnable Demucs vocal isolation for transcriptionfalse
--demucs-modelDemucs model namehtdemucs
--whisper-modelFaster-Whisper model: tiny, base, small, medium, large-v3base
--languageLanguage code (e.g., en, es, fr). Auto-detected if omitted(auto)
--deviceDevice: auto, cpu, cuda, mpsauto
--vadEnable voice activity detection (VAD) to filter non-speechfalse
--min-durationMinimum segment duration in seconds1.5
--max-durationMaximum segment duration in seconds30.0
--merge-gapMerge segments closer than this many seconds0.0 (off)
--re-encodeRe-encode for frame-accurate cuts (default: stream-copy)false
--normalize-numbersExpand digits into wordsfalse
--no-clean-textDisable special character strippingfalse
--workersNumber of parallel file workers (default: 1)1
--resumeResume a previous runfalse
--overwriteOverwrite existing output directoryfalse
--dry-runPrint pipeline steps without executingfalse
--verbose, -VPrint detailed progress messagesfalse
# YouTube video with timestamp-based segment naming
datasety video --input "https://youtube.com/watch?v=..." --output ./dataset

# Local video with frame-accurate cuts
datasety video --input ./interview.mp4 --output ./dataset --re-encode

# Directory of clips with vocal isolation for transcription
datasety video --input ./videos/ --output ./dataset --demucs --workers 4

Full documentation →


align — Align Control/Target Pairs

Match dimensions, enforce multiples of 32, and unify formats for control/target training pairs. Includes a built-in web server for visual comparison with a compare slider, caption editing, and pair management.

datasety align --target ./target --control ./control --dry-run
Options
OptionDescriptionDefault
--target, -tTarget images directoryrequired
--control, -cControl images directoryrequired
--multiple-ofAlign dimensions to this multiple32
--output-formatConvert all images: jpg, png, webpkeep original
--recursive, -RSearch input directories recursivelyoff
--dry-runPreview changes without modifying filesoff
# Preview, then apply
datasety align -t ./target -c ./control --dry-run
datasety align -t ./target -c ./control --output-format jpg

Full documentation →


train — LoRA Fine-Tuning & TTS Training

Train a LoRA adapter for image generation models (FLUX, SDXL, Qwen) or a TTS voice model (Piper). The mode is auto-detected from --family (flux/sdxl/qwen) or --backend (piper/coqui/f5-tts).

Image parameters (--family flux/sdxl/qwen): --lr, --lora-rank, --lora-alpha, --image-size, --optimizer, --lr-scheduler, etc.

Audio parameters (--backend piper): --sample-rate, --batch-size, --accelerator, --devices, --test-text.

# Image: FLUX.2-klein LoRA (~8 GB VRAM)
datasety train --input ./dataset --output lora.safetensors --family flux --steps 500 --lr 1e-4 --lora-rank 16

# Audio: Piper TTS (auto-downloads base model, auto-installs Piper, multi-GPU, voice watcher)
datasety train -i ./tts_dataset -o ./tts_output --backend piper \
    --model "rhasspy/piper-checkpoints:en/en_US/kristin/medium" \
    --devices auto --test-text "Hello world"
Image (LoRA) Options
OptionDescriptionDefault
--familyModel family: flux, sdxl, qwenauto-detected
--model, -mHuggingFace repo ID (base model)black-forest-labs/FLUX.2-klein-base-4B
--output, -oOutput .safetensors pathlora.safetensors
--stepsTraining steps100
--lrLearning rate1e-4
--lora-rankLoRA rank16
--lora-alphaLoRA alpha16.0
--lora-dropoutLoRA dropout rate0.0
--image-sizeTraining resolution (square crop)512
--deviceauto, cpu, cuda, mpsauto
--seedRandom seed42
--save-everySave checkpoint every N stepsend only
--resumeResume from a .safetensors checkpoint
--validation-splitFraction for validation (0.0–0.5)
--timestep-typeTimestep sampling: sigmoid, lognorm, linearsigmoid
--caption-dropoutProbability of dropping caption0.05
--gradient-checkpointingEnable gradient checkpointing (saves VRAM)off
--optimizeradamw or adamw8bit (requires bitsandbytes)adamw
--lr-schedulerLR schedule: constant, cosine, linearconstant
--lr-warmup-stepsLinear warmup steps0
--gradient-accumulation-stepsAccumulate gradients over N steps1
--min-snr-gammaMin-SNR-γ for SDXL (recommended: 5.0)disabled
--noise-offsetPer-channel noise offset for SDXL (recommended: 0.05–0.1)0.0
Audio (TTS) Options
OptionDescriptionDefault
--backendTTS backend: piper (coqui, f5-tts planned)piper
--modelPiper base model (repo_id:subfolder or local path)(required)
--output, -oOutput directory for .ckpt checkpoints(required)
--stepsTraining epochs100
--sample-rateAudio sample rate in Hz22050
--batch-sizeTraining batch size32
--acceleratorPyTorch Lightning accelerator: auto, gpu, cpuauto
--devicesNumber of GPUs: auto, 1, 2, -1 (all)auto
--test-textBackground inference text to test checkpoints
--seedRandom seed42

Full documentation →


Generate workflow YAML files with parameter grid combinations for synthetic editing. Computes the Cartesian product of sweep parameters.

datasety sweep -i ./images -o ./sweep_output -p "add a winter hat" --steps 4,8,16 --cfg-scale 1.0,2.5,5.0
Options
OptionDescriptionDefault
--input, -iInput images directoryrequired
--output, -oBase output directoryrequired
--prompt, -pEdit promptrequired
--stepsComma-separated step values to sweep
--cfg-scaleComma-separated CFG values to sweep
--true-cfg-scaleComma-separated true CFG values to sweep
--strengthComma-separated strength values to sweep
--loraComma-separated LoRA specs to sweep
--modelComma-separated model names to sweep
--seedRandom seed (passed through)
--output-fileOutput YAML pathsweep.yaml
--runGenerate and immediately executeoff
# Generate YAML, inspect, then run
datasety sweep -i ./images -o ./sweep -p "add sunglasses" --steps 4,8,16 --cfg-scale 1.0,2.5
datasety workflow -f sweep.yaml

# Generate and run immediately
datasety sweep -i ./images -o ./sweep -p "add a hat" --steps 4,8 --cfg-scale 2.0,3.0 --run

Full documentation →


workflow — Multi-Step Pipelines

Run multi-step datasety pipelines from YAML or JSON files with dry-run validation.

datasety workflow --file datasety.yaml --dry-run
Options
OptionDescriptionDefault
--file, -fPath to workflow fileauto-detect
--dry-runValidate steps without executingoff

Create datasety.yaml:

steps:
  - command: resize
    args:
      input: ./raw
      output: ./resized
      resolution: 768x1024
  - command: caption
    args:
      input: ./resized
      output: ./resized
      llm-api: true
      model: gpt-5-nano
# Validate first, then execute
datasety workflow --dry-run
datasety workflow

Full documentation →


server — REST API Server

Start a headless REST API for remote dataset management and job execution.

datasety server --port 8080

Provides /v1/ endpoints to register datasets (auto-detects types), manage files with full CRUD, and remotely execute any datasety command via JSON payloads.

Endpoints
EndpointMethodDescription
/v1/datasetsPOSTRegister a dataset
/v1/datasetsGETList all datasets
/v1/datasets/<id>GETGet dataset info
/v1/datasets/<id>PATCHUpdate dataset name
/v1/datasets/<id>DELETEUnregister dataset
/v1/datasets/<id>/filesGETList files (supports ?folder=&group= query params)
/v1/datasets/<id>/files/<path>GETDownload a file (or get info with ?info=true)
/v1/datasets/<id>/files/<path>POSTCreate a new file (binary, base64, or sidecar caption/metadata)
/v1/datasets/<id>/files/<path>PUTUpdate a file and/or its caption/metadata sidecars
/v1/datasets/<id>/files/<path>DELETEDelete a file (add ?caption=true to also remove .txt sidecar)
/v1/jobsGETList all jobs
/v1/jobsPOSTStart a new job (run any datasety command)
/v1/jobs/<id>GETGet job status & output
/v1/jobs/<id>DELETECancel a running job
/v1/commandsGETGet command schemas

Full API documentation →


upload — Upload to HuggingFace Hub

Upload datasets and model adapters to HuggingFace Hub. Auto-detects type (audio, image, video, document, model, generic) from directory structure and generates HF-compliant README dataset cards with YAML frontmatter.

datasety upload --path ./tts_dataset --repo-id user/my-voice --type audio
datasety upload --path ./lora_output --repo-id user/klein-lora --type model
datasety upload --path ./dataset --repo-id user/my-dataset --dry-run
Options
OptionDescriptionDefault
--path, -pPath to the dataset or model directory to uploadrequired
--repo-id, -rHuggingFace repo ID (e.g. username/my-dataset). Derived from dir name if omitted(derived)
--type, -tDataset or model typeauto
--privateMake the repository privatefalse
--tokenHuggingFace API token (or set HF_TOKEN env var)HF_TOKEN
--forceForce regenerate README.md if it already existsfalse
--dry-runShow what would be uploaded without uploadingfalse
--metadataExtra YAML key: value pairs for dataset card frontmatter
--yes, -ySkip all confirmation promptsfalse
--verbose, -VPrint detailed progress messagesfalse
# Upload a TTS dataset (auto-generates README with TTS task card)
datasety upload --path ./tts_dataset --repo-id your-username/my-voice --private

# Upload a LoRA adapter
datasety upload --path ./lora.safetensors --repo-id your-username/klein-lora --type model

# Dry-run to verify what will be uploaded
datasety upload --path ./dataset --repo-id user/dataset --dry-run --verbose

# With extra metadata
datasety upload --path ./dataset --repo-id user/dataset \
    --metadata 'license:cc-by-4.0 language: [en,fr]'

Full documentation →


License

MIT

Contributors

kontextox

67 commits

kontextox/datasety

CLI tool for dataset preparation: resize, align, caption, shuffle, synthetic, and mask generation.

2

stars

67

commits

Python

primary language

Apr 10, 2026

updated

kontextox.github.io/datasety/
ai
align
caption
caption-generation
captioning-images
captions
dataset
fine-tuning
finetuning
mask
mask-image
resize
resize-images
shuffle
synthetic
synthetic-dataset-generation
synthetic-images

README

CLI tool for dataset preparation

PyPI License: MIT Python 3.10+

CLI tool for dataset preparation — resize, caption, align, shuffle, synthetic editing, masking, degradation, character generation, LoRA training, audio TTS datasets, upload to HuggingFace, and multi-step workflows.

Full documentation →


Installation

pip install datasety                 # core (resize, align, shuffle, degrade)
pip install datasety[caption]        # + Florence-2 captioning
pip install datasety[synthetic]      # + image editing (FLUX, Qwen, SDXL)
pip install datasety[mask]           # + segmentation masks (SAM 3, CLIPSeg)
pip install datasety[filter]         # + content filtering (CLIP, NudeNet)
pip install datasety[character]      # + character dataset generation
pip install datasety[workflow]       # + YAML workflow support
pip install datasety[train]          # + LoRA training (FLUX, Qwen) & TTS (Piper)
pip install datasety[audio]          # + TTS audio datasets (YouTube, VAD, Piper)
pip install datasety[video]          # + video datasets (same deps as audio)
pip install datasety[upload]         # + upload to HuggingFace Hub
pip install datasety[all]            # everything

Commands

resize — Resize & Crop Images

Batch resize images to exact dimensions with configurable crop positions.

datasety resize --input ./raw --output ./resized --resolution 768x1024 --crop-position top
Options
OptionDescriptionDefault
--input, -iInput directoryrequired*
--output, -oOutput directoryrequired*
--input-imageSingle input image (alternative to dir mode)
--output-imageSingle output image (use with --input-image)
--resolution, -rTarget resolution (WIDTHxHEIGHT)
--megapixelTarget megapixel count (e.g., 0.5, 1.0)
--aspect-ratioAspect ratio W:H (e.g., 1:1, 16:9)
--crop-positiontop, center, bottom, left, rightcenter
--input-formatComma-separated input formatsjpg,jpeg,png,webp
--output-formatjpg, png, webpjpg
--output-name-numbersRename output files to 1.jpg, 2.jpg, ...off
--upscaleUpscale images smaller than targetoff
--min-resolutionSkip images below this size (e.g., 256x256)
--workersParallel workers for processing1
--recursive, -RSearch input directory recursivelyoff
--progressShow tqdm progress baroff
--dry-runPreview without modifying filesoff
# Single image
datasety resize --input-image photo.jpg --output-image resized.jpg -r 512x512

# Batch with sequential numbering
datasety resize -i ./photos -o ./dataset -r 1024x1024 --output-name-numbers --crop-position top

Full documentation →


filter — Filter Dataset by Content

Filter, curate, or clean datasets based on image content. Use CLIP for arbitrary text queries or NudeNet for NSFW label detection.

datasety filter --input ./dataset --output ./rejected --query "leg,male face" --action move
Options
OptionDescriptionDefault
--input, -iInput directoryrequired
--output, -oOutput directory for matched/rejected images
--query, -qComma-separated text queries (CLIP)
--labels, -lComma-separated NudeNet labels
--modelclip, nudenetclip
--actionmove, copy, delete, keepmove
--thresholdConfidence threshold (0.0-1.0)0.5
--deviceauto, cpu, cuda, mpsauto
--confirmRequired for destructive actions (delete, keep)off
--preserve-structureKeep subfolder hierarchy in output (with --recursive)off
--invertInvert match logic (act on non-matches)off
--logWrite CSV log of all decisions to this path
--dry-runPreview detections without modifying filesoff
--recursive, -RSearch input directory recursivelyoff
--progressShow tqdm progress baroff
# Move images containing legs or male faces to a reject folder
datasety filter -i ./dataset -o ./rejected --query "leg,male face" --action move

# Delete NSFW images using NudeNet labels
datasety filter -i ./dataset --labels "FEMALE_BREAST_EXPOSED,MALE_GENITALIA_EXPOSED" \
    --action delete --model nudenet --threshold 0.6 --confirm

# Keep only images with "hat and socks", move the rest out
datasety filter -i ./dataset -o ./rejected --query "hat and socks" --action keep

# Dry-run to preview what would be filtered
datasety filter -i ./dataset --query "blurry,low quality" --action delete --dry-run -R

# Write a decision log for review
datasety filter -i ./dataset -o ./rejected --query "outdoor" --action copy --log filter_log.csv

Full documentation →


degrade — Image Degradation

Create degraded versions of images for upscale/enhance training. Pure Pillow, no extra dependencies.

datasety degrade --input ./originals --output ./dataset --type random --intensity-range 0.2-0.8 --paired
Options
OptionDescriptionDefault
--input, -iInput directoryrequired*
--output, -oOutput directoryrequired*
--input-imageSingle input image
--output-imageSingle output image
--type, -tDegradation type(s), repeatablerandom
--intensityGlobal intensity (0.0-1.0)0.5
--intensity-rangeRandom range MIN-MAX
--chainApply multiple types sequentiallyoff
--num-variantsVariants per input image1
--pairedCreate control/ + target/ subdirsoff
--seedRandom seed
--output-formatpng, jpg, webppng
--skip-existingSkip images with existing outputoff
--workersParallel workers for processing1
--progressShow tqdm progress baroff
--dry-runPreview without writing filesoff

Degradation types: lowres, oversharpen, noise, blur, jpeg, motion-blur, pixelate, color-bands, upscale-sim, random

# Chain specific degradations for paired output
datasety degrade -i ./images -o ./dataset --type jpeg --type noise --chain --paired --seed 42

# Multiple random variants per image
datasety degrade -i ./images -o ./degraded --type random --num-variants 3 --intensity-range 0.3-0.8

Full documentation →


mask — Text-Prompted Segmentation Masks

Generate binary masks from images using text keywords. Supports SAM 3, SAM 2, and CLIPSeg.

datasety mask --input ./dataset --output ./masks --keywords "face,hair" --device cuda
Options
OptionDescriptionDefault
--input, -iInput directoryrequired*
--output, -oOutput directory for masksrequired*
--input-imageSingle input image
--output-imageSingle output mask
--keywords, -kComma-separated keywordsrequired
--modelsam3, sam2, clipsegsam3
--deviceauto, cpu, cuda, mpsauto
--thresholdConfidence threshold (0.0-1.0)0.3
--paddingPixels to expand mask (dilation)0
--blurGaussian blur radius for edges0
--invertInvert mask colorsoff
--namingfolder or suffix (_mask)folder
--output-formatpng, jpg, webppng
--skip-existingSkip images with existing masksoff
--dry-runPreview detections without savingoff
--recursive, -RSearch input directory recursivelyoff
--progressShow tqdm progress baroff
# CLIPSeg (lightweight, no extra deps)
datasety mask -i ./dataset -o ./masks -k "face" --model clipseg --threshold 0.5

# SAM 2 with mask refinement
datasety mask -i ./dataset -o ./masks -k "hat,glasses" --model sam2 --padding 5 --blur 3

Full documentation →


caption — Generate Image Captions

Generate captions using Florence-2 (local) or OpenAI-compatible vision APIs.

datasety caption --input ./images --output ./captions --template "[trigger] {{caption}}"
Options
OptionDescriptionDefault
--input, -iInput directoryrequired*
--output, -oOutput directory for .txt filesrequired*
--input-imageSingle input image
--output-captionSingle output .txt path
--deviceauto, cpu, cuda, mpsauto
--templateTemplate for caption text.
--promptFlorence-2 task prompt<MORE_DETAILED_CAPTION>
--modelHF model name or API model ID
--num-beamsBeam search width (1 = greedy)3
--florence-2-baseUse Florence-2-base (0.23B, faster)default
--florence-2-largeUse Florence-2-large (0.77B, more accurate)
--llm-apiUse OpenAI-compatible vision API
--max-tokensMax response tokens (API mode)300
--temperatureTemperature (API mode)0.3
--skip-existingSkip images that already have a .txt fileoff
--appendAppend text to existing captions
--prependPrepend text to existing captions
--recursive, -RSearch input directory recursivelyoff
--progressShow tqdm progress baroff
--dry-runPreview without processingoff
# Florence-2 with template
datasety caption -i ./dataset -o ./dataset --template "photo of sks person, {{caption}}" --device cuda

# Template without placeholder (prepends text)
datasety caption -i ./dataset -o ./dataset --template "photo of sks person," --device cuda

# OpenAI vision API (supports OPENAI_MODEL env var)
datasety caption -i ./images -o ./captions --llm-api --model gpt-5-nano

Full documentation →


shuffle — Random Caption Generation

Generate random captions by picking one variant from each text group.

datasety shuffle -i ./images -o ./captions \
    --group "A photo of a person.|Portrait of someone." \
    --group "Remove the hat.|Take off the hat."
Options
OptionDescriptionDefault
--input, -iInput directory containing imagesrequired
--output, -oOutput directory for .txt filesrequired
--group, -gInline |-separated, .txt file, or URLrequired
--separatorSeparator between groups" "
--seedRandom seed for reproducibility
--dry-runPreview captions without writingoff
--show-distributionShow caption distribution after generationoff
# Mix file, URL, and inline sources
datasety shuffle -i ./images -o ./captions \
    --group subjects.txt \
    --group "ending A|ending B" \
    --seed 42 --show-distribution

Full documentation →


synthetic — Synthetic Image Editing

Generate synthetic variations using image editing models (FLUX.2-klein FP8, FLUX.2-klein-9b-kv, Qwen-Image-Edit-2511, SDXL, LongCat, HunyuanImage). The default model FLUX.2-klein-4b-fp8 requires no HuggingFace token and fits in ~5 GB VRAM.

datasety synthetic --input ./images --output ./synthetic --prompt "add a winter hat" --steps 4
Options
OptionDescriptionDefault
--input, -iInput directoryrequired*
--output, -oOutput directoryrequired*
--input-imageSingle input image
--output-imageSingle output image
--prompt, -pEdit instructionrequired
--modelModel (auto-detects family or API model)black-forest-labs/FLUX.2-klein-4b-fp8
--image-apiUse OpenAI-compatible API for generationoff
--api-aspect-ratioAspect ratio for --image-api (e.g. 16:9, 9:16, 1:1)auto
--api-image-sizeResolution for --image-api: 0.5K, 1K, 2K, 4K1K
--weightsFine-tuned weights file
--loraLoRA adapter (repeatable, :WEIGHT)
--deviceauto, cpu, cuda, mpsauto
--cpu-offloadForce CPU offloadauto
--stepsInference steps4
--cfg-scaleGuidance scale2.5
--true-cfg-scaleTrue CFG (Qwen only)4.0
--negative-promptNegative prompt" "
--num-imagesImages per input1
--seedRandom seed
--ggufGGUF path/URL for quantized loading
--strengthImg2img strength (SDXL/FLUX.2, 0.0-1.0)0.7
--recursive, -RSearch input directory recursivelyoff
--output-formatpng, jpg, webppng
--skip-existingSkip images with existing outputoff
--batch-sizeFlush GPU memory every N images0 (off)
--progressShow tqdm progress baroff
--dry-runPreview without loading modelsoff
# Single image edit
datasety synthetic --input-image photo.jpg --output-image edited.png \
    --prompt "add sunglasses" --steps 4

# Cloud API — FLUX.2-flex (no GPU needed)
OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://openrouter.ai/api/v1 \
  datasety synthetic -i ./images -o ./synthetic \
  --prompt "add a winter hat" --image-api --model black-forest-labs/flux.2-flex \
  --api-aspect-ratio 1:1

# Cloud API — Gemini 2.5 Flash (text+image, supports image-to-image)
OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://openrouter.ai/api/v1 \
  datasety synthetic -i ./images -o ./synthetic \
  --prompt "transform into oil painting style" \
  --model google/gemini-2.5-flash-image --image-api \
  --api-aspect-ratio 3:4 --api-image-size 2K

# FLUX.2-klein-9b-kv (KV-cache, faster multi-reference, ~29 GB VRAM)
datasety synthetic -i ./images -o ./synthetic \
    --model "black-forest-labs/FLUX.2-klein-9b-kv" \
    --prompt "add sunglasses" --steps 4

# Qwen-Image-Edit-2511 with LoRA
datasety synthetic -i ./dataset -o ./synthetic \
    --model "Qwen/Qwen-Image-Edit-2511" \
    --lora "adapter.safetensors:0.8" \
    --prompt "add a red scarf" --steps 40

Full documentation →


character — Character Dataset Generation

Generate character datasets using LLM-generated prompts + text-to-image (FLUX.2-klein local or cloud API).

datasety character --output ./dataset --llm-ollama qwen3.5:4b --num-images 20
Options
OptionDescriptionDefault
--reference, -rReference face image(s) (optional, prompt context)
--output, -oOutput directoryrequired
--num-images, -nNumber of images to generate10
--modelModel for generation (local HF or API model ID)black-forest-labs/FLUX.2-klein-4b-fp8
--ggufGGUF path/URL for quantized loading
--image-apiUse OpenAI-compatible API for image generationoff
--api-aspect-ratioAspect ratio for --image-api (e.g. 9:16, 1:1)derived from --width/--height
--api-image-sizeResolution for --image-api: 0.5K, 1K, 2K, 4K
--character-descriptionText description of the character
--styleStyle guidance (e.g., photorealistic)
--prompts-onlyOnly generate prompts, skip imagesoff
--prompts-fileLoad prompts from file instead of LLM
--llm-apiUse OpenAI-compatible API for prompts
--llm-ollama MODELUse local Ollama server for prompts
--llm-gguf PATHUse local GGUF model for prompts
--llm-model REPOUse HuggingFace model for prompts
--deviceauto, cpu, cuda, mpsauto
--stepsInference steps4
--cfg-scaleGuidance scale4.0
--seedRandom seed
--heightOutput image height1024
--widthOutput image width1024
--output-formatpng, jpg, webppng
--batch-sizeFlush GPU memory every N images0 (off)
--dry-runPreview prompts without generating imagesoff
# Generate with local pipeline + Ollama prompts
datasety character -o ./dataset --llm-ollama qwen3.5:4b --num-images 20

# Cloud API for images (no GPU needed)
OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://openrouter.ai/api/v1 \
  datasety character -o ./dataset --prompts-file prompts.txt \
  --image-api --model black-forest-labs/flux.2-flex --api-aspect-ratio 2:3

# Preview prompts only
datasety character -o ./dataset --llm-api --prompts-only

Full documentation →


audio — Build TTS Audio Datasets

Build TTS (Text-to-Speech) audio datasets from video or audio files. Supports YouTube URLs, direct media URLs, local files, and text files containing lists of paths. Extracts audio, transcribes with faster-whisper, performs deep text cleaning, and outputs paired .wav + .txt files, or LJSpeech-compatible format with --metadata.

datasety audio --input ./video.mp4 --output ./dataset
datasety audio --input ./clips/ --output ./dataset
datasety audio --input "https://www.youtube.com/watch?v=..." --output ./dataset --language uk
Options
OptionDescriptionDefault
--input, -iInput: local file, URL, dir, or .txt list. Append ?start=X&end=Y to slicerequired
--output, -oOutput directory for the datasetrequired
--sample-rateOutput audio sample rate in Hz22050
--metadataOutput LJSpeech/Piper format with metadata.csv + wavs/ (default: flat pairs)false
--demucsEnable Demucs vocal isolationfalse
--demucs-modelDemucs model namehtdemucs
--whisper-modelFaster-Whisper model: tiny, base, small, medium, large-v3base
--languageLanguage code (e.g., en, es, fr, uk). Auto-detected if omitted(auto)
--deviceDevice: auto, cpu, cuda, mpsauto
--vadEnable voice activity detection (VAD) to filter non-speechfalse
--min-durationMinimum segment duration in seconds1.5
--max-durationMaximum segment duration in seconds30.0
--merge-gapMerge segments closer than this many seconds0.0 (off)
--normalize-numbersExpand digits into wordsfalse
--no-clean-textDisable special character strippingfalse
--phoneme-mapPath to config.json/phonemes.json to filter bad text (with --metadata)
--workersNumber of parallel file workers (default: 1)1
--keep-tempKeep temporary audio files at this path
--resumeResume a previous run (skip existing chunks, append to CSV)false
--overwriteOverwrite existing output directoryfalse
--dry-runPrint pipeline steps without executingfalse
--verbose, -VPrint detailed progress messagesfalse
# Default: flat .wav/.txt pairs with timestamp-based naming
datasety audio --input ./video.mp4 --output ./dataset

# LJSpeech/Piper format with metadata.csv + wavs/
datasety audio --input ./video.mp4 --output ./dataset --metadata

# Extract a specific 40-second slice from a YouTube video
datasety audio --input "https://youtube.com/watch?v=...?start=50&end=90" -o ./dataset

# Local video with vocal isolation and high-quality transcription
datasety audio --input ./video.mp4 --output ./dataset --demucs --whisper-model large-v3

# Parallel processing of multiple files
datasety audio --input ./videos/ --output ./dataset --workers 4

Full documentation →


video — Build Video Datasets

Build video datasets from video files. Extracts video segments based on speech transcription and outputs paired .mp4 + .txt files.

datasety video --input ./video.mp4 --output ./dataset
datasety video --input ./clips/ --output ./dataset
datasety video --input "https://www.youtube.com/watch?v=..." --output ./dataset --language en
Options
OptionDescriptionDefault
--input, -iInput: local file, URL, dir, or .txt list. Append ?start=X&end=Y to slicerequired
--output, -oOutput directory for the datasetrequired
--demucsEnable Demucs vocal isolation for transcriptionfalse
--demucs-modelDemucs model namehtdemucs
--whisper-modelFaster-Whisper model: tiny, base, small, medium, large-v3base
--languageLanguage code (e.g., en, es, fr). Auto-detected if omitted(auto)
--deviceDevice: auto, cpu, cuda, mpsauto
--vadEnable voice activity detection (VAD) to filter non-speechfalse
--min-durationMinimum segment duration in seconds1.5
--max-durationMaximum segment duration in seconds30.0
--merge-gapMerge segments closer than this many seconds0.0 (off)
--re-encodeRe-encode for frame-accurate cuts (default: stream-copy)false
--normalize-numbersExpand digits into wordsfalse
--no-clean-textDisable special character strippingfalse
--workersNumber of parallel file workers (default: 1)1
--resumeResume a previous runfalse
--overwriteOverwrite existing output directoryfalse
--dry-runPrint pipeline steps without executingfalse
--verbose, -VPrint detailed progress messagesfalse
# YouTube video with timestamp-based segment naming
datasety video --input "https://youtube.com/watch?v=..." --output ./dataset

# Local video with frame-accurate cuts
datasety video --input ./interview.mp4 --output ./dataset --re-encode

# Directory of clips with vocal isolation for transcription
datasety video --input ./videos/ --output ./dataset --demucs --workers 4

Full documentation →


align — Align Control/Target Pairs

Match dimensions, enforce multiples of 32, and unify formats for control/target training pairs. Includes a built-in web server for visual comparison with a compare slider, caption editing, and pair management.

datasety align --target ./target --control ./control --dry-run
Options
OptionDescriptionDefault
--target, -tTarget images directoryrequired
--control, -cControl images directoryrequired
--multiple-ofAlign dimensions to this multiple32
--output-formatConvert all images: jpg, png, webpkeep original
--recursive, -RSearch input directories recursivelyoff
--dry-runPreview changes without modifying filesoff
# Preview, then apply
datasety align -t ./target -c ./control --dry-run
datasety align -t ./target -c ./control --output-format jpg

Full documentation →


train — LoRA Fine-Tuning & TTS Training

Train a LoRA adapter for image generation models (FLUX, SDXL, Qwen) or a TTS voice model (Piper). The mode is auto-detected from --family (flux/sdxl/qwen) or --backend (piper/coqui/f5-tts).

Image parameters (--family flux/sdxl/qwen): --lr, --lora-rank, --lora-alpha, --image-size, --optimizer, --lr-scheduler, etc.

Audio parameters (--backend piper): --sample-rate, --batch-size, --accelerator, --devices, --test-text.

# Image: FLUX.2-klein LoRA (~8 GB VRAM)
datasety train --input ./dataset --output lora.safetensors --family flux --steps 500 --lr 1e-4 --lora-rank 16

# Audio: Piper TTS (auto-downloads base model, auto-installs Piper, multi-GPU, voice watcher)
datasety train -i ./tts_dataset -o ./tts_output --backend piper \
    --model "rhasspy/piper-checkpoints:en/en_US/kristin/medium" \
    --devices auto --test-text "Hello world"
Image (LoRA) Options
OptionDescriptionDefault
--familyModel family: flux, sdxl, qwenauto-detected
--model, -mHuggingFace repo ID (base model)black-forest-labs/FLUX.2-klein-base-4B
--output, -oOutput .safetensors pathlora.safetensors
--stepsTraining steps100
--lrLearning rate1e-4
--lora-rankLoRA rank16
--lora-alphaLoRA alpha16.0
--lora-dropoutLoRA dropout rate0.0
--image-sizeTraining resolution (square crop)512
--deviceauto, cpu, cuda, mpsauto
--seedRandom seed42
--save-everySave checkpoint every N stepsend only
--resumeResume from a .safetensors checkpoint
--validation-splitFraction for validation (0.0–0.5)
--timestep-typeTimestep sampling: sigmoid, lognorm, linearsigmoid
--caption-dropoutProbability of dropping caption0.05
--gradient-checkpointingEnable gradient checkpointing (saves VRAM)off
--optimizeradamw or adamw8bit (requires bitsandbytes)adamw
--lr-schedulerLR schedule: constant, cosine, linearconstant
--lr-warmup-stepsLinear warmup steps0
--gradient-accumulation-stepsAccumulate gradients over N steps1
--min-snr-gammaMin-SNR-γ for SDXL (recommended: 5.0)disabled
--noise-offsetPer-channel noise offset for SDXL (recommended: 0.05–0.1)0.0
Audio (TTS) Options
OptionDescriptionDefault
--backendTTS backend: piper (coqui, f5-tts planned)piper
--modelPiper base model (repo_id:subfolder or local path)(required)
--output, -oOutput directory for .ckpt checkpoints(required)
--stepsTraining epochs100
--sample-rateAudio sample rate in Hz22050
--batch-sizeTraining batch size32
--acceleratorPyTorch Lightning accelerator: auto, gpu, cpuauto
--devicesNumber of GPUs: auto, 1, 2, -1 (all)auto
--test-textBackground inference text to test checkpoints
--seedRandom seed42

Full documentation →


Generate workflow YAML files with parameter grid combinations for synthetic editing. Computes the Cartesian product of sweep parameters.

datasety sweep -i ./images -o ./sweep_output -p "add a winter hat" --steps 4,8,16 --cfg-scale 1.0,2.5,5.0
Options
OptionDescriptionDefault
--input, -iInput images directoryrequired
--output, -oBase output directoryrequired
--prompt, -pEdit promptrequired
--stepsComma-separated step values to sweep
--cfg-scaleComma-separated CFG values to sweep
--true-cfg-scaleComma-separated true CFG values to sweep
--strengthComma-separated strength values to sweep
--loraComma-separated LoRA specs to sweep
--modelComma-separated model names to sweep
--seedRandom seed (passed through)
--output-fileOutput YAML pathsweep.yaml
--runGenerate and immediately executeoff
# Generate YAML, inspect, then run
datasety sweep -i ./images -o ./sweep -p "add sunglasses" --steps 4,8,16 --cfg-scale 1.0,2.5
datasety workflow -f sweep.yaml

# Generate and run immediately
datasety sweep -i ./images -o ./sweep -p "add a hat" --steps 4,8 --cfg-scale 2.0,3.0 --run

Full documentation →


workflow — Multi-Step Pipelines

Run multi-step datasety pipelines from YAML or JSON files with dry-run validation.

datasety workflow --file datasety.yaml --dry-run
Options
OptionDescriptionDefault
--file, -fPath to workflow fileauto-detect
--dry-runValidate steps without executingoff

Create datasety.yaml:

steps:
  - command: resize
    args:
      input: ./raw
      output: ./resized
      resolution: 768x1024
  - command: caption
    args:
      input: ./resized
      output: ./resized
      llm-api: true
      model: gpt-5-nano
# Validate first, then execute
datasety workflow --dry-run
datasety workflow

Full documentation →


server — REST API Server

Start a headless REST API for remote dataset management and job execution.

datasety server --port 8080

Provides /v1/ endpoints to register datasets (auto-detects types), manage files with full CRUD, and remotely execute any datasety command via JSON payloads.

Endpoints
EndpointMethodDescription
/v1/datasetsPOSTRegister a dataset
/v1/datasetsGETList all datasets
/v1/datasets/<id>GETGet dataset info
/v1/datasets/<id>PATCHUpdate dataset name
/v1/datasets/<id>DELETEUnregister dataset
/v1/datasets/<id>/filesGETList files (supports ?folder=&group= query params)
/v1/datasets/<id>/files/<path>GETDownload a file (or get info with ?info=true)
/v1/datasets/<id>/files/<path>POSTCreate a new file (binary, base64, or sidecar caption/metadata)
/v1/datasets/<id>/files/<path>PUTUpdate a file and/or its caption/metadata sidecars
/v1/datasets/<id>/files/<path>DELETEDelete a file (add ?caption=true to also remove .txt sidecar)
/v1/jobsGETList all jobs
/v1/jobsPOSTStart a new job (run any datasety command)
/v1/jobs/<id>GETGet job status & output
/v1/jobs/<id>DELETECancel a running job
/v1/commandsGETGet command schemas

Full API documentation →


upload — Upload to HuggingFace Hub

Upload datasets and model adapters to HuggingFace Hub. Auto-detects type (audio, image, video, document, model, generic) from directory structure and generates HF-compliant README dataset cards with YAML frontmatter.

datasety upload --path ./tts_dataset --repo-id user/my-voice --type audio
datasety upload --path ./lora_output --repo-id user/klein-lora --type model
datasety upload --path ./dataset --repo-id user/my-dataset --dry-run
Options
OptionDescriptionDefault
--path, -pPath to the dataset or model directory to uploadrequired
--repo-id, -rHuggingFace repo ID (e.g. username/my-dataset). Derived from dir name if omitted(derived)
--type, -tDataset or model typeauto
--privateMake the repository privatefalse
--tokenHuggingFace API token (or set HF_TOKEN env var)HF_TOKEN
--forceForce regenerate README.md if it already existsfalse
--dry-runShow what would be uploaded without uploadingfalse
--metadataExtra YAML key: value pairs for dataset card frontmatter
--yes, -ySkip all confirmation promptsfalse
--verbose, -VPrint detailed progress messagesfalse
# Upload a TTS dataset (auto-generates README with TTS task card)
datasety upload --path ./tts_dataset --repo-id your-username/my-voice --private

# Upload a LoRA adapter
datasety upload --path ./lora.safetensors --repo-id your-username/klein-lora --type model

# Dry-run to verify what will be uploaded
datasety upload --path ./dataset --repo-id user/dataset --dry-run --verbose

# With extra metadata
datasety upload --path ./dataset --repo-id user/dataset \
    --metadata 'license:cc-by-4.0 language: [en,fr]'

Full documentation →


License

MIT

Contributors

kontextox

67 commits

Languages

Python

100.0%