Implementation:AUTOMATIC1111 Stable diffusion webui Parse prompts and ExtraNetworkLora
| Knowledge Sources | |
|---|---|
| Domains | Stable Diffusion, LoRA, Prompt Engineering, Text Parsing |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
Concrete tools for parsing inline network tags from generation prompts and activating LoRA networks with the extracted parameters, provided by the AUTOMATIC1111 stable-diffusion-webui repository.
Description
This implementation consists of two cooperating components:
parse_prompts() in modules/extra_networks.py is the entry point for prompt parsing. It accepts a list of prompt strings, scans each for <type:args> tags using the regex r"<(\w+):([^>]+)>", removes matched tags from the prompt text, and collects the extracted parameters into ExtraNetworkParams objects grouped by network type name. Only the extra network data from the first prompt is used (all prompts in a batch share one network configuration).
ExtraNetworkLora.activate() in extensions-builtin/Lora/extra_networks_lora.py is the LoRA-specific handler that receives the parsed parameters. It extracts network names, text encoder multipliers, UNet multipliers, and optional dynamic dimension values from the positional and named arguments, then delegates to networks.load_networks(). It also handles the global sd_lora setting (auto-appending a default LoRA if configured) and writes LoRA hash information into the generation infotext.
Usage
These functions are called automatically during every image generation run. parse_prompts() is invoked by the processing pipeline before text encoding to separate network parameters from the textual prompt. ExtraNetworkLora.activate() is called by the extra networks activation system after parsing is complete. Users do not call these functions directly; they interact with them by writing <lora:name:weight> tags in their prompts.
Code Reference
Source Location
- Repository: stable-diffusion-webui
- File (parse_prompts):
modules/extra_networks.py - Lines: 194-206
- File (ExtraNetworkLora):
extensions-builtin/Lora/extra_networks_lora.py - Lines: 14-56
Signature
# modules/extra_networks.py
def parse_prompts(prompts):
res = []
extra_data = None
for prompt in prompts:
updated_prompt, parsed_extra_data = parse_prompt(prompt)
if extra_data is None:
extra_data = parsed_extra_data
res.append(updated_prompt)
return res, extra_data
# extensions-builtin/Lora/extra_networks_lora.py
class ExtraNetworkLora(extra_networks.ExtraNetwork):
def __init__(self):
super().__init__('lora')
self.errors = {}
def activate(self, p, params_list):
additional = shared.opts.sd_lora
self.errors.clear()
if additional != "None" and additional in networks.available_networks and \
not any(x for x in params_list if x.items[0] == additional):
p.all_prompts = [x + f"<lora:{additional}:{shared.opts.extra_networks_default_multiplier}>"
for x in p.all_prompts]
params_list.append(extra_networks.ExtraNetworkParams(
items=[additional, shared.opts.extra_networks_default_multiplier]))
names = []
te_multipliers = []
unet_multipliers = []
dyn_dims = []
for params in params_list:
assert params.items
names.append(params.positional[0])
te_multiplier = float(params.positional[1]) if len(params.positional) > 1 else 1.0
te_multiplier = float(params.named.get("te", te_multiplier))
unet_multiplier = float(params.positional[2]) if len(params.positional) > 2 else te_multiplier
unet_multiplier = float(params.named.get("unet", unet_multiplier))
dyn_dim = int(params.positional[3]) if len(params.positional) > 3 else None
dyn_dim = int(params.named["dyn"]) if "dyn" in params.named else dyn_dim
te_multipliers.append(te_multiplier)
unet_multipliers.append(unet_multiplier)
dyn_dims.append(dyn_dim)
networks.load_networks(names, te_multipliers, unet_multipliers, dyn_dims)
...
def deactivate(self, p):
if self.errors:
p.comment("Networks with errors: " + ", ".join(f"{k} ({v})" for k, v in self.errors.items()))
self.errors.clear()
Import
from modules.extra_networks import parse_prompts, ExtraNetworkParams
from extra_networks_lora import ExtraNetworkLora
I/O Contract
Inputs
parse_prompts:
| Name | Type | Required | Description |
|---|---|---|---|
| prompts | list[str] | Yes | List of prompt strings potentially containing <type:args> tags
|
ExtraNetworkLora.activate:
| Name | Type | Required | Description |
|---|---|---|---|
| p | StableDiffusionProcessing | Yes | The current processing object containing prompt data and generation parameters |
| params_list | list[ExtraNetworkParams] | Yes | List of parsed parameter objects for LoRA networks; empty list means deactivate all |
Outputs
parse_prompts:
| Name | Type | Description |
|---|---|---|
| return | tuple[list[str], defaultdict[str, list[ExtraNetworkParams]]] | A tuple of (cleaned prompts with tags removed, dict mapping network type names to lists of ExtraNetworkParams) |
ExtraNetworkLora.activate:
| Name | Type | Description |
|---|---|---|
| return | None | Side effect: loads/unloads networks, sets multipliers, updates p.extra_generation_params with LoRA hashes
|
Usage Examples
Basic Usage
from modules.extra_networks import parse_prompts
prompts = [
"1girl, masterpiece <lora:character:0.8> <lora:style:0.6:0.4>",
"1boy, best quality <lora:character:0.8> <lora:style:0.6:0.4>",
]
cleaned_prompts, extra_data = parse_prompts(prompts)
# cleaned_prompts = ["1girl, masterpiece ", "1boy, best quality "]
# extra_data = {
# "lora": [
# ExtraNetworkParams(items=["character", "0.8"]),
# ExtraNetworkParams(items=["style", "0.6", "0.4"]),
# ]
# }
Weight Parsing Detail
# Single weight: applies to both TE and UNet
# <lora:name:0.8>
# -> te_multiplier=0.8, unet_multiplier=0.8
# Split weights: separate TE and UNet
# <lora:name:0.8:0.4>
# -> te_multiplier=0.8, unet_multiplier=0.4
# Named parameters override positional
# <lora:name:0.8:te=0.5:unet=0.3>
# -> te_multiplier=0.5, unet_multiplier=0.3
# Dynamic dimension
# <lora:name:1.0:1.0:128>
# -> te_multiplier=1.0, unet_multiplier=1.0, dyn_dim=128