Factory.ai

Open-Source Wikis

/

Stable Diffusion WebUI

/

Systems

/

Extra networks

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, search

Key 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_weights stores weight.original/weight.bias_original on the module before overwriting; network_restore_weights_from_backup puts 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 ExtraNetwork subclass and call extra_networks.register_extra_network(my_en) in your script's on_app_started (or at module import). Add a corresponding ExtraNetworksPage if you want a browser tab.
  • Listen for activation — there's no callback, but extra_network_data is on p.extra_network_data if your script needs to reason about the active networks.
  • Trigger a refresh/sdapi/v1/refresh-loras and friends call back into networks.list_available_networks().

Entry points for modification

  • Performance tuningnetworks.network_apply_weights is 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_*.py file with a subclass of network.NetworkModule and a detection helper, then add the import to networks.py's strategy list.
  • Fix a Lora that doesn't loadlora_logger.py writes to cache.json and to a debug log; Settings → Extra Networks → Always show all networks on the Lora page is 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.

Extra networks – Stable Diffusion WebUI wiki | Factory