How the AUTOMATIC1111 Training Tab Works for Embeddings and Hypernetworks: A Technical Deep Dive
The AUTOMATIC1111 training tab routes user inputs through Gradio callbacks to either train_embedding() in modules/textual_inversion/textual_inversion.py or train_hypernetwork() in modules/hypernetworks/hypernetwork.py, both executing gradient-accumulating optimization loops with shared dataset loading, learning rate scheduling, and interruption handling.
The AUTOMATIC1111 Stable Diffusion WebUI training tab provides a unified interface for fine-tuning textual inversion embeddings and hypernetworks without writing custom training scripts. According to the source code in modules/ui.py, the tab constructs Gradio components that wire directly to specialized training pipelines handling dataset preparation, optimizer configuration, and checkpoint serialization. Whether you are teaching the model a new token representation via embeddings or injecting style-specific modulation layers via hypernetworks, the underlying architecture follows the same validation, training, and logging infrastructure defined in the repository’s core modules.
UI Architecture and Entry Points
The Train tab interface is constructed in modules/ui.py (approximately lines 968-990) using Gradio sliders, text boxes, and buttons. Key UI elements include dimension controls, learning rate inputs, and action buttons:
# modules/ui.py – UI construction for training controls
training_width = gr.Slider(minimum=64, maximum=2048, step=8,
label="Width", value=512, elem_id="train_training_width")
training_height = gr.Slider(minimum=64, maximum=2048, step=8,
label="Height", value=512, elem_id="train_training_height")
train_embedding = gr.Button(value="Train Embedding", variant='primary',
elem_id="train_train_embedding")
train_hypernetwork = gr.Button(value="Train Hypernetwork", variant='primary',
elem_id="train_train_hypernetwork")
Callback wiring occurs immediately after UI definition. The Train Embedding button triggers textual_inversion_ui.train_embedding, while Train Hypernetwork triggers hypernetworks_ui.train_hypernetwork. Both utilize wrap_gradio_gpu_call to ensure GPU computation runs on a separate thread while maintaining UI responsiveness:
# modules/ui.py – Embedding callback registration (lines 1037-1054)
train_embedding.click(
fn=wrap_gradio_gpu_call(textual_inversion_ui.train_embedding,
extra_outputs=[gr.update()]),
_js="start_training_textual_inversion",
inputs=[ ... training parameters ... ],
outputs=[ti_output, ti_outcome],
)
# modules/ui.py – Hypernetwork callback registration (lines 1071-1088)
train_hypernetwork.click(
fn=wrap_gradio_gpu_call(hypernetworks_ui.train_hypernetwork,
extra_outputs=[gr.update()]),
_js="start_training_textual_inversion",
inputs=[ ... training parameters ... ],
outputs=[ti_output, ti_outcome],
)
The Interrupt button connects directly to shared.state.interrupt(), allowing immediate termination of either training job by setting a global interruption flag checked within the training loops.
Training Textual Inversion Embeddings
Entry Point and Validation
When a user initiates embedding training, the request flows through textual_inversion_ui.train_embedding in modules/textual_inversion/ui.py. This wrapper performs two critical checks: it asserts that shared.cmd_opts.lowvram is disabled (training requires sufficient VRAM), and conditionally disables cross-attention optimizations if the user has opted to train without them:
# modules/textual_inversion/ui.py – Entry point (lines 17-28)
def train_embedding(*args):
assert not shared.cmd_opts.lowvram, 'Training models with lowvram not possible'
apply_optimizations = shared.opts.training_xattention_optimizations
if not apply_optimizations:
sd_hijack.undo_optimizations()
embedding, filename = modules.textual_inversion.textual_inversion.train_embedding(*args)
Core Training Loop
The actual optimization occurs in modules/textual_inversion/textual_inversion.py within the train_embedding() function (signature at lines 400-410). The implementation follows a structured pipeline:
- Input validation via
validate_train_inputs() - Dataset preparation using
PersonalizedBase, which handles image loading, optional PNG alpha-channel weighting, and tag shuffling - Optimizer and scheduler setup with
LearnRateSchedulerfor dynamic learning rate adjustment - Gradient accumulation loop respecting the
gradient_stepparameter - Checkpointing and preview generation at user-specified intervals
The training loop utilizes automatic mixed precision and gradient scaling:
# modules/textual_inversion/textual_inversion.py – Training loop excerpt
scheduler = LearnRateScheduler(learn_rate, steps, initial_step)
clip_grad = torch.nn.utils.clip_grad_value_ if clip_grad_mode == "value" else \
torch.nn.utils.clip_grad_norm_ if clip_grad_mode == "norm" else None
for _ in range((steps - initial_step) * gradient_step):
if scheduler.finished or shared.state.interrupted:
break
for j, batch in enumerate(dl):
with devices.autocast():
x = batch.latent_sample.to(devices.device, non_blocking=pin_memory)
loss = shared.sd_model.forward(x, c)[0] / gradient_step
scaler.scale(loss).backward()
if (j + 1) % gradient_step == 0:
scaler.step(optimizer); scaler.update()
if clip_grad:
clip_grad(weights, clip_grad_sched.learn_rate)
optimizer.zero_grad()
The function saves embeddings to the embedding_dir and generates preview images based on the create_image_every and save_embedding_every parameters. Upon completion, it returns the updated embedding object and file path to the UI.
Training Hypernetworks
Architectural Differences
Hypernetwork training in AUTOMATIC1111 follows a parallel architecture but implements fundamentally different model modifications. While embeddings learn new token vectors in the text encoder's embedding space, hypernetworks learn additional neural network layers that modulate the UNet's cross-attention mechanisms.
The entry point in modules/hypernetworks/ui.py mirrors the embedding wrapper but clears any previously loaded hypernetworks to ensure a clean training state:
# modules/hypernetworks/ui.py – Entry point (lines 17-28)
def train_hypernetwork(*args):
shared.loaded_hypernetworks = []
hypernetwork, filename = modules.hypernetworks.hypernetwork.train_hypernetwork(*args)
return f"Training {'interrupted' if shared.state.interrupted else 'finished'} at {hypernetwork.step} steps.", ""
Hypernetwork Injection Mechanism
The critical distinction appears in modules/hypernetworks/hypernetwork.py (lines 473-485). The training function loads or creates a Hypernetwork instance and inserts it into shared.loaded_hypernetworks. During forward passes, the UNet's cross-attention layers are dynamically patched via sd_hijack_optimizations.py (lines 186-190) to invoke hypernetwork.apply_hypernetworks(), injecting learned modulation tensors into attention keys and values.
The dataset configuration differs by setting include_cond=True, providing the hypernetwork access to both image latents and text conditioning:
# modules/hypernetworks/hypernetwork.py – Dataset with conditioning
ds = modules.textual_inversion.dataset.PersonalizedBase(
data_root=data_root, width=training_width, height=training_height,
repeats=shared.opts.training_image_repeats_per_epoch,
placeholder_token=hypernetwork_name,
model=shared.sd_model, cond_model=shared.sd_model.cond_stage_model,
device=devices.device, template_file=template_file,
include_cond=True, # Critical difference from embeddings
batch_size=batch_size,
gradient_step=gradient_step, shuffle_tags=shuffle_tags,
tag_drop_out=tag_drop_out, latent_sampling_method=latent_sampling_method,
varsize=varsize, use_weight=use_weight)
The optimization loop structure—gradient accumulation, clipping, and mixed precision—remains identical to the embedding pipeline, ensuring consistent behavior across training modes.
Shared Training Infrastructure
Both training modes rely on configuration options defined in modules/shared_options.py under the training category (lines 155-167). These settings control hardware utilization and logging behavior:
unload_models_when_training: Moves VAE and CLIP to system RAM during training to maximize VRAM for the UNetpin_memory: Enablespin_memory=Truefor the DataLoader, accelerating CPU-to-GPU transferstraining_xattention_optimizations: Determines whether to disable memory-efficient attention optimizations during training (required for numerical stability in some configurations)training_enable_tensorboard: Activates TensorBoard logging with configurable flush intervals and image saving
The training loops check shared.state.interrupted at every step boundary, allowing immediate termination via the UI's Interrupt button regardless of training mode.
Programmatic Training Without the UI
You can trigger training programmatically by importing the core functions directly, bypassing the Gradio interface. This approach is useful for automation or integration with external workflows:
import modules.textual_inversion.textual_inversion as ti
from modules import shared
# Configure training parameters
args = (
"CustomConcept", # embedding_name
0.0005, # learn_rate
4, # batch_size
1, # gradient_step
"/path/to/dataset", # data_root
"logs/embeddings", # log_directory
512, 512, # training_width, training_height
False, # varsize
20000, # steps
"norm", 0.1, # clip_grad_mode, clip_grad_value
True, False, # shuffle_tags, tag_drop_out
"once", False, # latent_sampling_method, use_weight
500, 500, # create_image_every, save_embedding_every
"style_filewords.txt", # template_filename
True, # save_image_with_stored_embedding
False, "", "", 20, "Euler a", 7.0, 42, 512, 512 # preview params
)
# Execute training
embedding, filename = ti.train_embedding(*args)
print(f"Saved to {filename} at step {embedding.step}")
For hypernetworks, substitute modules.hypernetworks.hypernetwork.train_hypernetwork() with equivalent parameters.
Summary
- The Train tab in
modules/ui.pyconstructs Gradio interfaces that route to specialized training functions viawrap_gradio_gpu_call(). - Embeddings train via
modules/textual_inversion/textual_inversion.py, learning new token vectors using thePersonalizedBasedataset without UNet modification. - Hypernetworks train via
modules/hypernetworks/hypernetwork.py, learning attention modulation layers that are injected into the UNet throughsd_hijack_optimizations.py. - Both modes share gradient accumulation, learning rate scheduling, gradient clipping (value or norm), and interruption handling via
shared.state.interrupted. - Training configuration persists in
modules/shared_options.py, controlling VRAM management, TensorBoard logging, and optimization settings.
Frequently Asked Questions
What is the difference between training embeddings and hypernetworks in AUTOMATIC1111?
Textual inversion embeddings learn new token vectors that extend the text encoder's vocabulary, allowing you to reference custom concepts in prompts using short trigger words. Hypernetworks learn additional neural network weights that modify the UNet's cross-attention layers, altering how the model renders styles or subjects without changing the base model weights. According to the source code, embeddings modify the conditioning phase while hypernetworks patch the diffusion forward pass via sd_hijack_optimizations.py.
How do I interrupt a training job in the AUTOMATIC1111 training tab?
Click the Interrupt button in the UI, which triggers shared.state.interrupt(). This sets a global boolean flag that the training loops in both textual_inversion.py and hypernetwork.py check at the start of every iteration. The loop breaks immediately, performs cleanup, and returns the current training state to the UI.
Where are training checkpoints saved in AUTOMATIC1111?
Embeddings save as .pt or .safetensors files to the directory specified by log_directory (defaulting to the embeddings folder), with filenames containing the step count. Hypernetworks save to the hypernetworks directory defined in the paths configuration. Both respect the save_embedding_every or save_hypernetwork_every parameters to control checkpoint frequency.
Can I train embeddings or hypernetworks without using the Gradio UI?
Yes. Import modules.textual_inversion.textual_inversion.train_embedding or modules.hypernetworks.hypernetwork.train_hypernetwork and call them with the appropriate argument tuple. Ensure shared.sd_model is loaded and shared.cmd_opts.lowvram is False, as the training code explicitly asserts sufficient VRAM availability before beginning optimization.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →