Implementation:Huggingface Diffusers Log Validation
| Knowledge Sources | |
|---|---|
| Domains | Diffusion_Models, Training_Validation, Experiment_Tracking |
| Last Updated | 2026-02-13 21:00 GMT |
Overview
Concrete tool for generating and logging validation images during LoRA training, as implemented in the Diffusers text-to-image training example.
Description
The log_validation function takes a pipeline (constructed from the current training state), runs inference with a fixed validation prompt, and logs the generated images to all registered experiment trackers. It is called at the end of each validation epoch by the main process.
The function moves the pipeline to the accelerator device, creates a seeded random generator for reproducibility, and generates images one at a time within an autocast context (for mixed precision efficiency). For TensorBoard, images are logged as a grid via add_images. For Weights and Biases, images are logged as wandb.Image objects with captions. The function uses the phase name "validation" during training and "test" for the final validation after training completes.
In the LoRA training script, log_validation is called in two contexts: (1) periodically during training, where a pipeline is constructed with the in-progress UNet, and (2) after training, where the saved LoRA weights are loaded into a fresh pipeline for final evaluation.
Usage
Use log_validation when:
- You want to monitor LoRA training quality with periodic image generation
- You need to log generated images to TensorBoard or W&B
- Performing final validation after training completes
- You want reproducible validation with seeded generation
Code Reference
Source Location
- Repository: diffusers
- File:
examples/text_to_image/train_text_to_image_lora.py - Lines: 110-149
Signature
def log_validation(
pipeline,
args,
accelerator,
epoch,
is_final_validation=False,
):
Import
from diffusers import DiffusionPipeline
import torch
import numpy as np
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| pipeline | DiffusionPipeline |
Yes | A diffusion pipeline instance, either constructed with the in-training UNet or loaded with saved LoRA weights. |
| args | Namespace |
Yes | Training arguments containing validation_prompt, num_validation_images, and seed.
|
| accelerator | Accelerator |
Yes | The Accelerate accelerator instance, providing device info and tracker access. |
| epoch | int |
Yes | Current epoch number, used as the step for logging. |
| is_final_validation | bool |
No | If True, logs under the "test" phase instead of "validation". Default: False.
|
Configuration Parameters (via args)
| Name | Type | Required | Description |
|---|---|---|---|
| validation_prompt | str |
Yes | Text prompt used to generate validation images. Should test the fine-tuned capability. |
| num_validation_images | int |
No | Number of images to generate per validation step. Default: 4. |
| seed | int |
No | Random seed for the generator, ensuring reproducible validation images across epochs. |
Outputs
| Name | Type | Description |
|---|---|---|
| images | list[PIL.Image] |
List of generated validation images. |
Usage Examples
Basic Usage
from diffusers import DiffusionPipeline
import torch
# During training: construct pipeline with current UNet
pipeline = DiffusionPipeline.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5",
unet=accelerator.unwrap_model(unet),
torch_dtype=torch.float16,
)
# Run validation
images = log_validation(
pipeline=pipeline,
args=args,
accelerator=accelerator,
epoch=current_epoch,
)
# Clean up GPU memory
del pipeline
torch.cuda.empty_cache()
Final Validation After Training
# Load a fresh pipeline and apply saved LoRA weights
pipeline = DiffusionPipeline.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5",
torch_dtype=torch.float16,
)
pipeline.load_lora_weights(output_dir)
# Run final validation (logged as "test" phase)
images = log_validation(
pipeline=pipeline,
args=args,
accelerator=accelerator,
epoch=final_epoch,
is_final_validation=True,
)
Pipeline Construction for Validation
# The log_validation function internally does:
pipeline = pipeline.to(accelerator.device)
pipeline.set_progress_bar_config(disable=True)
generator = torch.Generator(device=accelerator.device)
if args.seed is not None:
generator = generator.manual_seed(args.seed)
images = []
with torch.autocast(accelerator.device.type):
for _ in range(args.num_validation_images):
image = pipeline(
args.validation_prompt,
num_inference_steps=30,
generator=generator,
).images[0]
images.append(image)