LoRA datasets

How many images do you need for a LoRA?

The short answer

There is no verified right number of images for a LoRA. The trainers' documentation doesn't give one, and the DreamBooth paper says only "just a few images of a subject". What matters is variety across situations, and images that are sharp and cropped to match their captions. Train at the base model's native size (512 for Stable Diffusion 1.5, about 1024 for SDXL), use aspect-ratio bucketing, and plan length in steps: images × repeats × epochs ÷ batch size.

Everyone wants a number: 15 images, 50, 200. We can't give you one that holds up, because the sources that would define it don't. Neither the kohya-ss sd-scripts documentation nor the Hugging Face diffusers guides we read recommend an image count for LoRA training. They do document the mechanics: how images are resized, cropped and bucketed, and how count, repeats, epochs and batch size become training steps.

This guide covers those mechanics, plus a way to reason about your own dataset. It is about the images only: captions are in how to caption a LoRA dataset with tags, and the cleaning order is in the dataset workflow guide.

There is no official number

The closest documented guidance comes from a different method. The DreamBooth paper describes its input as "just a few images of a subject", and the Hugging Face DreamBooth guide, whose sample dataset is five dog photos, says "just a few images of a subject or style". But DreamBooth updates the whole model, a LoRA trains a small set of added weights, and that guide warns that "DreamBooth is very sensitive to training hyperparameters, and it is easy to overfit." None of these sources sets a minimum or maximum for yours.

You will see precise ranges quoted in forums and videos. We found none in the trainers' own documentation, so we don't repeat them.

Reason from variety, not from a count

A count matters only through the variety it holds. Start from what you are teaching:

ConceptVary across imagesKeep constant
A characterPose, angle, distance, outfit, background, lightingThe character's own features
A styleSubject: people, animals, places, objectsThe style
An objectAngle, background, lightingThe object

Anything the same in every image, such as the background, a pose or a watermark, may be learned as part of the concept. That is why 40 pictures from one photo session can teach less than 15 from different sources.

Count also sets how much each image weighs. At 1,000 steps and batch size 2, the model sees 2,000 samples. Over 20 images, each is seen about 100 times and one flawed image is a 5% share of what is learned; over 200 images, 0.5%.

Near-duplicates act the same way: ten almost identical frames are ten samples of one picture. The duplicate image finder groups them (its Similar preset targets small crops and alternate versions; see how perceptual hashing works) and prints each image's pixel and file size, so you can keep the largest.

Match the base model's native size

Start from the size your base model learned from.

Base modelTrained atWhere it is stated
Stable Diffusion 1.5512×512The model card: fine-tuned for "595k steps at resolution 512x512"
SDXLAbout 1024×1024 pixels of area, many aspect ratiosThe SDXL paper, section 2.3, and the sd-scripts SDXL notes: "The default resolution of SDXL is 1024x1024."

The diffusers text-to-image LoRA scripts default --resolution to 512 (Stable Diffusion) and 1024 (SDXL). For any other base model, read its model card.

Source images: size and sharpness

With bucketing on (see below), larger than the training size is fine, because images are shrunk. The sd-scripts README (in Japanese) calls resizing beforehand basically unnecessary, though it tentatively cautions that images beyond roughly 3000×3000 pixels may cause errors.

Much smaller images are the real problem, since enlarging adds no detail. The README says to skip extremely small images or enlarge them first with a super-resolution tool. The SDXL paper names the risk: "upscaling artifacts which may leak into the final model outputs, causing, for example, blurry samples". In sd-scripts you can drop them, set skip_image_resolution (it skips images whose area is at or below a size you give), or set bucket_no_upscale.

Pixel size also says little about sharpness, so view samples at 100%. ImgTagger's WD14 models can't output lowres or jpeg_artifacts, so the tagger won't flag soft or compressed images.

Aspect ratio, cropping and buckets

A batch needs images of one size, and how the trainer gets there decides what is cut off.

Without bucketing

The diffusers LoRA scripts resize each image so its shorter side equals --resolution, then cut out a square, at a random position unless you pass --center_crop. A 1536×1024 landscape at resolution 512 becomes 768×512, and the square keeps 512 of 768 columns. A third of the picture is gone, somewhere different each time, and a caption that mentions it describes pixels never seen.

sd-scripts without bucketing also uses one fixed size. With --cache_latents it scales each image to cover that size and trims the center. Without latent caching it doesn't resize at all: in the version we read, a larger image stops with an error unless random_crop is on, and a smaller one stops with an "image size is small" error. The README's examples turn bucketing on and say it removes the need to unify sizes.

With bucketing

Aspect-ratio bucketing keeps each image's shape. The trainer builds a list of allowed sizes, called buckets, and sends each image to the bucket closest to its own shape. The image is scaled, never stretched, until it covers the bucket, and the small overflow is trimmed from the center (random_crop trims at a random position). Every batch comes from one bucket, so its images share a size. The SDXL paper describes the same scheme: buckets near 1024² pixels, sides in multiples of 64, one bucket per batch.

In sd-scripts, bucketing is off until you set enable_bucket. A bucket's area never exceeds the area of your resolution (512 means a square, [512, 768] means width × height). Sides move in steps of 64 (bucket_reso_steps) and stay between min_bucket_reso (default 256) and max_bucket_reso (default 1024). At resolution 512 that gives 17 possible sizes, from 512×512 out to 256×1024 and 1024×256. The dataset configuration guide lists every option.

Four images, run through sd-scripts' own bucket-selection code:

Your imageResolutionBucketScaled toTrimmed
1000×1500 (2:3)512384×640427×64043 px of width (10%)
1920×1080 (16:9)512640×384683×38443 px of width (6%)
2000×3000 (2:3)1024704×1024704×105632 px of height (3%)
3000×600 (5:1)5121024×2561280×256256 px of width (20%)

Ordinary photo shapes lose roughly 3% to 10% along one side. Panoramas lose far more, because with the default minimum and maximum buckets stop at 4:1. The third row shows a quieter effect: at resolution 1024, the default max_bucket_reso of 1024 caps every side, so that portrait trains at 704×1024, about 69% of the area of 1024×1024. With max_bucket_reso at 2048 it gets 832×1216, about 96%. The README says a larger maximum may be worth setting when you raise the resolution.

Versions we read

The sd-scripts facts are from its docs and source as of October 18, 2026 (commit 04ca541), the diffusers facts from its example scripts that day.

Cropping by hand

Bucketing handles shape. Hand cropping is for content: remove borders, watermarks, interface elements and a second person who isn't your subject. Don't square-crop everything if you use bucketing; that discards framing the trainer would keep.

Captions must match the final pixels. Crop a full-body picture to the shoulders and a "full body" caption teaches a wrong link, so crop before you tag. Every crop is also a separate training image, so ten crops of one picture are near-duplicates, not ten images.

ImgTagger has no crop tool, so use an image editor. Afterward, the face sorter can flag character images that lost their face by landing in "No Faces Detected" (it also misses some drawn faces, so look before you delete).

From images to training steps

These come from the sd-scripts README (an epoch is one pass over the data after repeats) and from how train_network.py turns --max_train_epochs into steps:

samples per epoch = images × repeats
steps per epoch   = samples per epoch ÷ batch size (rounded up)
total steps       = steps per epoch × epochs
images seen       = total steps × batch size
ImagesRepeatsEpochsBatchSteps per epochTotal stepsEach image seen
20101021001,000100 times
4051021001,00050 times
10011042525010 times

The first two rows run the same number of steps, but the first model sees 20 pictures and the second 40. Repeats change how often the trainer looks at an image, not what the images contain. The README introduces them as a way to balance regularization images against training images, and num_repeats is set per folder, so it can balance folders too. The captioning guide covers the 10_miraoc folder-name method.

Bucketing nudges the count up. Batches never mix buckets, so each bucket ends with a partial batch, and the README says the count rises slightly. Take 200 samples at batch size 4: one bucket gives 50 steps, but buckets of 90, 70 and 40 samples give 23 + 18 + 10 = 51.

With gradient accumulation, sd-scripts counts one step per optimizer update, so steps per epoch divide by the accumulation count and each step covers that many batches. The README also warns that 1,600 steps at batch size 1 and 400 at batch size 4 differ: at the same learning rate, the larger batch usually ends up under-trained.

None of this says how many steps are enough; that depends on learning rate, network size and data. Save a checkpoint every epoch (--save_every_n_epochs=1) and compare outputs.

Audit files before you train

The metadata viewer works as a dataset inventory. For each file it shows format, file size, dimensions, megapixels and aspect ratio, plus a Color type row for PNGs (for example "RGB with alpha"). Its CSV export has one row per field (File, Group, Field, Value), so filter the Field column to list dimensions. Then check three things.

  • Format. sd-scripts looks for PNG, JPEG, WebP and BMP files (AVIF and JPEG XL only with optional libraries). GIF, TIFF and HEIC aren't on its list, so convert them first.
  • Transparency. By default sd-scripts converts each image to RGB, which drops the alpha channel instead of blending it onto a background, so transparent areas show whatever color values the file stores underneath. Our tagger treats them as white, so captions and trainer can disagree. Flatten transparent images onto a plain background yourself and caption it. The alternative is alpha_mask, which makes the trainer ignore transparent pixels in DreamBooth-style datasets (see the masked loss notes).
  • Rotation. Phone photos are often stored sideways with an Orientation tag, which the viewer lists as a row. We found no code in sd-scripts that applies the tag, while the diffusers DreamBooth LoRA script does, so a tagged photo may train sideways. Neither the viewer nor the metadata remover rotates pixels. Re-save the photo upright in an editor and confirm in the viewer that the row is gone. The EXIF guide explains the tag.
Put this into practice

Group visually similar images with perceptual hashing. It catches resized, re-saved and lightly edited copies that file hashes miss. It runs in your browser. Open the Duplicate Image Finder.

Frequently asked questions

Should I turn on flip augmentation or random crop?

Only on purpose. In sd-scripts, flip_aug mirrors each image half the time, and random_crop trims overflow at a random position instead of the center. diffusers offers --random_flip, and crops randomly unless you pass --center_crop. Skip mirroring when sides differ: an asymmetric hairstyle, a one-sided accessory, any text.

Can I train at a larger size than the base model's native size?

The trainer allows it. The sd-scripts README says that for SD 1.x a larger or non-square size such as [512, 768] "may" reduce breakage in tall or wide generations, and that a bigger resolution calls for a bigger max_bucket_reso (it mentions 1280 for 768). It promises no extra detail, and memory use follows bucket area. We found no benchmark, so treat anything above native as an experiment.

How do I tell whether my set is big enough?

Test it. Save a checkpoint every epoch and prompt for situations that aren't in your dataset, such as another outfit, background or angle. If the concept falls apart there, add images that cover those situations rather than adding repeats. If outputs copy training images, you may have too few distinct images or too many steps, so compare earlier checkpoints. This is common practice, not a documented rule.

Does ImgTagger crop, resize or convert my images?

No tool of ours crops or resizes your files. The duplicate finder and face sorter download your originals unchanged. The color fixer re-encodes each image at its original pixel size (JPEG stays JPEG, WebP stays WebP, everything else becomes PNG). The metadata remover rewrites JPEG, PNG, WebP and GIF files without decoding pixels. The tagger scales a padded copy to 448×448 for the model only. Files added to any ImgTagger tool are also uploaded to our servers, so use copies you are comfortable sharing (see the privacy policy).