AUTOMATIC1111/stable-diffusion-webui
Extra networks
Active contributors: AUTOMATIC1111, w-e-w, missionfloyd, Kohaku-Blueleaf
Purpose
The framework that powers the <lora:name:weight>, <hypernet:name:weight>, and embedding prompt syntaxes. It also powers the card-style browser in the UI that lets users insert these into prompts with a click. Lora is the primary user; hypernetworks and textual-inversion embeddings re-use the same plumbing.
Directory layout
modules/
├── extra_networks.py # the framework: parse, register, activate, deactivate
├── extra_networks_hypernet.py # hypernet implementation
├── ui_extra_networks.py # the browser UI (~830 lines)
├── ui_extra_networks_checkpoints.py
├── ui_extra_networks_checkpoints_user_metadata.py
├── ui_extra_networks_hypernets.py
├── ui_extra_networks_textual_inversion.py
└── ui_extra_networks_user_metadata.py
extensions-builtin/Lora/
├── extra_networks_lora.py # the Lora ExtraNetwork
├── networks.py # patcher: load, apply, undo (729 lines)
├── network_*.py # per-type strategies (lora, hada, lokr, ia3, glora, oft, full, norm)
├── ui_edit_user_metadata.py
├── ui_extra_networks_lora.py
├── lyco_helpers.py # LyCORIS support helpers
├── lora_logger.py
├── lora_patches.py
└── preload.py
javascript/extraNetworks.js # ~970 lines: card filtering, drag-and-drop, searchKey abstractions
| Type | File | Description |
|---|---|---|
ExtraNetwork (base) |
modules/extra_networks.py |
Implement activate(p, params_list) and deactivate(p). |
register_extra_network(en) |
same | Adds the network to the global registry keyed by en.name. |
parse_prompts(prompts) |
same | Strips <type:args> tokens out of prompts, returns the cleaned prompts plus an extra_network_data dict per prompt. |
activate(p, extra_network_data) |
same | Dispatches each entry to the matching ExtraNetwork.activate. |
deactivate(p) |
same | Calls ExtraNetwork.deactivate on every active one — used to undo any in-place patches. |
ExtraNetworkParams |
same | The (items, named) parsed args for a single token. |
ExtraNetworksPage |
modules/ui_extra_networks.py |
Base class for browser tabs (Lora, Embeddings, Hypernet, Checkpoints). |
register_page(page) |
same | Adds a new tab to the right-side browser drawer. |
extra_network_lora |
extensions-builtin/Lora/extra_networks_lora.py |
The Lora ExtraNetwork instance. |
networks.load_networks(names, te_multipliers, unet_multipliers, dyn_dims) |
extensions-builtin/Lora/networks.py |
Loads matching .safetensors from models/Lora/, builds patches, and stores them on the model. |
networks.network_apply_weights(self) / network_restore_weights_from_backup(self) |
same | The actual hot patcher of nn.Linear / nn.Conv2d weights. |
How the prompt syntax works
A prompt like a cat <lora:dog:0.7> sitting <embedding:my_emb> triggers:
graph TD
Prompt --> Parse[extra_networks.parse_prompts]
Parse -->|stripped prompt| Encode[CLIP encode_with_transformer]
Parse -->|extra_network_data| Activate
Activate -->|"lora": [(['dog', '0.7'], {})]| ENL[extra_network_lora.activate]
ENL --> Net[networks.load_networks([(name, 0.7)])]
Net -->|build LoraNetwork modules| Patch[networks.network_apply_weights]
Patch -->|patches every nn.Linear/Conv2d| UNet+TextEnc
Sample[Sampler.sample] --> Forward
Forward --> PatchedUNet
Sample --> Done
Done --> Deactivate[extra_networks.deactivate]
Deactivate --> ENLD[extra_network_lora.deactivate]
ENLD --> Restore[networks.network_restore_weights_from_backup]Two important properties:
- Prompt-stripping happens before encoding. The
<lora:...>text never reaches CLIP. This avoids polluting the conditioning tensor. - Patching is in-place with backups.
networks.network_apply_weightsstoresweight.original/weight.bias_originalon the module before overwriting;network_restore_weights_from_backupputs them back. This avoids extra copies but requires the deactivate path to always run, even on errors.
The Lora subsystem
extensions-builtin/Lora/networks.py is the heaviest single file in the extension tree (~730 lines). It supports multiple network types, picked at load time based on the keys present in the file:
| Strategy | File | Detected by |
|---|---|---|
| Plain LoRA | network_lora.py |
up/down/alpha keys |
| LoHa | network_hada.py |
hada_w1_a etc. |
| LoKr | network_lokr.py |
lokr_w1_a etc. |
| IA3 | network_ia3.py |
on_input key |
| GLoRA | network_glora.py |
a1 / a2 / b1 / b2 |
| Norm | network_norm.py |
norm-layer specific keys |
| Full | network_full.py |
full diff weight (size matches base) |
| OFT | network_oft.py |
oft_blocks |
Each strategy is a Network subclass implementing apply(). The dispatch happens in networks.load_network() based on network_module.
Per-block weights and dynamic ranks
Power users specify per-block weights (<lora:foo:0.7:lbw=A:0.5>) and dynamic LoRA dims (<lora:foo:1:dyn=64>). These come through as the named dict on the ExtraNetworkParams. extra_networks_lora.activate parses them out and forwards them to networks.load_networks.
Caching
Loaded networks live in networks.loaded_networks: list[Network]. The networks.available_networks: dict[str, NetworkOnDisk] is populated at boot (and on /sdapi/v1/refresh-loras etc.) by scanning models/Lora/. Each entry includes the precomputed sha256 (cached in cache.json via modules/hashes.py).
The card browser
ExtraNetworksPage subclasses generate HTML cards for each model file. The browser (in javascript/extraNetworks.js) handles search, sort, and click-to-insert-prompt-token client-side. Server endpoints serve the thumbnails (/sd_extra_networks/thumb) and per-card metadata edits (/sd_extra_networks/metadata).
The Settings page exposes ~20 options in the "Extra Networks" section, mostly cosmetic (card size, page size, default sort).
Integration points
- Add a new extra-network type — implement an
ExtraNetworksubclass and callextra_networks.register_extra_network(my_en)in your script'son_app_started(or at module import). Add a correspondingExtraNetworksPageif you want a browser tab. - Listen for activation — there's no callback, but
extra_network_datais onp.extra_network_dataif your script needs to reason about the active networks. - Trigger a refresh —
/sdapi/v1/refresh-lorasand friends call back intonetworks.list_available_networks().
Entry points for modification
- Performance tuning —
networks.network_apply_weightsis the hot path; v1.10 added "Prevent unnecessary extra networks bias backup" (#15816) as one of six perf PRs that landed together. - Add a new strategy — drop a new
network_*.pyfile with a subclass ofnetwork.NetworkModuleand a detection helper, then add the import tonetworks.py's strategy list. - Fix a Lora that doesn't load —
lora_logger.pywrites tocache.jsonand to a debug log;Settings → Extra Networks → Always show all networks on the Lora pageis useful when filtering hides a candidate.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.
Previous
Script callbacks
Next
Postprocessing