CodeVetter · Repo Unpack · Data flow
AUTOMATIC1111/stable-diffusion-webui
Input boundary is either Gradio component values or pydantic API models (modules/api/models.py). Both converge on a StableDiffusionProcessing dataclass ('p') that is the single mutable carrier through the pipeline: scripts mutate it, prompt parsing expands it, sampling consumes it, and a Processed object carries results back out. Persistence flows: settings → config.json, generated images + infotext → outpath_* dirs, last prompt → data_path/params.txt, checkpoint sha256 cache → cache.json, per-model metadata → <name>.json sidecars.
- UI path: Gradio button handlers call modules/txt2img.py or modules/img2img.py which build StableDiffusionProcessingTxt2Img/Img2Img with shared.sd_model and outpath_samples from opts.outdir_* settings, attach p.scripts=scripts_txt2img/img2img runner and p.script_args (the flattened list of all script UI component values).
- API path: text2imgapi/img2imgapi convert the pydantic request via apply_infotext() (merges parsed infotext fields the caller didn't set), init_script_args() (merges script_name + alwayson_scripts args into the flat script_args list at args_from/args_to indexes), then call process_images directly under the shared queue_lock.
- process_images() snapshots overridden opts, applies p.override_settings via opts.set(k,v,is_api=True) — special-casing sd_model_checkpoint (reload_model_weights) and sd_vae (reload_vae_weights) — applies token merging, fixes invalid sampler/scheduler names, then runs process_images_inner() under profiling.Profiler and restores opts in a finally block.
- process_images_inner() order: fix seeds → fill fields from opts → setup_prompts() → load embeddings → p.scripts.process → p.init() once → per-iteration loop: slice prompts/seeds → before_process_batch → parse_extra_network_prompts → extra_networks.activate → process_batch → setup_conds → p.sample() → post_sample → decode_latent_batch → postprocess_batch → per-image face restore/overlay/color-correct → images.save_image → grid assembly → extra_networks.deactivate → Processed.
- Extra-network data flows prompt → p.parse_extra_network_prompts() (extra_networks.parse_prompts strips <name:args> tags) → p.extra_network_data dict → extra_networks.activate(p, data) which calls each registered ExtraNetwork.activate (Lora patches model weights, ExtraNetworkHypernet applies hypernets), deactivated after the batch loop.
- Prompt → conditioning: setup_conds() uses prompt_parser.get_learned_conditioning / get_multicond_learned_conditioning to build ScheduledPromptConditioning lists and MulticondLearnedConditioning, which sd_samplers_cfg_denoiser recombines per step; p.c/p.uc cache positive/negative conditioning (cached_c/cached_uc).
- Latents → pixels: p.sample() returns latent samples; if not already_decoded they are NaN-tested (devices.test_for_nans) then decoded via decode_latent_batch (full VAE or opts.sd_vae_decode_method approximations), converted to uint8 numpy then PIL Image.
- Image persistence: images.save_image(image, p.outpath_samples, ...) writes PNG with infotext in pnginfo 'parameters' chunk (or EXIF for jpg/webp), firing script_callbacks.before_image_saved/image_saved; filenames derive from opts.samples_filename_pattern; the first batch's infotext is also written to data_path/params.txt unless --no-prompt-history.
- Processed object is the output boundary: fields images, infotexts, info, seed, index_of_first_image; UI returns processed.images + processed.js() (JSON for JS gallery metadata); API base64-encodes images via encode_pil_to_base64 preserving PNG metadata/EXIF.
- Settings persistence: Options.save() writes JSON to shared.config_filename on any UI settings change; disabled_extensions/disable_all_extensions live in that file and are read back by launch_utils.list_extensions() at next boot; corrupt configs are quarantined to tmp/config.json.
- Checkpoint identity flows through sha256 hashes computed in modules/hashes.py (cached in cache.json), producing CheckpointInfo.hash/short sha256 used in infotexts ('Model hash'), extra-network metadata, and the API /sdapi/v1/sd-models listing.
- Shared mutable state coordination: shared_state.State owns job_count/job/interrupted/skipped/stopping_generation and server command queue (wait_for_server_command/request_restart); progress.start_task/finish_task and TotalTQDM update the console and /internal/progress endpoint.