libcom 0.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- libcom/__init__.py +23 -0
- libcom/color_transfer/__init__.py +3 -0
- libcom/color_transfer/reinhard.py +57 -0
- libcom/fopa_heat_map/__init__.py +4 -0
- libcom/fopa_heat_map/fopa_heat_map.py +212 -0
- libcom/fopa_heat_map/source/__init__.py +0 -0
- libcom/fopa_heat_map/source/backbone/ResNet.py +229 -0
- libcom/fopa_heat_map/source/backbone/__init__.py +0 -0
- libcom/fopa_heat_map/source/data/OBdataset.py +292 -0
- libcom/fopa_heat_map/source/data/__init__.py +0 -0
- libcom/fopa_heat_map/source/data/all_transforms.py +25 -0
- libcom/fopa_heat_map/source/network/BaseBlocks.py +26 -0
- libcom/fopa_heat_map/source/network/DynamicModules.py +43 -0
- libcom/fopa_heat_map/source/network/ObPlaNet_simple.py +112 -0
- libcom/fopa_heat_map/source/network/__init__.py +1 -0
- libcom/fopa_heat_map/source/network/tensor_ops.py +37 -0
- libcom/fopa_heat_map/source/prepare_multi_fg_scales.py +85 -0
- libcom/fos_score/__init__.py +4 -0
- libcom/fos_score/fos_score_prediction.py +218 -0
- libcom/fos_score/source/__init__.py +0 -0
- libcom/fos_score/source/config/__init__.py +1 -0
- libcom/fos_score/source/config/config.py +68 -0
- libcom/fos_score/source/config/config.sfosd.yaml +43 -0
- libcom/fos_score/source/config/config_rfosd.yaml +43 -0
- libcom/fos_score/source/loss_function.py +118 -0
- libcom/fos_score/source/networks.py +355 -0
- libcom/harmony_score/__init__.py +3 -0
- libcom/harmony_score/harmony_score_prediction.py +119 -0
- libcom/harmony_score/source/__init__.py +0 -0
- libcom/harmony_score/source/bargainnet.py +226 -0
- libcom/image_harmonization/__init__.py +4 -0
- libcom/image_harmonization/image_harmonization.py +193 -0
- libcom/image_harmonization/source/__init__.py +0 -0
- libcom/image_harmonization/source/functions.py +747 -0
- libcom/image_harmonization/source/pct_net.py +85 -0
- libcom/image_harmonization/source/src/__init__.py +0 -0
- libcom/image_harmonization/source/src/lbm/__init__.py +0 -0
- libcom/image_harmonization/source/src/lbm/config.py +141 -0
- libcom/image_harmonization/source/src/lbm/data/__init__.py +62 -0
- libcom/image_harmonization/source/src/lbm/data/datasets/__init__.py +9 -0
- libcom/image_harmonization/source/src/lbm/data/datasets/collation_fn.py +41 -0
- libcom/image_harmonization/source/src/lbm/data/datasets/dataset.py +243 -0
- libcom/image_harmonization/source/src/lbm/data/datasets/datasets_config.py +42 -0
- libcom/image_harmonization/source/src/lbm/data/filters/__init__.py +12 -0
- libcom/image_harmonization/source/src/lbm/data/filters/base.py +21 -0
- libcom/image_harmonization/source/src/lbm/data/filters/filter_wrapper.py +36 -0
- libcom/image_harmonization/source/src/lbm/data/filters/filters.py +33 -0
- libcom/image_harmonization/source/src/lbm/data/filters/filters_config.py +32 -0
- libcom/image_harmonization/source/src/lbm/data/mappers/__init__.py +19 -0
- libcom/image_harmonization/source/src/lbm/data/mappers/base.py +26 -0
- libcom/image_harmonization/source/src/lbm/data/mappers/mappers.py +135 -0
- libcom/image_harmonization/source/src/lbm/data/mappers/mappers_config.py +109 -0
- libcom/image_harmonization/source/src/lbm/data/mappers/mappers_wrapper.py +31 -0
- libcom/image_harmonization/source/src/lbm/inference/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/inference/inference.py +70 -0
- libcom/image_harmonization/source/src/lbm/inference/utils.py +222 -0
- libcom/image_harmonization/source/src/lbm/models/__init__.py +0 -0
- libcom/image_harmonization/source/src/lbm/models/base/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/models/base/base_model.py +66 -0
- libcom/image_harmonization/source/src/lbm/models/base/model_config.py +8 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/base/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/base/base_conditioner.py +60 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/base/base_conditioner_config.py +27 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/conditioners_wrapper.py +114 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/latents_concat/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/latents_concat/latents_concat_embedder_config.py +31 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/latents_concat/latents_concat_embedder_model.py +80 -0
- libcom/image_harmonization/source/src/lbm/models/lbm/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/models/lbm/lbm_config.py +101 -0
- libcom/image_harmonization/source/src/lbm/models/lbm/lbm_model.py +359 -0
- libcom/image_harmonization/source/src/lbm/models/unets/__init__.py +14 -0
- libcom/image_harmonization/source/src/lbm/models/unets/unet.py +148 -0
- libcom/image_harmonization/source/src/lbm/models/utils.py +377 -0
- libcom/image_harmonization/source/src/lbm/models/vae/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/models/vae/autoencoderKL.py +136 -0
- libcom/image_harmonization/source/src/lbm/models/vae/autoencoderKL_config.py +27 -0
- libcom/image_harmonization/source/src/lbm/trainer/__init__.py +85 -0
- libcom/image_harmonization/source/src/lbm/trainer/loggers.py +324 -0
- libcom/image_harmonization/source/src/lbm/trainer/trainer.py +199 -0
- libcom/image_harmonization/source/src/lbm/trainer/training_config.py +82 -0
- libcom/image_harmonization/source/src/lbm/trainer/utils.py +193 -0
- libcom/inharmonious_region_localization/__init__.py +4 -0
- libcom/inharmonious_region_localization/inharmonious_region_localization.py +97 -0
- libcom/inharmonious_region_localization/source/__init__.py +0 -0
- libcom/inharmonious_region_localization/source/blocks.py +368 -0
- libcom/inharmonious_region_localization/source/functions.py +679 -0
- libcom/inharmonious_region_localization/source/madis_net.py +79 -0
- libcom/kontext_blending_harmonization/__init__.py +3 -0
- libcom/kontext_blending_harmonization/kontext_blending_harmonization.py +148 -0
- libcom/kontext_blending_harmonization/source/__init__.py +0 -0
- libcom/kontext_blending_harmonization/source/pipeline.py +1135 -0
- libcom/naive_composition/__init__.py +3 -0
- libcom/naive_composition/generate_composite_image.py +116 -0
- libcom/opa_score/__init__.py +3 -0
- libcom/opa_score/opa_score_prediction.py +101 -0
- libcom/opa_score/source/__init__.py +3 -0
- libcom/opa_score/source/object_place_net.py +55 -0
- libcom/opa_score/source/oblect_place_config.py +66 -0
- libcom/opa_score/source/resnet_4ch.py +213 -0
- libcom/os_insert/__init__.py +3 -0
- libcom/os_insert/diffusers_osinsert/__init__.py +78 -0
- libcom/os_insert/diffusers_osinsert/_patched_pipeline_flux_fill.py +878 -0
- libcom/os_insert/os_insert.py +534 -0
- libcom/os_insert/source/__init__.py +1 -0
- libcom/os_insert/source/ia_utils.py +183 -0
- libcom/os_insert/source/insertanything_infer.py +529 -0
- libcom/os_insert/source/ldm/__init__.py +0 -0
- libcom/os_insert/source/ldm/data/__init__.py +0 -0
- libcom/os_insert/source/ldm/data/base.py +23 -0
- libcom/os_insert/source/ldm/data/datamodule.py +128 -0
- libcom/os_insert/source/ldm/data/imagenet.py +394 -0
- libcom/os_insert/source/ldm/data/lsun.py +92 -0
- libcom/os_insert/source/ldm/data/open_images.py +728 -0
- libcom/os_insert/source/ldm/lr_scheduler.py +98 -0
- libcom/os_insert/source/ldm/models/__init__.py +0 -0
- libcom/os_insert/source/ldm/models/autoencoder.py +443 -0
- libcom/os_insert/source/ldm/models/diffusion/__init__.py +0 -0
- libcom/os_insert/source/ldm/models/diffusion/classifier.py +267 -0
- libcom/os_insert/source/ldm/models/diffusion/ddim.py +263 -0
- libcom/os_insert/source/ldm/models/diffusion/ddpm.py +1417 -0
- libcom/os_insert/source/ldm/models/diffusion/plms.py +252 -0
- libcom/os_insert/source/ldm/modules/__init__.py +0 -0
- libcom/os_insert/source/ldm/modules/attention.py +261 -0
- libcom/os_insert/source/ldm/modules/diffusionmodules/__init__.py +0 -0
- libcom/os_insert/source/ldm/modules/diffusionmodules/model.py +835 -0
- libcom/os_insert/source/ldm/modules/diffusionmodules/openaimodel.py +1108 -0
- libcom/os_insert/source/ldm/modules/diffusionmodules/util.py +267 -0
- libcom/os_insert/source/ldm/modules/distributions/__init__.py +0 -0
- libcom/os_insert/source/ldm/modules/distributions/distributions.py +92 -0
- libcom/os_insert/source/ldm/modules/ema.py +76 -0
- libcom/os_insert/source/ldm/modules/encoders/__init__.py +0 -0
- libcom/os_insert/source/ldm/modules/encoders/modules.py +190 -0
- libcom/os_insert/source/ldm/modules/encoders/xf.py +130 -0
- libcom/os_insert/source/ldm/modules/losses/__init__.py +1 -0
- libcom/os_insert/source/ldm/modules/losses/contperceptual.py +111 -0
- libcom/os_insert/source/ldm/modules/losses/vqperceptual.py +167 -0
- libcom/os_insert/source/ldm/modules/x_transformer.py +641 -0
- libcom/os_insert/source/ldm/util.py +203 -0
- libcom/os_insert/source/objectstitch_data.py +66 -0
- libcom/os_insert/source/objectstitch_infer.py +618 -0
- libcom/os_insert/source/sam_on_objectstitch.py +253 -0
- libcom/os_insert/source/utils.py +41 -0
- libcom/os_insert/source/v1.yaml +108 -0
- libcom/painterly_image_harmonization/__init__.py +4 -0
- libcom/painterly_image_harmonization/painterly_image_harmonization.py +215 -0
- libcom/painterly_image_harmonization/source/PHDNet/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDNet/networks.py +202 -0
- libcom/painterly_image_harmonization/source/PHDNet/phdnet.py +47 -0
- libcom/painterly_image_harmonization/source/PHDNet/phdnet_config.py +18 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/inference_base.py +300 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/lr_scheduler.py +98 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/autoencoder.py +211 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/__init__.py +3 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/ddim.py +336 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/ddpm.py +1400 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/dpm_solver/__init__.py +1 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/dpm_solver/dpm_solver.py +1217 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/dpm_solver/sampler.py +87 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/plms.py +243 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/scheduling_pndm.py +518 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/attention.py +378 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/diffusionmodules/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/diffusionmodules/model.py +857 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/diffusionmodules/openaimodel.py +823 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/diffusionmodules/util.py +270 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/distributions/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/distributions/distributions.py +92 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/ema.py +80 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/encoders/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/encoders/adapter.py +213 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/encoders/modules.py +82 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/__init__.py +1 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/api.py +269 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/api.py +175 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/base_model.py +16 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/blocks.py +342 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/dpt_depth.py +109 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/midas_net.py +76 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/midas_net_custom.py +128 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/transforms.py +234 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/vit.py +491 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/utils.py +189 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/model_edge.py +653 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/api.py +35 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/body.py +209 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/hand.py +75 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/model.py +178 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/util.py +203 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/utils.py +72 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/fusion/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/fusion/dual_encoder_fusion.py +93 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/image_degradation/__init__.py +2 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/image_degradation/bsrgan.py +730 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/image_degradation/bsrgan_light.py +651 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/image_degradation/utils_image.py +916 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/util.py +200 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/stable_diffusion.yaml +75 -0
- libcom/painterly_image_harmonization/source/__init__.py +0 -0
- libcom/reflection_generation/__init__.py +3 -0
- libcom/reflection_generation/reflection_generation.py +174 -0
- libcom/reflection_generation/source/PostProcessModel.py +513 -0
- libcom/reflection_generation/source/__init__.py +0 -0
- libcom/reflection_generation/source/cldm/__init__.py +0 -0
- libcom/reflection_generation/source/cldm/base_network.py +166 -0
- libcom/reflection_generation/source/cldm/cldm.py +509 -0
- libcom/reflection_generation/source/cldm/ddim_hacked.py +317 -0
- libcom/reflection_generation/source/cldm/hack.py +111 -0
- libcom/reflection_generation/source/cldm/logger.py +127 -0
- libcom/reflection_generation/source/cldm/model.py +26 -0
- libcom/reflection_generation/source/cldm_v15.yaml +81 -0
- libcom/reflection_generation/source/cluster_feature.py +109 -0
- libcom/reflection_generation/source/ldm/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/models/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/models/autoencoder.py +219 -0
- libcom/reflection_generation/source/ldm/models/diffusion/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/models/diffusion/attention_processor.py +188 -0
- libcom/reflection_generation/source/ldm/models/diffusion/ddim.py +340 -0
- libcom/reflection_generation/source/ldm/models/diffusion/ddpm.py +1892 -0
- libcom/reflection_generation/source/ldm/models/diffusion/dpm_solver/__init__.py +1 -0
- libcom/reflection_generation/source/ldm/models/diffusion/dpm_solver/dpm_solver.py +1154 -0
- libcom/reflection_generation/source/ldm/models/diffusion/dpm_solver/sampler.py +87 -0
- libcom/reflection_generation/source/ldm/models/diffusion/ip_adapter.py +57 -0
- libcom/reflection_generation/source/ldm/models/diffusion/plms.py +244 -0
- libcom/reflection_generation/source/ldm/models/diffusion/sampling_util.py +22 -0
- libcom/reflection_generation/source/ldm/modules/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/modules/attention.py +341 -0
- libcom/reflection_generation/source/ldm/modules/diffusionmodules/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/modules/diffusionmodules/model.py +852 -0
- libcom/reflection_generation/source/ldm/modules/diffusionmodules/openaimodel.py +786 -0
- libcom/reflection_generation/source/ldm/modules/diffusionmodules/upscaling.py +81 -0
- libcom/reflection_generation/source/ldm/modules/diffusionmodules/util.py +280 -0
- libcom/reflection_generation/source/ldm/modules/distributions/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/modules/distributions/distributions.py +92 -0
- libcom/reflection_generation/source/ldm/modules/ema.py +80 -0
- libcom/reflection_generation/source/ldm/modules/encoders/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/modules/encoders/modules.py +214 -0
- libcom/reflection_generation/source/ldm/modules/image_degradation/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/modules/image_degradation/bsrgan.py +730 -0
- libcom/reflection_generation/source/ldm/modules/image_degradation/bsrgan_light.py +651 -0
- libcom/reflection_generation/source/ldm/modules/image_degradation/utils_image.py +916 -0
- libcom/reflection_generation/source/ldm/util.py +198 -0
- libcom/reflection_generation/source/local_clip.py +749 -0
- libcom/reflection_generation/source/tool_add_control.py +49 -0
- libcom/shadow_generation/__init__.py +3 -0
- libcom/shadow_generation/shadow_generation.py +754 -0
- libcom/shadow_generation/source/PostProcessModel.py +511 -0
- libcom/shadow_generation/source/__init__.py +0 -0
- libcom/shadow_generation/source/attention_processor.py +234 -0
- libcom/shadow_generation/source/cldm/__init__.py +0 -0
- libcom/shadow_generation/source/cldm/base_network.py +166 -0
- libcom/shadow_generation/source/cldm/cldm.py +524 -0
- libcom/shadow_generation/source/cldm/model.py +28 -0
- libcom/shadow_generation/source/ldm/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/models/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/models/autoencoder.py +219 -0
- libcom/shadow_generation/source/ldm/models/diffusion/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/models/diffusion/attention_processor.py +188 -0
- libcom/shadow_generation/source/ldm/models/diffusion/ddim.py +340 -0
- libcom/shadow_generation/source/ldm/models/diffusion/ddpm.py +1893 -0
- libcom/shadow_generation/source/ldm/models/diffusion/dpm_solver/__init__.py +1 -0
- libcom/shadow_generation/source/ldm/models/diffusion/dpm_solver/dpm_solver.py +1154 -0
- libcom/shadow_generation/source/ldm/models/diffusion/dpm_solver/sampler.py +87 -0
- libcom/shadow_generation/source/ldm/models/diffusion/ip_adapter.py +57 -0
- libcom/shadow_generation/source/ldm/models/diffusion/plms.py +244 -0
- libcom/shadow_generation/source/ldm/models/diffusion/sampling_util.py +22 -0
- libcom/shadow_generation/source/ldm/modules/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/modules/attention.py +341 -0
- libcom/shadow_generation/source/ldm/modules/diffusionmodules/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/modules/diffusionmodules/model.py +852 -0
- libcom/shadow_generation/source/ldm/modules/diffusionmodules/openaimodel.py +786 -0
- libcom/shadow_generation/source/ldm/modules/diffusionmodules/upscaling.py +81 -0
- libcom/shadow_generation/source/ldm/modules/diffusionmodules/util.py +270 -0
- libcom/shadow_generation/source/ldm/modules/distributions/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/modules/distributions/distributions.py +92 -0
- libcom/shadow_generation/source/ldm/modules/ema.py +80 -0
- libcom/shadow_generation/source/ldm/modules/encoders/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/modules/encoders/modules.py +214 -0
- libcom/shadow_generation/source/ldm/modules/image_degradation/__init__.py +2 -0
- libcom/shadow_generation/source/ldm/modules/image_degradation/bsrgan.py +730 -0
- libcom/shadow_generation/source/ldm/modules/image_degradation/bsrgan_light.py +651 -0
- libcom/shadow_generation/source/ldm/modules/image_degradation/utils_image.py +916 -0
- libcom/shadow_generation/source/ldm/modules/midas/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/modules/midas/api.py +170 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/base_model.py +16 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/blocks.py +342 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/dpt_depth.py +109 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/midas_net.py +76 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/midas_net_custom.py +128 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/transforms.py +234 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/vit.py +491 -0
- libcom/shadow_generation/source/ldm/modules/midas/utils.py +189 -0
- libcom/shadow_generation/source/ldm/util.py +199 -0
- libcom/utils/__init__.py +0 -0
- libcom/utils/environment.py +12 -0
- libcom/utils/model_download.py +67 -0
- libcom/utils/process_image.py +108 -0
- libcom-0.1.8.dist-info/METADATA +157 -0
- libcom-0.1.8.dist-info/RECORD +310 -0
- libcom-0.1.8.dist-info/WHEEL +5 -0
- libcom-0.1.8.dist-info/licenses/LICENSE +201 -0
- libcom-0.1.8.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1893 @@
|
|
|
1
|
+
"""
|
|
2
|
+
wild mixture of
|
|
3
|
+
https://github.com/lucidrains/denoising-diffusion-pytorch/blob/7706bdfc6f527f58d33f84b7b522e61e6e3164b3/denoising_diffusion_pytorch/denoising_diffusion_pytorch.py
|
|
4
|
+
https://github.com/openai/improved-diffusion/blob/e94489283bb876ac1477d5dd7709bbbd2d9902ce/improved_diffusion/gaussian_diffusion.py
|
|
5
|
+
https://github.com/CompVis/taming-transformers
|
|
6
|
+
-- merci
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from diffusers import StableDiffusionPipeline
|
|
10
|
+
import torch
|
|
11
|
+
import torch.nn as nn
|
|
12
|
+
import numpy as np
|
|
13
|
+
import pytorch_lightning as pl
|
|
14
|
+
from torch.optim.lr_scheduler import LambdaLR
|
|
15
|
+
from einops import rearrange, repeat
|
|
16
|
+
from contextlib import contextmanager, nullcontext
|
|
17
|
+
from functools import partial
|
|
18
|
+
import itertools
|
|
19
|
+
from tqdm import tqdm
|
|
20
|
+
from torchvision.utils import make_grid
|
|
21
|
+
from pytorch_lightning.utilities import rank_zero_only
|
|
22
|
+
from omegaconf import ListConfig
|
|
23
|
+
import torch.nn.functional as F
|
|
24
|
+
from libcom.shadow_generation.source.ldm.util import log_txt_as_img, exists, default, ismap, isimage, mean_flat, count_params, instantiate_from_config
|
|
25
|
+
from libcom.shadow_generation.source.ldm.modules.ema import LitEma
|
|
26
|
+
from libcom.shadow_generation.source.ldm.modules.distributions.distributions import normal_kl, DiagonalGaussianDistribution
|
|
27
|
+
from libcom.shadow_generation.source.ldm.models.autoencoder import IdentityFirstStage, AutoencoderKL
|
|
28
|
+
from libcom.shadow_generation.source.ldm.modules.diffusionmodules.util import make_beta_schedule, extract_into_tensor, noise_like
|
|
29
|
+
from libcom.shadow_generation.source.ldm.models.diffusion.ddim import DDIMSampler
|
|
30
|
+
from diffusers import AutoencoderKL, DDPMScheduler, UNet2DConditionModel
|
|
31
|
+
from .attention_processor import IPAttnProcessor, AttnProcessor
|
|
32
|
+
from .ip_adapter import IPAdapter, ImageProjModel
|
|
33
|
+
|
|
34
|
+
__conditioning_keys__ = {'concat': 'c_concat',
|
|
35
|
+
'crossattn': 'c_crossattn',
|
|
36
|
+
'adm': 'y'}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def disabled_train(self, mode=True):
|
|
40
|
+
"""Overwrite model.train with this function to make sure train/eval mode
|
|
41
|
+
does not change anymore."""
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def uniform_on_device(r1, r2, shape, device):
|
|
46
|
+
return (r1 - r2) * torch.rand(*shape, device=device) + r2
|
|
47
|
+
|
|
48
|
+
class DiceLoss(nn.Module):
|
|
49
|
+
def __init__(self, smooth=1):
|
|
50
|
+
super(DiceLoss, self).__init__()
|
|
51
|
+
self.smooth = smooth
|
|
52
|
+
|
|
53
|
+
def forward(self, preds, targets):
|
|
54
|
+
preds = preds.contiguous()
|
|
55
|
+
targets = targets.contiguous()
|
|
56
|
+
|
|
57
|
+
intersection = (preds * targets).sum(dim=2).sum(dim=2)
|
|
58
|
+
|
|
59
|
+
loss = (1 - ((2. * intersection + self.smooth) / (preds.sum(dim=2).sum(dim=2) + targets.sum(dim=2).sum(dim=2) + self.smooth)))
|
|
60
|
+
|
|
61
|
+
return loss.mean()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class FocalLoss(nn.Module):
|
|
65
|
+
def __init__(self, alpha=1., gamma=2.):
|
|
66
|
+
super(FocalLoss, self).__init__()
|
|
67
|
+
self.alpha = alpha
|
|
68
|
+
self.gamma = gamma
|
|
69
|
+
|
|
70
|
+
def forward(self, preds, targets):
|
|
71
|
+
BCE_loss = F.binary_cross_entropy(preds, targets, reduction='none')
|
|
72
|
+
pt = torch.exp(-BCE_loss)
|
|
73
|
+
F_loss = self.alpha * (1-pt)**self.gamma * BCE_loss
|
|
74
|
+
return F_loss.mean()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class IoULoss(nn.Module):
|
|
78
|
+
def __init__(self, smooth=1e-6):
|
|
79
|
+
super(IoULoss, self).__init__()
|
|
80
|
+
self.smooth = smooth
|
|
81
|
+
|
|
82
|
+
def forward(self, preds, targets):
|
|
83
|
+
# 预测值通过 sigmoid 函数映射到 [0,1] 区间内
|
|
84
|
+
# preds = torch.sigmoid(preds)
|
|
85
|
+
# 二值化预测值
|
|
86
|
+
preds = (preds > 0.5).float()
|
|
87
|
+
|
|
88
|
+
# 计算交集
|
|
89
|
+
intersection = (preds * targets).sum()
|
|
90
|
+
# 计算并集
|
|
91
|
+
total = (preds + targets).sum()
|
|
92
|
+
union = total - intersection
|
|
93
|
+
|
|
94
|
+
iou = (intersection + self.smooth) / (union + self.smooth)
|
|
95
|
+
return 1 - iou
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class DDPM(pl.LightningModule):
|
|
99
|
+
# classic DDPM with Gaussian diffusion, in image space
|
|
100
|
+
def __init__(self,
|
|
101
|
+
unet_config,
|
|
102
|
+
timesteps=1000,
|
|
103
|
+
beta_schedule="linear",
|
|
104
|
+
loss_type="l2",
|
|
105
|
+
ckpt_path=None,
|
|
106
|
+
ignore_keys=[],
|
|
107
|
+
load_only_unet=False,
|
|
108
|
+
monitor="val/loss",
|
|
109
|
+
use_ema=True,
|
|
110
|
+
first_stage_key="image",
|
|
111
|
+
image_size=256,
|
|
112
|
+
channels=3,
|
|
113
|
+
log_every_t=100,
|
|
114
|
+
clip_denoised=True,
|
|
115
|
+
linear_start=1e-4,
|
|
116
|
+
linear_end=2e-2,
|
|
117
|
+
cosine_s=8e-3,
|
|
118
|
+
given_betas=None,
|
|
119
|
+
original_elbo_weight=0.,
|
|
120
|
+
v_posterior=0., # weight for choosing posterior variance as sigma = (1-v) * beta_tilde + v * beta
|
|
121
|
+
l_simple_weight=1.,
|
|
122
|
+
conditioning_key=None,
|
|
123
|
+
parameterization="eps", # all assuming fixed variance schedules
|
|
124
|
+
scheduler_config=None,
|
|
125
|
+
use_positional_encodings=False,
|
|
126
|
+
learn_logvar=False,
|
|
127
|
+
logvar_init=0.,
|
|
128
|
+
make_it_fit=False,
|
|
129
|
+
ucg_training=None,
|
|
130
|
+
reset_ema=False,
|
|
131
|
+
reset_num_ema_updates=False,
|
|
132
|
+
):
|
|
133
|
+
super().__init__()
|
|
134
|
+
assert parameterization in ["eps", "x0", "v"], 'currently only supporting "eps" and "x0" and "v"'
|
|
135
|
+
self.parameterization = parameterization
|
|
136
|
+
print(f"{self.__class__.__name__}: Running in {self.parameterization}-prediction mode")
|
|
137
|
+
self.cond_stage_model = None
|
|
138
|
+
self.clip_denoised = clip_denoised
|
|
139
|
+
self.log_every_t = log_every_t
|
|
140
|
+
self.first_stage_key = first_stage_key
|
|
141
|
+
self.image_size = image_size # try conv?
|
|
142
|
+
self.channels = channels
|
|
143
|
+
self.use_positional_encodings = use_positional_encodings
|
|
144
|
+
self.model = DiffusionWrapper(unet_config, conditioning_key)
|
|
145
|
+
count_params(self.model, verbose=True)
|
|
146
|
+
self.use_ema = use_ema
|
|
147
|
+
if self.use_ema:
|
|
148
|
+
self.model_ema = LitEma(self.model)
|
|
149
|
+
print(f"Keeping EMAs of {len(list(self.model_ema.buffers()))}.")
|
|
150
|
+
|
|
151
|
+
self.use_scheduler = scheduler_config is not None
|
|
152
|
+
if self.use_scheduler:
|
|
153
|
+
self.scheduler_config = scheduler_config
|
|
154
|
+
|
|
155
|
+
self.v_posterior = v_posterior
|
|
156
|
+
self.original_elbo_weight = original_elbo_weight
|
|
157
|
+
self.l_simple_weight = l_simple_weight
|
|
158
|
+
|
|
159
|
+
if monitor is not None:
|
|
160
|
+
self.monitor = monitor
|
|
161
|
+
self.make_it_fit = make_it_fit
|
|
162
|
+
if reset_ema: assert exists(ckpt_path)
|
|
163
|
+
if ckpt_path is not None:
|
|
164
|
+
self.init_from_ckpt(ckpt_path, ignore_keys=ignore_keys, only_model=load_only_unet)
|
|
165
|
+
if reset_ema:
|
|
166
|
+
assert self.use_ema
|
|
167
|
+
print(f"Resetting ema to pure model weights. This is useful when restoring from an ema-only checkpoint.")
|
|
168
|
+
self.model_ema = LitEma(self.model)
|
|
169
|
+
if reset_num_ema_updates:
|
|
170
|
+
print(" +++++++++++ WARNING: RESETTING NUM_EMA UPDATES TO ZERO +++++++++++ ")
|
|
171
|
+
assert self.use_ema
|
|
172
|
+
self.model_ema.reset_num_updates()
|
|
173
|
+
|
|
174
|
+
self.register_schedule(given_betas=given_betas, beta_schedule=beta_schedule, timesteps=timesteps,
|
|
175
|
+
linear_start=linear_start, linear_end=linear_end, cosine_s=cosine_s)
|
|
176
|
+
|
|
177
|
+
self.loss_type = loss_type
|
|
178
|
+
|
|
179
|
+
self.learn_logvar = learn_logvar
|
|
180
|
+
logvar = torch.full(fill_value=logvar_init, size=(self.num_timesteps,))
|
|
181
|
+
if self.learn_logvar:
|
|
182
|
+
self.logvar = nn.Parameter(self.logvar, requires_grad=True)
|
|
183
|
+
else:
|
|
184
|
+
self.register_buffer('logvar', logvar)
|
|
185
|
+
|
|
186
|
+
self.ucg_training = ucg_training or dict()
|
|
187
|
+
if self.ucg_training:
|
|
188
|
+
self.ucg_prng = np.random.RandomState()
|
|
189
|
+
|
|
190
|
+
def register_schedule(self, given_betas=None, beta_schedule="linear", timesteps=1000,
|
|
191
|
+
linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3):
|
|
192
|
+
if exists(given_betas):
|
|
193
|
+
betas = given_betas
|
|
194
|
+
else:
|
|
195
|
+
betas = make_beta_schedule(beta_schedule, timesteps, linear_start=linear_start, linear_end=linear_end,
|
|
196
|
+
cosine_s=cosine_s)
|
|
197
|
+
alphas = 1. - betas
|
|
198
|
+
alphas_cumprod = np.cumprod(alphas, axis=0)
|
|
199
|
+
alphas_cumprod_prev = np.append(1., alphas_cumprod[:-1])
|
|
200
|
+
|
|
201
|
+
timesteps, = betas.shape
|
|
202
|
+
self.num_timesteps = int(timesteps)
|
|
203
|
+
self.linear_start = linear_start
|
|
204
|
+
self.linear_end = linear_end
|
|
205
|
+
assert alphas_cumprod.shape[0] == self.num_timesteps, 'alphas have to be defined for each timestep'
|
|
206
|
+
|
|
207
|
+
to_torch = partial(torch.tensor, dtype=torch.float32)
|
|
208
|
+
|
|
209
|
+
self.register_buffer('betas', to_torch(betas))
|
|
210
|
+
self.register_buffer('alphas_cumprod', to_torch(alphas_cumprod))
|
|
211
|
+
self.register_buffer('alphas_cumprod_prev', to_torch(alphas_cumprod_prev))
|
|
212
|
+
|
|
213
|
+
# calculations for diffusion q(x_t | x_{t-1}) and others
|
|
214
|
+
self.register_buffer('sqrt_alphas_cumprod', to_torch(np.sqrt(alphas_cumprod)))
|
|
215
|
+
self.register_buffer('sqrt_one_minus_alphas_cumprod', to_torch(np.sqrt(1. - alphas_cumprod)))
|
|
216
|
+
self.register_buffer('log_one_minus_alphas_cumprod', to_torch(np.log(1. - alphas_cumprod)))
|
|
217
|
+
self.register_buffer('sqrt_recip_alphas_cumprod', to_torch(np.sqrt(1. / alphas_cumprod)))
|
|
218
|
+
self.register_buffer('sqrt_recipm1_alphas_cumprod', to_torch(np.sqrt(1. / alphas_cumprod - 1)))
|
|
219
|
+
|
|
220
|
+
# calculations for posterior q(x_{t-1} | x_t, x_0)
|
|
221
|
+
posterior_variance = (1 - self.v_posterior) * betas * (1. - alphas_cumprod_prev) / (
|
|
222
|
+
1. - alphas_cumprod) + self.v_posterior * betas
|
|
223
|
+
# above: equal to 1. / (1. / (1. - alpha_cumprod_tm1) + alpha_t / beta_t)
|
|
224
|
+
self.register_buffer('posterior_variance', to_torch(posterior_variance))
|
|
225
|
+
# below: log calculation clipped because the posterior variance is 0 at the beginning of the diffusion chain
|
|
226
|
+
self.register_buffer('posterior_log_variance_clipped', to_torch(np.log(np.maximum(posterior_variance, 1e-20))))
|
|
227
|
+
self.register_buffer('posterior_mean_coef1', to_torch(
|
|
228
|
+
betas * np.sqrt(alphas_cumprod_prev) / (1. - alphas_cumprod)))
|
|
229
|
+
self.register_buffer('posterior_mean_coef2', to_torch(
|
|
230
|
+
(1. - alphas_cumprod_prev) * np.sqrt(alphas) / (1. - alphas_cumprod)))
|
|
231
|
+
|
|
232
|
+
if self.parameterization == "eps":
|
|
233
|
+
lvlb_weights = self.betas ** 2 / (
|
|
234
|
+
2 * self.posterior_variance * to_torch(alphas) * (1 - self.alphas_cumprod))
|
|
235
|
+
elif self.parameterization == "x0":
|
|
236
|
+
lvlb_weights = 0.5 * np.sqrt(torch.Tensor(alphas_cumprod)) / (2. * 1 - torch.Tensor(alphas_cumprod))
|
|
237
|
+
elif self.parameterization == "v":
|
|
238
|
+
lvlb_weights = torch.ones_like(self.betas ** 2 / (
|
|
239
|
+
2 * self.posterior_variance * to_torch(alphas) * (1 - self.alphas_cumprod)))
|
|
240
|
+
else:
|
|
241
|
+
raise NotImplementedError("mu not supported")
|
|
242
|
+
lvlb_weights[0] = lvlb_weights[1]
|
|
243
|
+
self.register_buffer('lvlb_weights', lvlb_weights, persistent=False)
|
|
244
|
+
assert not torch.isnan(self.lvlb_weights).all()
|
|
245
|
+
|
|
246
|
+
@contextmanager
|
|
247
|
+
def ema_scope(self, context=None):
|
|
248
|
+
if self.use_ema:
|
|
249
|
+
self.model_ema.store(self.model.parameters())
|
|
250
|
+
self.model_ema.copy_to(self.model)
|
|
251
|
+
if context is not None:
|
|
252
|
+
print(f"{context}: Switched to EMA weights")
|
|
253
|
+
try:
|
|
254
|
+
yield None
|
|
255
|
+
finally:
|
|
256
|
+
if self.use_ema:
|
|
257
|
+
self.model_ema.restore(self.model.parameters())
|
|
258
|
+
if context is not None:
|
|
259
|
+
print(f"{context}: Restored training weights")
|
|
260
|
+
|
|
261
|
+
@torch.no_grad()
|
|
262
|
+
def init_from_ckpt(self, path, ignore_keys=list(), only_model=False):
|
|
263
|
+
sd = torch.load(path, map_location="cpu")
|
|
264
|
+
if "state_dict" in list(sd.keys()):
|
|
265
|
+
sd = sd["state_dict"]
|
|
266
|
+
keys = list(sd.keys())
|
|
267
|
+
for k in keys:
|
|
268
|
+
for ik in ignore_keys:
|
|
269
|
+
if k.startswith(ik):
|
|
270
|
+
print("Deleting key {} from state_dict.".format(k))
|
|
271
|
+
del sd[k]
|
|
272
|
+
if self.make_it_fit:
|
|
273
|
+
n_params = len([name for name, _ in
|
|
274
|
+
itertools.chain(self.named_parameters(),
|
|
275
|
+
self.named_buffers())])
|
|
276
|
+
for name, param in tqdm(
|
|
277
|
+
itertools.chain(self.named_parameters(),
|
|
278
|
+
self.named_buffers()),
|
|
279
|
+
desc="Fitting old weights to new weights",
|
|
280
|
+
total=n_params
|
|
281
|
+
):
|
|
282
|
+
if not name in sd:
|
|
283
|
+
continue
|
|
284
|
+
old_shape = sd[name].shape
|
|
285
|
+
new_shape = param.shape
|
|
286
|
+
assert len(old_shape) == len(new_shape)
|
|
287
|
+
if len(new_shape) > 2:
|
|
288
|
+
# we only modify first two axes
|
|
289
|
+
assert new_shape[2:] == old_shape[2:]
|
|
290
|
+
# assumes first axis corresponds to output dim
|
|
291
|
+
if not new_shape == old_shape:
|
|
292
|
+
new_param = param.clone()
|
|
293
|
+
old_param = sd[name]
|
|
294
|
+
if len(new_shape) == 1:
|
|
295
|
+
for i in range(new_param.shape[0]):
|
|
296
|
+
new_param[i] = old_param[i % old_shape[0]]
|
|
297
|
+
elif len(new_shape) >= 2:
|
|
298
|
+
for i in range(new_param.shape[0]):
|
|
299
|
+
for j in range(new_param.shape[1]):
|
|
300
|
+
new_param[i, j] = old_param[i % old_shape[0], j % old_shape[1]]
|
|
301
|
+
|
|
302
|
+
n_used_old = torch.ones(old_shape[1])
|
|
303
|
+
for j in range(new_param.shape[1]):
|
|
304
|
+
n_used_old[j % old_shape[1]] += 1
|
|
305
|
+
n_used_new = torch.zeros(new_shape[1])
|
|
306
|
+
for j in range(new_param.shape[1]):
|
|
307
|
+
n_used_new[j] = n_used_old[j % old_shape[1]]
|
|
308
|
+
|
|
309
|
+
n_used_new = n_used_new[None, :]
|
|
310
|
+
while len(n_used_new.shape) < len(new_shape):
|
|
311
|
+
n_used_new = n_used_new.unsqueeze(-1)
|
|
312
|
+
new_param /= n_used_new
|
|
313
|
+
|
|
314
|
+
sd[name] = new_param
|
|
315
|
+
|
|
316
|
+
missing, unexpected = self.load_state_dict(sd, strict=False) if not only_model else self.model.load_state_dict(
|
|
317
|
+
sd, strict=False)
|
|
318
|
+
print(f"Restored from {path} with {len(missing)} missing and {len(unexpected)} unexpected keys")
|
|
319
|
+
if len(missing) > 0:
|
|
320
|
+
print(f"Missing Keys:\n {missing}")
|
|
321
|
+
if len(unexpected) > 0:
|
|
322
|
+
print(f"\nUnexpected Keys:\n {unexpected}")
|
|
323
|
+
|
|
324
|
+
def q_mean_variance(self, x_start, t):
|
|
325
|
+
"""
|
|
326
|
+
Get the distribution q(x_t | x_0).
|
|
327
|
+
:param x_start: the [N x C x ...] tensor of noiseless inputs.
|
|
328
|
+
:param t: the number of diffusion steps (minus 1). Here, 0 means one step.
|
|
329
|
+
:return: A tuple (mean, variance, log_variance), all of x_start's shape.
|
|
330
|
+
"""
|
|
331
|
+
mean = (extract_into_tensor(self.sqrt_alphas_cumprod, t, x_start.shape) * x_start)
|
|
332
|
+
variance = extract_into_tensor(1.0 - self.alphas_cumprod, t, x_start.shape)
|
|
333
|
+
log_variance = extract_into_tensor(self.log_one_minus_alphas_cumprod, t, x_start.shape)
|
|
334
|
+
return mean, variance, log_variance
|
|
335
|
+
|
|
336
|
+
def predict_start_from_noise(self, x_t, t, noise):
|
|
337
|
+
return (
|
|
338
|
+
extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x_t.shape) * x_t -
|
|
339
|
+
extract_into_tensor(self.sqrt_recipm1_alphas_cumprod, t, x_t.shape) * noise
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
def predict_start_from_z_and_v(self, x_t, t, v):
|
|
343
|
+
# self.register_buffer('sqrt_alphas_cumprod', to_torch(np.sqrt(alphas_cumprod)))
|
|
344
|
+
# self.register_buffer('sqrt_one_minus_alphas_cumprod', to_torch(np.sqrt(1. - alphas_cumprod)))
|
|
345
|
+
return (
|
|
346
|
+
extract_into_tensor(self.sqrt_alphas_cumprod, t, x_t.shape) * x_t -
|
|
347
|
+
extract_into_tensor(self.sqrt_one_minus_alphas_cumprod, t, x_t.shape) * v
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
def predict_eps_from_z_and_v(self, x_t, t, v):
|
|
351
|
+
return (
|
|
352
|
+
extract_into_tensor(self.sqrt_alphas_cumprod, t, x_t.shape) * v +
|
|
353
|
+
extract_into_tensor(self.sqrt_one_minus_alphas_cumprod, t, x_t.shape) * x_t
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
def q_posterior(self, x_start, x_t, t):
|
|
357
|
+
posterior_mean = (
|
|
358
|
+
extract_into_tensor(self.posterior_mean_coef1, t, x_t.shape) * x_start +
|
|
359
|
+
extract_into_tensor(self.posterior_mean_coef2, t, x_t.shape) * x_t
|
|
360
|
+
)
|
|
361
|
+
posterior_variance = extract_into_tensor(self.posterior_variance, t, x_t.shape)
|
|
362
|
+
posterior_log_variance_clipped = extract_into_tensor(self.posterior_log_variance_clipped, t, x_t.shape)
|
|
363
|
+
return posterior_mean, posterior_variance, posterior_log_variance_clipped
|
|
364
|
+
|
|
365
|
+
def p_mean_variance(self, x, t, clip_denoised: bool):
|
|
366
|
+
model_out = self.model(x, t)
|
|
367
|
+
if self.parameterization == "eps":
|
|
368
|
+
x_recon = self.predict_start_from_noise(x, t=t, noise=model_out)
|
|
369
|
+
elif self.parameterization == "x0":
|
|
370
|
+
x_recon = model_out
|
|
371
|
+
if clip_denoised:
|
|
372
|
+
x_recon.clamp_(-1., 1.)
|
|
373
|
+
|
|
374
|
+
model_mean, posterior_variance, posterior_log_variance = self.q_posterior(x_start=x_recon, x_t=x, t=t)
|
|
375
|
+
return model_mean, posterior_variance, posterior_log_variance
|
|
376
|
+
|
|
377
|
+
@torch.no_grad()
|
|
378
|
+
def p_sample(self, x, t, clip_denoised=True, repeat_noise=False):
|
|
379
|
+
b, *_, device = *x.shape, x.device
|
|
380
|
+
model_mean, _, model_log_variance = self.p_mean_variance(x=x, t=t, clip_denoised=clip_denoised)
|
|
381
|
+
noise = noise_like(x.shape, device, repeat_noise)
|
|
382
|
+
# no noise when t == 0
|
|
383
|
+
nonzero_mask = (1 - (t == 0).float()).reshape(b, *((1,) * (len(x.shape) - 1)))
|
|
384
|
+
return model_mean + nonzero_mask * (0.5 * model_log_variance).exp() * noise
|
|
385
|
+
|
|
386
|
+
@torch.no_grad()
|
|
387
|
+
def p_sample_loop(self, shape, return_intermediates=False):
|
|
388
|
+
device = self.betas.device
|
|
389
|
+
b = shape[0]
|
|
390
|
+
img = torch.randn(shape, device=device)
|
|
391
|
+
intermediates = [img]
|
|
392
|
+
for i in tqdm(reversed(range(0, self.num_timesteps)), desc='Sampling t', total=self.num_timesteps):
|
|
393
|
+
img = self.p_sample(img, torch.full((b,), i, device=device, dtype=torch.long),
|
|
394
|
+
clip_denoised=self.clip_denoised)
|
|
395
|
+
if i % self.log_every_t == 0 or i == self.num_timesteps - 1:
|
|
396
|
+
intermediates.append(img)
|
|
397
|
+
if return_intermediates:
|
|
398
|
+
return img, intermediates
|
|
399
|
+
return img
|
|
400
|
+
|
|
401
|
+
@torch.no_grad()
|
|
402
|
+
def sample(self, batch_size=16, return_intermediates=False):
|
|
403
|
+
image_size = self.image_size
|
|
404
|
+
channels = self.channels
|
|
405
|
+
return self.p_sample_loop((batch_size, channels, image_size, image_size),
|
|
406
|
+
return_intermediates=return_intermediates)
|
|
407
|
+
|
|
408
|
+
def q_sample(self, x_start, t, noise=None):
|
|
409
|
+
noise = default(noise, lambda: torch.randn_like(x_start))
|
|
410
|
+
return (extract_into_tensor(self.sqrt_alphas_cumprod, t, x_start.shape) * x_start +
|
|
411
|
+
extract_into_tensor(self.sqrt_one_minus_alphas_cumprod, t, x_start.shape) * noise)
|
|
412
|
+
|
|
413
|
+
def get_v(self, x, noise, t):
|
|
414
|
+
return (
|
|
415
|
+
extract_into_tensor(self.sqrt_alphas_cumprod, t, x.shape) * noise -
|
|
416
|
+
extract_into_tensor(self.sqrt_one_minus_alphas_cumprod, t, x.shape) * x
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
def get_loss(self, pred, target, mean=True, mask=None):
|
|
420
|
+
if self.loss_type == 'l1':
|
|
421
|
+
loss = (target - pred).abs()
|
|
422
|
+
if mean:
|
|
423
|
+
loss = loss.mean()
|
|
424
|
+
elif self.loss_type == 'l2':
|
|
425
|
+
if mean:
|
|
426
|
+
loss = torch.nn.functional.mse_loss(target, pred)
|
|
427
|
+
else:
|
|
428
|
+
loss = torch.nn.functional.mse_loss(target, pred, reduction='none')
|
|
429
|
+
else:
|
|
430
|
+
raise NotImplementedError("unknown loss type '{loss_type}'")
|
|
431
|
+
|
|
432
|
+
if mask is not None:
|
|
433
|
+
weights = torch.ones_like(mask)
|
|
434
|
+
weights[mask >= 0.6] = 10
|
|
435
|
+
|
|
436
|
+
loss *= weights[:, None, :, :]
|
|
437
|
+
|
|
438
|
+
return loss
|
|
439
|
+
|
|
440
|
+
def p_losses(self, x_start, t, noise=None):
|
|
441
|
+
noise = default(noise, lambda: torch.randn_like(x_start))
|
|
442
|
+
x_noisy = self.q_sample(x_start=x_start, t=t, noise=noise)
|
|
443
|
+
model_out = self.model(x_noisy, t)
|
|
444
|
+
|
|
445
|
+
loss_dict = {}
|
|
446
|
+
if self.parameterization == "eps":
|
|
447
|
+
target = noise
|
|
448
|
+
elif self.parameterization == "x0":
|
|
449
|
+
target = x_start
|
|
450
|
+
elif self.parameterization == "v":
|
|
451
|
+
target = self.get_v(x_start, noise, t)
|
|
452
|
+
else:
|
|
453
|
+
raise NotImplementedError(f"Parameterization {self.parameterization} not yet supported")
|
|
454
|
+
|
|
455
|
+
loss = self.get_loss(model_out, target, mean=False).mean(dim=[1, 2, 3])
|
|
456
|
+
|
|
457
|
+
log_prefix = 'train' if self.training else 'val'
|
|
458
|
+
|
|
459
|
+
loss_dict.update({f'{log_prefix}/loss_simple': loss.mean()})
|
|
460
|
+
loss_simple = loss.mean() * self.l_simple_weight
|
|
461
|
+
|
|
462
|
+
loss_vlb = (self.lvlb_weights[t] * loss).mean()
|
|
463
|
+
loss_dict.update({f'{log_prefix}/loss_vlb': loss_vlb})
|
|
464
|
+
|
|
465
|
+
loss = loss_simple + self.original_elbo_weight * loss_vlb
|
|
466
|
+
|
|
467
|
+
loss_dict.update({f'{log_prefix}/loss': loss})
|
|
468
|
+
|
|
469
|
+
return loss, loss_dict
|
|
470
|
+
|
|
471
|
+
def forward(self, x, *args, **kwargs):
|
|
472
|
+
# b, c, h, w, device, img_size, = *x.shape, x.device, self.image_size
|
|
473
|
+
# assert h == img_size and w == img_size, f'height and width of image must be {img_size}'
|
|
474
|
+
t = torch.randint(0, self.num_timesteps, (x.shape[0],), device=self.device).long()
|
|
475
|
+
return self.p_losses(x, t, *args, **kwargs)
|
|
476
|
+
|
|
477
|
+
def get_input(self, batch, k):
|
|
478
|
+
x = batch[k]
|
|
479
|
+
if len(x.shape) == 3:
|
|
480
|
+
x = x[..., None]
|
|
481
|
+
x = rearrange(x, 'b h w c -> b c h w')
|
|
482
|
+
x = x.to(memory_format=torch.contiguous_format).float()
|
|
483
|
+
return x
|
|
484
|
+
|
|
485
|
+
def shared_step(self, batch):
|
|
486
|
+
x = self.get_input(batch, self.first_stage_key)
|
|
487
|
+
loss, loss_dict = self(x)
|
|
488
|
+
return loss, loss_dict
|
|
489
|
+
|
|
490
|
+
def training_step(self, batch, batch_idx):
|
|
491
|
+
for k in self.ucg_training:
|
|
492
|
+
p = self.ucg_training[k]["p"]
|
|
493
|
+
val = self.ucg_training[k]["val"]
|
|
494
|
+
if val is None:
|
|
495
|
+
val = ""
|
|
496
|
+
for i in range(len(batch[k])):
|
|
497
|
+
if self.ucg_prng.choice(2, p=[1 - p, p]):
|
|
498
|
+
batch[k][i] = val
|
|
499
|
+
|
|
500
|
+
loss, loss_dict = self.shared_step(batch)
|
|
501
|
+
|
|
502
|
+
self.log_dict(loss_dict, prog_bar=True,
|
|
503
|
+
logger=True, on_step=True, on_epoch=True)
|
|
504
|
+
|
|
505
|
+
self.log("global_step", self.global_step,
|
|
506
|
+
prog_bar=True, logger=True, on_step=True, on_epoch=False)
|
|
507
|
+
|
|
508
|
+
if self.use_scheduler:
|
|
509
|
+
lr = self.optimizers().param_groups[0]['lr']
|
|
510
|
+
self.log('lr_abs', lr, prog_bar=True, logger=True, on_step=True, on_epoch=False)
|
|
511
|
+
|
|
512
|
+
return loss
|
|
513
|
+
|
|
514
|
+
@torch.no_grad()
|
|
515
|
+
def validation_step(self, batch, batch_idx):
|
|
516
|
+
_, loss_dict_no_ema = self.shared_step(batch)
|
|
517
|
+
with self.ema_scope():
|
|
518
|
+
_, loss_dict_ema = self.shared_step(batch)
|
|
519
|
+
loss_dict_ema = {key + '_ema': loss_dict_ema[key] for key in loss_dict_ema}
|
|
520
|
+
self.log_dict(loss_dict_no_ema, prog_bar=False, logger=True, on_step=False, on_epoch=True)
|
|
521
|
+
self.log_dict(loss_dict_ema, prog_bar=False, logger=True, on_step=False, on_epoch=True)
|
|
522
|
+
|
|
523
|
+
def on_train_batch_end(self, *args, **kwargs):
|
|
524
|
+
if self.use_ema:
|
|
525
|
+
self.model_ema(self.model)
|
|
526
|
+
|
|
527
|
+
def _get_rows_from_list(self, samples):
|
|
528
|
+
n_imgs_per_row = len(samples)
|
|
529
|
+
denoise_grid = rearrange(samples, 'n b c h w -> b n c h w')
|
|
530
|
+
denoise_grid = rearrange(denoise_grid, 'b n c h w -> (b n) c h w')
|
|
531
|
+
denoise_grid = make_grid(denoise_grid, nrow=n_imgs_per_row)
|
|
532
|
+
return denoise_grid
|
|
533
|
+
|
|
534
|
+
@torch.no_grad()
|
|
535
|
+
def log_images(self, batch, N=8, n_row=2, sample=True, return_keys=None, **kwargs):
|
|
536
|
+
log = dict()
|
|
537
|
+
x = self.get_input(batch, self.first_stage_key)
|
|
538
|
+
N = min(x.shape[0], N)
|
|
539
|
+
n_row = min(x.shape[0], n_row)
|
|
540
|
+
x = x.to(self.device)[:N]
|
|
541
|
+
log["inputs"] = x
|
|
542
|
+
|
|
543
|
+
# get diffusion row
|
|
544
|
+
diffusion_row = list()
|
|
545
|
+
x_start = x[:n_row]
|
|
546
|
+
|
|
547
|
+
for t in range(self.num_timesteps):
|
|
548
|
+
if t % self.log_every_t == 0 or t == self.num_timesteps - 1:
|
|
549
|
+
t = repeat(torch.tensor([t]), '1 -> b', b=n_row)
|
|
550
|
+
t = t.to(self.device).long()
|
|
551
|
+
noise = torch.randn_like(x_start)
|
|
552
|
+
x_noisy = self.q_sample(x_start=x_start, t=t, noise=noise)
|
|
553
|
+
diffusion_row.append(x_noisy)
|
|
554
|
+
|
|
555
|
+
log["diffusion_row"] = self._get_rows_from_list(diffusion_row)
|
|
556
|
+
|
|
557
|
+
if sample:
|
|
558
|
+
# get denoise row
|
|
559
|
+
with self.ema_scope("Plotting"):
|
|
560
|
+
samples, denoise_row = self.sample(batch_size=N, return_intermediates=True)
|
|
561
|
+
|
|
562
|
+
log["samples"] = samples
|
|
563
|
+
log["denoise_row"] = self._get_rows_from_list(denoise_row)
|
|
564
|
+
|
|
565
|
+
if return_keys:
|
|
566
|
+
if np.intersect1d(list(log.keys()), return_keys).shape[0] == 0:
|
|
567
|
+
return log
|
|
568
|
+
else:
|
|
569
|
+
return {key: log[key] for key in return_keys}
|
|
570
|
+
return log
|
|
571
|
+
|
|
572
|
+
def configure_optimizers(self):
|
|
573
|
+
lr = self.learning_rate
|
|
574
|
+
params = list(self.model.parameters())
|
|
575
|
+
if self.learn_logvar:
|
|
576
|
+
params = params + [self.logvar]
|
|
577
|
+
opt = torch.optim.AdamW(params, lr=lr)
|
|
578
|
+
return opt
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
class LatentDiffusion(DDPM):
|
|
582
|
+
"""main class"""
|
|
583
|
+
|
|
584
|
+
def __init__(self,
|
|
585
|
+
first_stage_config,
|
|
586
|
+
cond_stage_config,
|
|
587
|
+
num_timesteps_cond=None,
|
|
588
|
+
cond_stage_key="image",
|
|
589
|
+
cond_stage_trainable=False,
|
|
590
|
+
concat_mode=True,
|
|
591
|
+
cond_stage_forward=None,
|
|
592
|
+
conditioning_key=None,
|
|
593
|
+
scale_factor=1.0,
|
|
594
|
+
scale_by_std=False,
|
|
595
|
+
force_null_conditioning=False,
|
|
596
|
+
*args, **kwargs):
|
|
597
|
+
self.force_null_conditioning = force_null_conditioning
|
|
598
|
+
self.num_timesteps_cond = default(num_timesteps_cond, 1)
|
|
599
|
+
self.scale_by_std = scale_by_std
|
|
600
|
+
assert self.num_timesteps_cond <= kwargs['timesteps']
|
|
601
|
+
# for backwards compatibility after implementation of DiffusionWrapper
|
|
602
|
+
if conditioning_key is None:
|
|
603
|
+
conditioning_key = 'concat' if concat_mode else 'crossattn'
|
|
604
|
+
if cond_stage_config == '__is_unconditional__' and not self.force_null_conditioning:
|
|
605
|
+
conditioning_key = None
|
|
606
|
+
ckpt_path = kwargs.pop("ckpt_path", None)
|
|
607
|
+
reset_ema = kwargs.pop("reset_ema", False)
|
|
608
|
+
reset_num_ema_updates = kwargs.pop("reset_num_ema_updates", False)
|
|
609
|
+
ignore_keys = kwargs.pop("ignore_keys", [])
|
|
610
|
+
super().__init__(conditioning_key=conditioning_key, *args, **kwargs)
|
|
611
|
+
self.concat_mode = concat_mode
|
|
612
|
+
self.cond_stage_trainable = cond_stage_trainable
|
|
613
|
+
self.cond_stage_key = cond_stage_key
|
|
614
|
+
try:
|
|
615
|
+
self.num_downs = len(first_stage_config.params.ddconfig.ch_mult) - 1
|
|
616
|
+
except:
|
|
617
|
+
self.num_downs = 0
|
|
618
|
+
if not scale_by_std:
|
|
619
|
+
self.scale_factor = scale_factor
|
|
620
|
+
else:
|
|
621
|
+
self.register_buffer('scale_factor', torch.tensor(scale_factor))
|
|
622
|
+
self.instantiate_first_stage(first_stage_config)
|
|
623
|
+
self.instantiate_cond_stage(cond_stage_config)
|
|
624
|
+
self.cond_stage_forward = cond_stage_forward
|
|
625
|
+
self.clip_denoised = False
|
|
626
|
+
self.bbox_tokenizer = None
|
|
627
|
+
|
|
628
|
+
self.restarted_from_ckpt = False
|
|
629
|
+
if ckpt_path is not None:
|
|
630
|
+
self.init_from_ckpt(ckpt_path, ignore_keys)
|
|
631
|
+
self.restarted_from_ckpt = True
|
|
632
|
+
if reset_ema:
|
|
633
|
+
assert self.use_ema
|
|
634
|
+
print(
|
|
635
|
+
f"Resetting ema to pure model weights. This is useful when restoring from an ema-only checkpoint.")
|
|
636
|
+
self.model_ema = LitEma(self.model)
|
|
637
|
+
if reset_num_ema_updates:
|
|
638
|
+
print(" +++++++++++ WARNING: RESETTING NUM_EMA UPDATES TO ZERO +++++++++++ ")
|
|
639
|
+
assert self.use_ema
|
|
640
|
+
self.model_ema.reset_num_updates()
|
|
641
|
+
|
|
642
|
+
def make_cond_schedule(self, ):
|
|
643
|
+
self.cond_ids = torch.full(size=(self.num_timesteps,), fill_value=self.num_timesteps - 1, dtype=torch.long)
|
|
644
|
+
ids = torch.round(torch.linspace(0, self.num_timesteps - 1, self.num_timesteps_cond)).long()
|
|
645
|
+
self.cond_ids[:self.num_timesteps_cond] = ids
|
|
646
|
+
|
|
647
|
+
@rank_zero_only
|
|
648
|
+
@torch.no_grad()
|
|
649
|
+
def on_train_batch_start(self, batch, batch_idx, dataloader_idx): #TODO
|
|
650
|
+
# only for very first batch
|
|
651
|
+
if self.scale_by_std and self.current_epoch == 0 and self.global_step == 0 and batch_idx == 0 and not self.restarted_from_ckpt:
|
|
652
|
+
assert self.scale_factor == 1., 'rather not use custom rescaling and std-rescaling simultaneously'
|
|
653
|
+
# set rescale weight to 1./std of encodings
|
|
654
|
+
print("### USING STD-RESCALING ###")
|
|
655
|
+
x = super().get_input(batch, self.first_stage_key)
|
|
656
|
+
x = x.to(self.device)
|
|
657
|
+
encoder_posterior = self.encode_first_stage(x)
|
|
658
|
+
z = self.get_first_stage_encoding(encoder_posterior).detach()
|
|
659
|
+
del self.scale_factor
|
|
660
|
+
self.register_buffer('scale_factor', 1. / z.flatten().std())
|
|
661
|
+
print(f"setting self.scale_factor to {self.scale_factor}")
|
|
662
|
+
print("### USING STD-RESCALING ###")
|
|
663
|
+
|
|
664
|
+
def register_schedule(self,
|
|
665
|
+
given_betas=None, beta_schedule="linear", timesteps=1000,
|
|
666
|
+
linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3):
|
|
667
|
+
super().register_schedule(given_betas, beta_schedule, timesteps, linear_start, linear_end, cosine_s)
|
|
668
|
+
|
|
669
|
+
self.shorten_cond_schedule = self.num_timesteps_cond > 1
|
|
670
|
+
if self.shorten_cond_schedule:
|
|
671
|
+
self.make_cond_schedule()
|
|
672
|
+
|
|
673
|
+
def instantiate_first_stage(self, config):
|
|
674
|
+
model = instantiate_from_config(config)
|
|
675
|
+
self.first_stage_model = model.eval()
|
|
676
|
+
self.first_stage_model.train = disabled_train
|
|
677
|
+
for param in self.first_stage_model.parameters():
|
|
678
|
+
param.requires_grad = False
|
|
679
|
+
|
|
680
|
+
def instantiate_cond_stage(self, config):
|
|
681
|
+
if not self.cond_stage_trainable:
|
|
682
|
+
if config == "__is_first_stage__":
|
|
683
|
+
print("Using first stage also as cond stage.")
|
|
684
|
+
self.cond_stage_model = self.first_stage_model
|
|
685
|
+
elif config == "__is_unconditional__":
|
|
686
|
+
print(f"Training {self.__class__.__name__} as an unconditional model.")
|
|
687
|
+
self.cond_stage_model = None
|
|
688
|
+
# self.be_unconditional = True
|
|
689
|
+
else:
|
|
690
|
+
model = instantiate_from_config(config)
|
|
691
|
+
self.cond_stage_model = model.eval()
|
|
692
|
+
self.cond_stage_model.train = disabled_train
|
|
693
|
+
for param in self.cond_stage_model.parameters():
|
|
694
|
+
param.requires_grad = False
|
|
695
|
+
else:
|
|
696
|
+
assert config != '__is_first_stage__'
|
|
697
|
+
assert config != '__is_unconditional__'
|
|
698
|
+
model = instantiate_from_config(config)
|
|
699
|
+
self.cond_stage_model = model
|
|
700
|
+
|
|
701
|
+
def _get_denoise_row_from_list(self, samples, desc='', force_no_decoder_quantization=False):
|
|
702
|
+
denoise_row = []
|
|
703
|
+
for zd in tqdm(samples, desc=desc):
|
|
704
|
+
denoise_row.append(self.decode_first_stage(zd.to(self.device),
|
|
705
|
+
force_not_quantize=force_no_decoder_quantization))
|
|
706
|
+
n_imgs_per_row = len(denoise_row)
|
|
707
|
+
denoise_row = torch.stack(denoise_row) # n_log_step, n_row, C, H, W
|
|
708
|
+
denoise_grid = rearrange(denoise_row, 'n b c h w -> b n c h w')
|
|
709
|
+
denoise_grid = rearrange(denoise_grid, 'b n c h w -> (b n) c h w')
|
|
710
|
+
denoise_grid = make_grid(denoise_grid, nrow=n_imgs_per_row)
|
|
711
|
+
return denoise_grid
|
|
712
|
+
|
|
713
|
+
def get_first_stage_encoding(self, encoder_posterior):
|
|
714
|
+
if isinstance(encoder_posterior, DiagonalGaussianDistribution):
|
|
715
|
+
z = encoder_posterior.sample()
|
|
716
|
+
elif isinstance(encoder_posterior, torch.Tensor):
|
|
717
|
+
z = encoder_posterior
|
|
718
|
+
else:
|
|
719
|
+
raise NotImplementedError(f"encoder_posterior of type '{type(encoder_posterior)}' not yet implemented")
|
|
720
|
+
return self.scale_factor * z
|
|
721
|
+
|
|
722
|
+
def get_learned_conditioning(self, c):
|
|
723
|
+
if self.cond_stage_forward is None:
|
|
724
|
+
if hasattr(self.cond_stage_model, 'encode') and callable(self.cond_stage_model.encode):
|
|
725
|
+
c = self.cond_stage_model.encode(c)
|
|
726
|
+
if isinstance(c, DiagonalGaussianDistribution):
|
|
727
|
+
c = c.mode()
|
|
728
|
+
else:
|
|
729
|
+
c = self.cond_stage_model(c)
|
|
730
|
+
else:
|
|
731
|
+
assert hasattr(self.cond_stage_model, self.cond_stage_forward)
|
|
732
|
+
c = getattr(self.cond_stage_model, self.cond_stage_forward)(c)
|
|
733
|
+
return c
|
|
734
|
+
|
|
735
|
+
def meshgrid(self, h, w):
|
|
736
|
+
y = torch.arange(0, h).view(h, 1, 1).repeat(1, w, 1)
|
|
737
|
+
x = torch.arange(0, w).view(1, w, 1).repeat(h, 1, 1)
|
|
738
|
+
|
|
739
|
+
arr = torch.cat([y, x], dim=-1)
|
|
740
|
+
return arr
|
|
741
|
+
|
|
742
|
+
def delta_border(self, h, w):
|
|
743
|
+
"""
|
|
744
|
+
:param h: height
|
|
745
|
+
:param w: width
|
|
746
|
+
:return: normalized distance to image border,
|
|
747
|
+
wtith min distance = 0 at border and max dist = 0.5 at image center
|
|
748
|
+
"""
|
|
749
|
+
lower_right_corner = torch.tensor([h - 1, w - 1]).view(1, 1, 2)
|
|
750
|
+
arr = self.meshgrid(h, w) / lower_right_corner
|
|
751
|
+
dist_left_up = torch.min(arr, dim=-1, keepdims=True)[0]
|
|
752
|
+
dist_right_down = torch.min(1 - arr, dim=-1, keepdims=True)[0]
|
|
753
|
+
edge_dist = torch.min(torch.cat([dist_left_up, dist_right_down], dim=-1), dim=-1)[0]
|
|
754
|
+
return edge_dist
|
|
755
|
+
|
|
756
|
+
def get_weighting(self, h, w, Ly, Lx, device):
|
|
757
|
+
weighting = self.delta_border(h, w)
|
|
758
|
+
weighting = torch.clip(weighting, self.split_input_params["clip_min_weight"],
|
|
759
|
+
self.split_input_params["clip_max_weight"], )
|
|
760
|
+
weighting = weighting.view(1, h * w, 1).repeat(1, 1, Ly * Lx).to(device)
|
|
761
|
+
|
|
762
|
+
if self.split_input_params["tie_braker"]:
|
|
763
|
+
L_weighting = self.delta_border(Ly, Lx)
|
|
764
|
+
L_weighting = torch.clip(L_weighting,
|
|
765
|
+
self.split_input_params["clip_min_tie_weight"],
|
|
766
|
+
self.split_input_params["clip_max_tie_weight"])
|
|
767
|
+
|
|
768
|
+
L_weighting = L_weighting.view(1, 1, Ly * Lx).to(device)
|
|
769
|
+
weighting = weighting * L_weighting
|
|
770
|
+
return weighting
|
|
771
|
+
|
|
772
|
+
def get_fold_unfold(self, x, kernel_size, stride, uf=1, df=1): # todo load once not every time, shorten code
|
|
773
|
+
"""
|
|
774
|
+
:param x: img of size (bs, c, h, w)
|
|
775
|
+
:return: n img crops of size (n, bs, c, kernel_size[0], kernel_size[1])
|
|
776
|
+
"""
|
|
777
|
+
bs, nc, h, w = x.shape
|
|
778
|
+
|
|
779
|
+
# number of crops in image
|
|
780
|
+
Ly = (h - kernel_size[0]) // stride[0] + 1
|
|
781
|
+
Lx = (w - kernel_size[1]) // stride[1] + 1
|
|
782
|
+
|
|
783
|
+
if uf == 1 and df == 1:
|
|
784
|
+
fold_params = dict(kernel_size=kernel_size, dilation=1, padding=0, stride=stride)
|
|
785
|
+
unfold = torch.nn.Unfold(**fold_params)
|
|
786
|
+
|
|
787
|
+
fold = torch.nn.Fold(output_size=x.shape[2:], **fold_params)
|
|
788
|
+
|
|
789
|
+
weighting = self.get_weighting(kernel_size[0], kernel_size[1], Ly, Lx, x.device).to(x.dtype)
|
|
790
|
+
normalization = fold(weighting).view(1, 1, h, w) # normalizes the overlap
|
|
791
|
+
weighting = weighting.view((1, 1, kernel_size[0], kernel_size[1], Ly * Lx))
|
|
792
|
+
|
|
793
|
+
elif uf > 1 and df == 1:
|
|
794
|
+
fold_params = dict(kernel_size=kernel_size, dilation=1, padding=0, stride=stride)
|
|
795
|
+
unfold = torch.nn.Unfold(**fold_params)
|
|
796
|
+
|
|
797
|
+
fold_params2 = dict(kernel_size=(kernel_size[0] * uf, kernel_size[0] * uf),
|
|
798
|
+
dilation=1, padding=0,
|
|
799
|
+
stride=(stride[0] * uf, stride[1] * uf))
|
|
800
|
+
fold = torch.nn.Fold(output_size=(x.shape[2] * uf, x.shape[3] * uf), **fold_params2)
|
|
801
|
+
|
|
802
|
+
weighting = self.get_weighting(kernel_size[0] * uf, kernel_size[1] * uf, Ly, Lx, x.device).to(x.dtype)
|
|
803
|
+
normalization = fold(weighting).view(1, 1, h * uf, w * uf) # normalizes the overlap
|
|
804
|
+
weighting = weighting.view((1, 1, kernel_size[0] * uf, kernel_size[1] * uf, Ly * Lx))
|
|
805
|
+
|
|
806
|
+
elif df > 1 and uf == 1:
|
|
807
|
+
fold_params = dict(kernel_size=kernel_size, dilation=1, padding=0, stride=stride)
|
|
808
|
+
unfold = torch.nn.Unfold(**fold_params)
|
|
809
|
+
|
|
810
|
+
fold_params2 = dict(kernel_size=(kernel_size[0] // df, kernel_size[0] // df),
|
|
811
|
+
dilation=1, padding=0,
|
|
812
|
+
stride=(stride[0] // df, stride[1] // df))
|
|
813
|
+
fold = torch.nn.Fold(output_size=(x.shape[2] // df, x.shape[3] // df), **fold_params2)
|
|
814
|
+
|
|
815
|
+
weighting = self.get_weighting(kernel_size[0] // df, kernel_size[1] // df, Ly, Lx, x.device).to(x.dtype)
|
|
816
|
+
normalization = fold(weighting).view(1, 1, h // df, w // df) # normalizes the overlap
|
|
817
|
+
weighting = weighting.view((1, 1, kernel_size[0] // df, kernel_size[1] // df, Ly * Lx))
|
|
818
|
+
|
|
819
|
+
else:
|
|
820
|
+
raise NotImplementedError
|
|
821
|
+
|
|
822
|
+
return fold, unfold, normalization, weighting
|
|
823
|
+
|
|
824
|
+
@torch.no_grad()
|
|
825
|
+
def get_input(self, batch, k, return_first_stage_outputs=False, force_c_encode=False,
|
|
826
|
+
cond_key=None, return_original_cond=False, bs=None, return_x=False):
|
|
827
|
+
x = super().get_input(batch, k)
|
|
828
|
+
if bs is not None:
|
|
829
|
+
x = x[:bs]
|
|
830
|
+
x = x.to(self.device)
|
|
831
|
+
encoder_posterior = self.encode_first_stage(x)
|
|
832
|
+
z = self.get_first_stage_encoding(encoder_posterior).detach()
|
|
833
|
+
|
|
834
|
+
if self.model.conditioning_key is not None and not self.force_null_conditioning:
|
|
835
|
+
if cond_key is None:
|
|
836
|
+
cond_key = self.cond_stage_key
|
|
837
|
+
if cond_key != self.first_stage_key:
|
|
838
|
+
if cond_key in ['caption', 'coordinates_bbox', "txt"]:
|
|
839
|
+
xc = batch[cond_key]
|
|
840
|
+
elif cond_key in ['class_label', 'cls']:
|
|
841
|
+
xc = batch
|
|
842
|
+
else:
|
|
843
|
+
xc = super().get_input(batch, cond_key).to(self.device)
|
|
844
|
+
else:
|
|
845
|
+
xc = x
|
|
846
|
+
if not self.cond_stage_trainable or force_c_encode:
|
|
847
|
+
if isinstance(xc, dict) or isinstance(xc, list):
|
|
848
|
+
c = self.get_learned_conditioning(xc)
|
|
849
|
+
else:
|
|
850
|
+
c = self.get_learned_conditioning(xc.to(self.device))
|
|
851
|
+
else:
|
|
852
|
+
c = xc
|
|
853
|
+
if bs is not None:
|
|
854
|
+
c = c[:bs]
|
|
855
|
+
|
|
856
|
+
if self.use_positional_encodings:
|
|
857
|
+
pos_x, pos_y = self.compute_latent_shifts(batch)
|
|
858
|
+
ckey = __conditioning_keys__[self.model.conditioning_key]
|
|
859
|
+
c = {ckey: c, 'pos_x': pos_x, 'pos_y': pos_y}
|
|
860
|
+
|
|
861
|
+
else:
|
|
862
|
+
c = None
|
|
863
|
+
xc = None
|
|
864
|
+
if self.use_positional_encodings:
|
|
865
|
+
pos_x, pos_y = self.compute_latent_shifts(batch)
|
|
866
|
+
c = {'pos_x': pos_x, 'pos_y': pos_y}
|
|
867
|
+
out = [z, c]
|
|
868
|
+
if return_first_stage_outputs:
|
|
869
|
+
xrec = self.decode_first_stage(z)
|
|
870
|
+
out.extend([x, xrec])
|
|
871
|
+
if return_x:
|
|
872
|
+
out.extend([x])
|
|
873
|
+
if return_original_cond:
|
|
874
|
+
out.append(xc)
|
|
875
|
+
return out
|
|
876
|
+
|
|
877
|
+
@torch.no_grad()
|
|
878
|
+
def decode_first_stage(self, z, predict_cids=False, force_not_quantize=False):
|
|
879
|
+
if predict_cids:
|
|
880
|
+
if z.dim() == 4:
|
|
881
|
+
z = torch.argmax(z.exp(), dim=1).long()
|
|
882
|
+
z = self.first_stage_model.quantize.get_codebook_entry(z, shape=None)
|
|
883
|
+
z = rearrange(z, 'b h w c -> b c h w').contiguous()
|
|
884
|
+
|
|
885
|
+
z = 1. / self.scale_factor * z
|
|
886
|
+
return self.first_stage_model.decode(z)
|
|
887
|
+
|
|
888
|
+
@torch.no_grad()
|
|
889
|
+
def encode_first_stage(self, x):
|
|
890
|
+
return self.first_stage_model.encode(x)
|
|
891
|
+
|
|
892
|
+
def shared_step(self, batch, **kwargs):
|
|
893
|
+
x, c = self.get_input(batch, self.first_stage_key)
|
|
894
|
+
loss = self(x, c, shadowmask=batch['dilated_shadow_mask'], batch=batch)
|
|
895
|
+
return loss
|
|
896
|
+
|
|
897
|
+
def forward(self, x, c, shadowmask=None, batch=None, *args, **kwargs):
|
|
898
|
+
t = torch.randint(0, self.num_timesteps, (x.shape[0],), device=self.device).long()
|
|
899
|
+
if self.model.conditioning_key is not None:
|
|
900
|
+
assert c is not None
|
|
901
|
+
if self.cond_stage_trainable:
|
|
902
|
+
c = self.get_learned_conditioning(c)
|
|
903
|
+
if self.shorten_cond_schedule: # TODO: drop this option
|
|
904
|
+
tc = self.cond_ids[t].to(self.device)
|
|
905
|
+
c = self.q_sample(x_start=c, t=tc, noise=torch.randn_like(c.float()))
|
|
906
|
+
return self.p_losses(x, c, t, shadowmask=shadowmask, batch=batch, *args, **kwargs)
|
|
907
|
+
|
|
908
|
+
def apply_model(self, x_noisy, t, cond, return_ids=False):
|
|
909
|
+
if isinstance(cond, dict):
|
|
910
|
+
# hybrid case, cond is expected to be a dict
|
|
911
|
+
pass
|
|
912
|
+
else:
|
|
913
|
+
if not isinstance(cond, list):
|
|
914
|
+
cond = [cond]
|
|
915
|
+
key = 'c_concat' if self.model.conditioning_key == 'concat' else 'c_crossattn'
|
|
916
|
+
cond = {key: cond}
|
|
917
|
+
|
|
918
|
+
x_recon = self.model(x_noisy, t, **cond)
|
|
919
|
+
|
|
920
|
+
if isinstance(x_recon, tuple) and not return_ids:
|
|
921
|
+
return x_recon[0]
|
|
922
|
+
else:
|
|
923
|
+
return x_recon
|
|
924
|
+
|
|
925
|
+
def _predict_eps_from_xstart(self, x_t, t, pred_xstart):
|
|
926
|
+
return (extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x_t.shape) * x_t - pred_xstart) / \
|
|
927
|
+
extract_into_tensor(self.sqrt_recipm1_alphas_cumprod, t, x_t.shape)
|
|
928
|
+
|
|
929
|
+
def _prior_bpd(self, x_start):
|
|
930
|
+
"""
|
|
931
|
+
Get the prior KL term for the variational lower-bound, measured in
|
|
932
|
+
bits-per-dim.
|
|
933
|
+
This term can't be optimized, as it only depends on the encoder.
|
|
934
|
+
:param x_start: the [N x C x ...] tensor of inputs.
|
|
935
|
+
:return: a batch of [N] KL values (in bits), one per batch element.
|
|
936
|
+
"""
|
|
937
|
+
batch_size = x_start.shape[0]
|
|
938
|
+
t = torch.tensor([self.num_timesteps - 1] * batch_size, device=x_start.device)
|
|
939
|
+
qt_mean, _, qt_log_variance = self.q_mean_variance(x_start, t)
|
|
940
|
+
kl_prior = normal_kl(mean1=qt_mean, logvar1=qt_log_variance, mean2=0.0, logvar2=0.0)
|
|
941
|
+
return mean_flat(kl_prior) / np.log(2.0)
|
|
942
|
+
|
|
943
|
+
def p_losses(self, x_start, cond, t, noise=None, shadowmask=None, batch=None):
|
|
944
|
+
noise = default(noise, lambda: torch.randn_like(x_start))
|
|
945
|
+
x_noisy = self.q_sample(x_start=x_start, t=t, noise=noise)
|
|
946
|
+
model_output = self.apply_model(x_noisy, t, cond, batch=batch)
|
|
947
|
+
|
|
948
|
+
loss_dict = {}
|
|
949
|
+
prefix = 'train' if self.training else 'val'
|
|
950
|
+
|
|
951
|
+
if self.parameterization == "x0":
|
|
952
|
+
target = x_start
|
|
953
|
+
elif self.parameterization == "eps":
|
|
954
|
+
target = noise
|
|
955
|
+
elif self.parameterization == "v":
|
|
956
|
+
target = self.get_v(x_start, noise, t)
|
|
957
|
+
else:
|
|
958
|
+
raise NotImplementedError()
|
|
959
|
+
|
|
960
|
+
loss_simple = self.get_loss(model_output, target, mean=False, mask=shadowmask).mean([1, 2, 3])
|
|
961
|
+
# loss_simple = self.get_loss(model_output, target, mean=False).mean([1, 2, 3])
|
|
962
|
+
loss_dict.update({f'{prefix}/loss_simple': loss_simple.mean()})
|
|
963
|
+
|
|
964
|
+
logvar_t = self.logvar[t].to(self.device)
|
|
965
|
+
loss = loss_simple / torch.exp(logvar_t) + logvar_t
|
|
966
|
+
# loss = loss_simple / torch.exp(self.logvar) + self.logvar
|
|
967
|
+
if self.learn_logvar:
|
|
968
|
+
loss_dict.update({f'{prefix}/loss_gamma': loss.mean()})
|
|
969
|
+
loss_dict.update({'logvar': self.logvar.data.mean()})
|
|
970
|
+
|
|
971
|
+
loss = self.l_simple_weight * loss.mean()
|
|
972
|
+
|
|
973
|
+
loss_vlb = self.get_loss(model_output, target, mean=False).mean(dim=(1, 2, 3))
|
|
974
|
+
loss_vlb = (self.lvlb_weights[t] * loss_vlb).mean()
|
|
975
|
+
loss_dict.update({f'{prefix}/loss_vlb': loss_vlb})
|
|
976
|
+
loss += (self.original_elbo_weight * loss_vlb)
|
|
977
|
+
loss_dict.update({f'{prefix}/loss': loss})
|
|
978
|
+
|
|
979
|
+
return loss, loss_dict
|
|
980
|
+
|
|
981
|
+
def p_mean_variance(self, x, c, t, clip_denoised: bool, return_codebook_ids=False, quantize_denoised=False,
|
|
982
|
+
return_x0=False, score_corrector=None, corrector_kwargs=None):
|
|
983
|
+
t_in = t
|
|
984
|
+
model_out = self.apply_model(x, t_in, c, return_ids=return_codebook_ids)
|
|
985
|
+
|
|
986
|
+
if score_corrector is not None:
|
|
987
|
+
assert self.parameterization == "eps"
|
|
988
|
+
model_out = score_corrector.modify_score(self, model_out, x, t, c, **corrector_kwargs)
|
|
989
|
+
|
|
990
|
+
if return_codebook_ids:
|
|
991
|
+
model_out, logits = model_out
|
|
992
|
+
|
|
993
|
+
if self.parameterization == "eps":
|
|
994
|
+
x_recon = self.predict_start_from_noise(x, t=t, noise=model_out)
|
|
995
|
+
elif self.parameterization == "x0":
|
|
996
|
+
x_recon = model_out
|
|
997
|
+
else:
|
|
998
|
+
raise NotImplementedError()
|
|
999
|
+
|
|
1000
|
+
if clip_denoised:
|
|
1001
|
+
x_recon.clamp_(-1., 1.)
|
|
1002
|
+
if quantize_denoised:
|
|
1003
|
+
x_recon, _, [_, _, indices] = self.first_stage_model.quantize(x_recon)
|
|
1004
|
+
model_mean, posterior_variance, posterior_log_variance = self.q_posterior(x_start=x_recon, x_t=x, t=t)
|
|
1005
|
+
if return_codebook_ids:
|
|
1006
|
+
return model_mean, posterior_variance, posterior_log_variance, logits
|
|
1007
|
+
elif return_x0:
|
|
1008
|
+
return model_mean, posterior_variance, posterior_log_variance, x_recon
|
|
1009
|
+
else:
|
|
1010
|
+
return model_mean, posterior_variance, posterior_log_variance
|
|
1011
|
+
|
|
1012
|
+
@torch.no_grad()
|
|
1013
|
+
def p_sample(self, x, c, t, clip_denoised=False, repeat_noise=False,
|
|
1014
|
+
return_codebook_ids=False, quantize_denoised=False, return_x0=False,
|
|
1015
|
+
temperature=1., noise_dropout=0., score_corrector=None, corrector_kwargs=None):
|
|
1016
|
+
b, *_, device = *x.shape, x.device
|
|
1017
|
+
outputs = self.p_mean_variance(x=x, c=c, t=t, clip_denoised=clip_denoised,
|
|
1018
|
+
return_codebook_ids=return_codebook_ids,
|
|
1019
|
+
quantize_denoised=quantize_denoised,
|
|
1020
|
+
return_x0=return_x0,
|
|
1021
|
+
score_corrector=score_corrector, corrector_kwargs=corrector_kwargs)
|
|
1022
|
+
if return_codebook_ids:
|
|
1023
|
+
raise DeprecationWarning("Support dropped.")
|
|
1024
|
+
model_mean, _, model_log_variance, logits = outputs
|
|
1025
|
+
elif return_x0:
|
|
1026
|
+
model_mean, _, model_log_variance, x0 = outputs
|
|
1027
|
+
else:
|
|
1028
|
+
model_mean, _, model_log_variance = outputs
|
|
1029
|
+
|
|
1030
|
+
noise = noise_like(x.shape, device, repeat_noise) * temperature
|
|
1031
|
+
if noise_dropout > 0.:
|
|
1032
|
+
noise = torch.nn.functional.dropout(noise, p=noise_dropout)
|
|
1033
|
+
# no noise when t == 0
|
|
1034
|
+
nonzero_mask = (1 - (t == 0).float()).reshape(b, *((1,) * (len(x.shape) - 1)))
|
|
1035
|
+
|
|
1036
|
+
if return_codebook_ids:
|
|
1037
|
+
return model_mean + nonzero_mask * (0.5 * model_log_variance).exp() * noise, logits.argmax(dim=1)
|
|
1038
|
+
if return_x0:
|
|
1039
|
+
return model_mean + nonzero_mask * (0.5 * model_log_variance).exp() * noise, x0
|
|
1040
|
+
else:
|
|
1041
|
+
return model_mean + nonzero_mask * (0.5 * model_log_variance).exp() * noise
|
|
1042
|
+
|
|
1043
|
+
@torch.no_grad()
|
|
1044
|
+
def progressive_denoising(self, cond, shape, verbose=True, callback=None, quantize_denoised=False,
|
|
1045
|
+
img_callback=None, mask=None, x0=None, temperature=1., noise_dropout=0.,
|
|
1046
|
+
score_corrector=None, corrector_kwargs=None, batch_size=None, x_T=None, start_T=None,
|
|
1047
|
+
log_every_t=None):
|
|
1048
|
+
if not log_every_t:
|
|
1049
|
+
log_every_t = self.log_every_t
|
|
1050
|
+
timesteps = self.num_timesteps
|
|
1051
|
+
if batch_size is not None:
|
|
1052
|
+
b = batch_size if batch_size is not None else shape[0]
|
|
1053
|
+
shape = [batch_size] + list(shape)
|
|
1054
|
+
else:
|
|
1055
|
+
b = batch_size = shape[0]
|
|
1056
|
+
if x_T is None:
|
|
1057
|
+
img = torch.randn(shape, device=self.device)
|
|
1058
|
+
else:
|
|
1059
|
+
img = x_T
|
|
1060
|
+
intermediates = []
|
|
1061
|
+
if cond is not None:
|
|
1062
|
+
if isinstance(cond, dict):
|
|
1063
|
+
cond = {key: cond[key][:batch_size] if not isinstance(cond[key], list) else
|
|
1064
|
+
list(map(lambda x: x[:batch_size], cond[key])) for key in cond}
|
|
1065
|
+
else:
|
|
1066
|
+
cond = [c[:batch_size] for c in cond] if isinstance(cond, list) else cond[:batch_size]
|
|
1067
|
+
|
|
1068
|
+
if start_T is not None:
|
|
1069
|
+
timesteps = min(timesteps, start_T)
|
|
1070
|
+
iterator = tqdm(reversed(range(0, timesteps)), desc='Progressive Generation',
|
|
1071
|
+
total=timesteps) if verbose else reversed(
|
|
1072
|
+
range(0, timesteps))
|
|
1073
|
+
if type(temperature) == float:
|
|
1074
|
+
temperature = [temperature] * timesteps
|
|
1075
|
+
|
|
1076
|
+
for i in iterator:
|
|
1077
|
+
ts = torch.full((b,), i, device=self.device, dtype=torch.long)
|
|
1078
|
+
if self.shorten_cond_schedule:
|
|
1079
|
+
assert self.model.conditioning_key != 'hybrid'
|
|
1080
|
+
tc = self.cond_ids[ts].to(cond.device)
|
|
1081
|
+
cond = self.q_sample(x_start=cond, t=tc, noise=torch.randn_like(cond))
|
|
1082
|
+
|
|
1083
|
+
img, x0_partial = self.p_sample(img, cond, ts,
|
|
1084
|
+
clip_denoised=self.clip_denoised,
|
|
1085
|
+
quantize_denoised=quantize_denoised, return_x0=True,
|
|
1086
|
+
temperature=temperature[i], noise_dropout=noise_dropout,
|
|
1087
|
+
score_corrector=score_corrector, corrector_kwargs=corrector_kwargs)
|
|
1088
|
+
if mask is not None:
|
|
1089
|
+
assert x0 is not None
|
|
1090
|
+
img_orig = self.q_sample(x0, ts)
|
|
1091
|
+
img = img_orig * mask + (1. - mask) * img
|
|
1092
|
+
|
|
1093
|
+
if i % log_every_t == 0 or i == timesteps - 1:
|
|
1094
|
+
intermediates.append(x0_partial)
|
|
1095
|
+
if callback: callback(i)
|
|
1096
|
+
if img_callback: img_callback(img, i)
|
|
1097
|
+
return img, intermediates
|
|
1098
|
+
|
|
1099
|
+
@torch.no_grad()
|
|
1100
|
+
def p_sample_loop(self, cond, shape, return_intermediates=False,
|
|
1101
|
+
x_T=None, verbose=True, callback=None, timesteps=None, quantize_denoised=False,
|
|
1102
|
+
mask=None, x0=None, img_callback=None, start_T=None,
|
|
1103
|
+
log_every_t=None):
|
|
1104
|
+
|
|
1105
|
+
if not log_every_t:
|
|
1106
|
+
log_every_t = self.log_every_t
|
|
1107
|
+
device = self.betas.device
|
|
1108
|
+
b = shape[0]
|
|
1109
|
+
if x_T is None:
|
|
1110
|
+
img = torch.randn(shape, device=device)
|
|
1111
|
+
else:
|
|
1112
|
+
img = x_T
|
|
1113
|
+
|
|
1114
|
+
intermediates = [img]
|
|
1115
|
+
if timesteps is None:
|
|
1116
|
+
timesteps = self.num_timesteps
|
|
1117
|
+
|
|
1118
|
+
if start_T is not None:
|
|
1119
|
+
timesteps = min(timesteps, start_T)
|
|
1120
|
+
iterator = tqdm(reversed(range(0, timesteps)), desc='Sampling t', total=timesteps) if verbose else reversed(
|
|
1121
|
+
range(0, timesteps))
|
|
1122
|
+
|
|
1123
|
+
if mask is not None:
|
|
1124
|
+
assert x0 is not None
|
|
1125
|
+
assert x0.shape[2:3] == mask.shape[2:3] # spatial size has to match
|
|
1126
|
+
|
|
1127
|
+
for i in iterator:
|
|
1128
|
+
ts = torch.full((b,), i, device=device, dtype=torch.long)
|
|
1129
|
+
if self.shorten_cond_schedule:
|
|
1130
|
+
assert self.model.conditioning_key != 'hybrid'
|
|
1131
|
+
tc = self.cond_ids[ts].to(cond.device)
|
|
1132
|
+
cond = self.q_sample(x_start=cond, t=tc, noise=torch.randn_like(cond))
|
|
1133
|
+
|
|
1134
|
+
img = self.p_sample(img, cond, ts,
|
|
1135
|
+
clip_denoised=self.clip_denoised,
|
|
1136
|
+
quantize_denoised=quantize_denoised)
|
|
1137
|
+
if mask is not None:
|
|
1138
|
+
img_orig = self.q_sample(x0, ts)
|
|
1139
|
+
img = img_orig * mask + (1. - mask) * img
|
|
1140
|
+
|
|
1141
|
+
if i % log_every_t == 0 or i == timesteps - 1:
|
|
1142
|
+
intermediates.append(img)
|
|
1143
|
+
if callback: callback(i)
|
|
1144
|
+
if img_callback: img_callback(img, i)
|
|
1145
|
+
|
|
1146
|
+
if return_intermediates:
|
|
1147
|
+
return img, intermediates
|
|
1148
|
+
return img
|
|
1149
|
+
|
|
1150
|
+
@torch.no_grad()
|
|
1151
|
+
def sample(self, cond, batch_size=16, return_intermediates=False, x_T=None,
|
|
1152
|
+
verbose=True, timesteps=None, quantize_denoised=False,
|
|
1153
|
+
mask=None, x0=None, shape=None, **kwargs):
|
|
1154
|
+
if shape is None:
|
|
1155
|
+
shape = (batch_size, self.channels, self.image_size, self.image_size)
|
|
1156
|
+
if cond is not None:
|
|
1157
|
+
if isinstance(cond, dict):
|
|
1158
|
+
cond = {key: cond[key][:batch_size] if not isinstance(cond[key], list) else
|
|
1159
|
+
list(map(lambda x: x[:batch_size], cond[key])) for key in cond}
|
|
1160
|
+
else:
|
|
1161
|
+
cond = [c[:batch_size] for c in cond] if isinstance(cond, list) else cond[:batch_size]
|
|
1162
|
+
return self.p_sample_loop(cond,
|
|
1163
|
+
shape,
|
|
1164
|
+
return_intermediates=return_intermediates, x_T=x_T,
|
|
1165
|
+
verbose=verbose, timesteps=timesteps, quantize_denoised=quantize_denoised,
|
|
1166
|
+
mask=mask, x0=x0)
|
|
1167
|
+
|
|
1168
|
+
@torch.no_grad()
|
|
1169
|
+
def sample_log(self, cond, batch_size, ddim, ddim_steps, **kwargs):
|
|
1170
|
+
if ddim:
|
|
1171
|
+
ddim_sampler = DDIMSampler(self)
|
|
1172
|
+
shape = (self.channels, self.image_size, self.image_size)
|
|
1173
|
+
samples, intermediates = ddim_sampler.sample(ddim_steps, batch_size,
|
|
1174
|
+
shape, cond, verbose=False, **kwargs)
|
|
1175
|
+
|
|
1176
|
+
else:
|
|
1177
|
+
samples, intermediates = self.sample(cond=cond, batch_size=batch_size,
|
|
1178
|
+
return_intermediates=True, **kwargs)
|
|
1179
|
+
|
|
1180
|
+
return samples, intermediates
|
|
1181
|
+
|
|
1182
|
+
@torch.no_grad()
|
|
1183
|
+
def get_unconditional_conditioning(self, batch_size, null_label=None):
|
|
1184
|
+
if null_label is not None:
|
|
1185
|
+
xc = null_label
|
|
1186
|
+
if isinstance(xc, ListConfig):
|
|
1187
|
+
xc = list(xc)
|
|
1188
|
+
if isinstance(xc, dict) or isinstance(xc, list):
|
|
1189
|
+
c = self.get_learned_conditioning(xc)
|
|
1190
|
+
else:
|
|
1191
|
+
if hasattr(xc, "to"):
|
|
1192
|
+
xc = xc.to(self.device)
|
|
1193
|
+
c = self.get_learned_conditioning(xc)
|
|
1194
|
+
else:
|
|
1195
|
+
if self.cond_stage_key in ["class_label", "cls"]:
|
|
1196
|
+
xc = self.cond_stage_model.get_unconditional_conditioning(batch_size, device=self.device)
|
|
1197
|
+
return self.get_learned_conditioning(xc)
|
|
1198
|
+
else:
|
|
1199
|
+
raise NotImplementedError("todo")
|
|
1200
|
+
if isinstance(c, list): # in case the encoder gives us a list
|
|
1201
|
+
for i in range(len(c)):
|
|
1202
|
+
c[i] = repeat(c[i], '1 ... -> b ...', b=batch_size).to(self.device)
|
|
1203
|
+
else:
|
|
1204
|
+
c = repeat(c, '1 ... -> b ...', b=batch_size).to(self.device)
|
|
1205
|
+
return c
|
|
1206
|
+
|
|
1207
|
+
@torch.no_grad()
|
|
1208
|
+
def log_images(self, batch, N=8, n_row=4, sample=True, ddim_steps=50, ddim_eta=0., return_keys=None,
|
|
1209
|
+
quantize_denoised=True, inpaint=True, plot_denoise_rows=False, plot_progressive_rows=True,
|
|
1210
|
+
plot_diffusion_rows=True, unconditional_guidance_scale=1., unconditional_guidance_label=None,
|
|
1211
|
+
use_ema_scope=True,
|
|
1212
|
+
**kwargs):
|
|
1213
|
+
ema_scope = self.ema_scope if use_ema_scope else nullcontext
|
|
1214
|
+
use_ddim = ddim_steps is not None
|
|
1215
|
+
|
|
1216
|
+
log = dict()
|
|
1217
|
+
z, c, x, xrec, xc = self.get_input(batch, self.first_stage_key,
|
|
1218
|
+
return_first_stage_outputs=True,
|
|
1219
|
+
force_c_encode=True,
|
|
1220
|
+
return_original_cond=True,
|
|
1221
|
+
bs=N)
|
|
1222
|
+
N = min(x.shape[0], N)
|
|
1223
|
+
n_row = min(x.shape[0], n_row)
|
|
1224
|
+
log["inputs"] = x
|
|
1225
|
+
log["reconstruction"] = xrec
|
|
1226
|
+
if self.model.conditioning_key is not None:
|
|
1227
|
+
if hasattr(self.cond_stage_model, "decode"):
|
|
1228
|
+
xc = self.cond_stage_model.decode(c)
|
|
1229
|
+
log["conditioning"] = xc
|
|
1230
|
+
elif self.cond_stage_key in ["caption", "txt"]:
|
|
1231
|
+
xc = log_txt_as_img((x.shape[2], x.shape[3]), batch[self.cond_stage_key], size=x.shape[2] // 25)
|
|
1232
|
+
log["conditioning"] = xc
|
|
1233
|
+
elif self.cond_stage_key in ['class_label', "cls"]:
|
|
1234
|
+
try:
|
|
1235
|
+
xc = log_txt_as_img((x.shape[2], x.shape[3]), batch["human_label"], size=x.shape[2] // 25)
|
|
1236
|
+
log['conditioning'] = xc
|
|
1237
|
+
except KeyError:
|
|
1238
|
+
# probably no "human_label" in batch
|
|
1239
|
+
pass
|
|
1240
|
+
elif isimage(xc):
|
|
1241
|
+
log["conditioning"] = xc
|
|
1242
|
+
if ismap(xc):
|
|
1243
|
+
log["original_conditioning"] = self.to_rgb(xc)
|
|
1244
|
+
|
|
1245
|
+
if plot_diffusion_rows:
|
|
1246
|
+
# get diffusion row
|
|
1247
|
+
diffusion_row = list()
|
|
1248
|
+
z_start = z[:n_row]
|
|
1249
|
+
for t in range(self.num_timesteps):
|
|
1250
|
+
if t % self.log_every_t == 0 or t == self.num_timesteps - 1:
|
|
1251
|
+
t = repeat(torch.tensor([t]), '1 -> b', b=n_row)
|
|
1252
|
+
t = t.to(self.device).long()
|
|
1253
|
+
noise = torch.randn_like(z_start)
|
|
1254
|
+
z_noisy = self.q_sample(x_start=z_start, t=t, noise=noise)
|
|
1255
|
+
diffusion_row.append(self.decode_first_stage(z_noisy))
|
|
1256
|
+
|
|
1257
|
+
diffusion_row = torch.stack(diffusion_row) # n_log_step, n_row, C, H, W
|
|
1258
|
+
diffusion_grid = rearrange(diffusion_row, 'n b c h w -> b n c h w')
|
|
1259
|
+
diffusion_grid = rearrange(diffusion_grid, 'b n c h w -> (b n) c h w')
|
|
1260
|
+
diffusion_grid = make_grid(diffusion_grid, nrow=diffusion_row.shape[0])
|
|
1261
|
+
log["diffusion_row"] = diffusion_grid
|
|
1262
|
+
|
|
1263
|
+
if sample:
|
|
1264
|
+
# get denoise row
|
|
1265
|
+
with ema_scope("Sampling"):
|
|
1266
|
+
samples, z_denoise_row = self.sample_log(cond=c, batch_size=N, ddim=use_ddim,
|
|
1267
|
+
ddim_steps=ddim_steps, eta=ddim_eta)
|
|
1268
|
+
# samples, z_denoise_row = self.sample(cond=c, batch_size=N, return_intermediates=True)
|
|
1269
|
+
x_samples = self.decode_first_stage(samples)
|
|
1270
|
+
log["samples"] = x_samples
|
|
1271
|
+
if plot_denoise_rows:
|
|
1272
|
+
denoise_grid = self._get_denoise_row_from_list(z_denoise_row)
|
|
1273
|
+
log["denoise_row"] = denoise_grid
|
|
1274
|
+
|
|
1275
|
+
if quantize_denoised and not isinstance(self.first_stage_model, AutoencoderKL) and not isinstance(
|
|
1276
|
+
self.first_stage_model, IdentityFirstStage):
|
|
1277
|
+
# also display when quantizing x0 while sampling
|
|
1278
|
+
with ema_scope("Plotting Quantized Denoised"):
|
|
1279
|
+
samples, z_denoise_row = self.sample_log(cond=c, batch_size=N, ddim=use_ddim,
|
|
1280
|
+
ddim_steps=ddim_steps, eta=ddim_eta,
|
|
1281
|
+
quantize_denoised=True)
|
|
1282
|
+
# samples, z_denoise_row = self.sample(cond=c, batch_size=N, return_intermediates=True,
|
|
1283
|
+
# quantize_denoised=True)
|
|
1284
|
+
x_samples = self.decode_first_stage(samples.to(self.device))
|
|
1285
|
+
log["samples_x0_quantized"] = x_samples
|
|
1286
|
+
|
|
1287
|
+
if unconditional_guidance_scale > 1.0:
|
|
1288
|
+
uc = self.get_unconditional_conditioning(N, unconditional_guidance_label)
|
|
1289
|
+
if self.model.conditioning_key == "crossattn-adm":
|
|
1290
|
+
uc = {"c_crossattn": [uc], "c_adm": c["c_adm"]}
|
|
1291
|
+
with ema_scope("Sampling with classifier-free guidance"):
|
|
1292
|
+
samples_cfg, _ = self.sample_log(cond=c, batch_size=N, ddim=use_ddim,
|
|
1293
|
+
ddim_steps=ddim_steps, eta=ddim_eta,
|
|
1294
|
+
unconditional_guidance_scale=unconditional_guidance_scale,
|
|
1295
|
+
unconditional_conditioning=uc,
|
|
1296
|
+
)
|
|
1297
|
+
x_samples_cfg = self.decode_first_stage(samples_cfg)
|
|
1298
|
+
log[f"samples_cfg_scale_{unconditional_guidance_scale:.2f}"] = x_samples_cfg
|
|
1299
|
+
|
|
1300
|
+
if inpaint:
|
|
1301
|
+
# make a simple center square
|
|
1302
|
+
b, h, w = z.shape[0], z.shape[2], z.shape[3]
|
|
1303
|
+
mask = torch.ones(N, h, w).to(self.device)
|
|
1304
|
+
# zeros will be filled in
|
|
1305
|
+
mask[:, h // 4:3 * h // 4, w // 4:3 * w // 4] = 0.
|
|
1306
|
+
mask = mask[:, None, ...]
|
|
1307
|
+
with ema_scope("Plotting Inpaint"):
|
|
1308
|
+
samples, _ = self.sample_log(cond=c, batch_size=N, ddim=use_ddim, eta=ddim_eta,
|
|
1309
|
+
ddim_steps=ddim_steps, x0=z[:N], mask=mask)
|
|
1310
|
+
x_samples = self.decode_first_stage(samples.to(self.device))
|
|
1311
|
+
log["samples_inpainting"] = x_samples
|
|
1312
|
+
log["mask"] = mask
|
|
1313
|
+
|
|
1314
|
+
# outpaint
|
|
1315
|
+
mask = 1. - mask
|
|
1316
|
+
with ema_scope("Plotting Outpaint"):
|
|
1317
|
+
samples, _ = self.sample_log(cond=c, batch_size=N, ddim=use_ddim, eta=ddim_eta,
|
|
1318
|
+
ddim_steps=ddim_steps, x0=z[:N], mask=mask)
|
|
1319
|
+
x_samples = self.decode_first_stage(samples.to(self.device))
|
|
1320
|
+
log["samples_outpainting"] = x_samples
|
|
1321
|
+
|
|
1322
|
+
if plot_progressive_rows:
|
|
1323
|
+
with ema_scope("Plotting Progressives"):
|
|
1324
|
+
img, progressives = self.progressive_denoising(c,
|
|
1325
|
+
shape=(self.channels, self.image_size, self.image_size),
|
|
1326
|
+
batch_size=N)
|
|
1327
|
+
prog_row = self._get_denoise_row_from_list(progressives, desc="Progressive Generation")
|
|
1328
|
+
log["progressive_row"] = prog_row
|
|
1329
|
+
|
|
1330
|
+
if return_keys:
|
|
1331
|
+
if np.intersect1d(list(log.keys()), return_keys).shape[0] == 0:
|
|
1332
|
+
return log
|
|
1333
|
+
else:
|
|
1334
|
+
return {key: log[key] for key in return_keys}
|
|
1335
|
+
return log
|
|
1336
|
+
|
|
1337
|
+
def configure_optimizers(self):
|
|
1338
|
+
lr = self.learning_rate
|
|
1339
|
+
params = list(self.model.parameters())
|
|
1340
|
+
if self.cond_stage_trainable:
|
|
1341
|
+
print(f"{self.__class__.__name__}: Also optimizing conditioner params!")
|
|
1342
|
+
params = params + list(self.cond_stage_model.parameters())
|
|
1343
|
+
if self.learn_logvar:
|
|
1344
|
+
print('Diffusion model optimizing logvar')
|
|
1345
|
+
params.append(self.logvar)
|
|
1346
|
+
opt = torch.optim.AdamW(params, lr=lr)
|
|
1347
|
+
if self.use_scheduler:
|
|
1348
|
+
assert 'target' in self.scheduler_config
|
|
1349
|
+
scheduler = instantiate_from_config(self.scheduler_config)
|
|
1350
|
+
|
|
1351
|
+
print("Setting up LambdaLR scheduler...")
|
|
1352
|
+
scheduler = [
|
|
1353
|
+
{
|
|
1354
|
+
'scheduler': LambdaLR(opt, lr_lambda=scheduler.schedule),
|
|
1355
|
+
'interval': 'step',
|
|
1356
|
+
'frequency': 1
|
|
1357
|
+
}]
|
|
1358
|
+
return [opt], scheduler
|
|
1359
|
+
return opt
|
|
1360
|
+
|
|
1361
|
+
@torch.no_grad()
|
|
1362
|
+
def to_rgb(self, x):
|
|
1363
|
+
x = x.float()
|
|
1364
|
+
if not hasattr(self, "colorize"):
|
|
1365
|
+
self.colorize = torch.randn(3, x.shape[1], 1, 1).to(x)
|
|
1366
|
+
x = nn.functional.conv2d(x, weight=self.colorize)
|
|
1367
|
+
x = 2. * (x - x.min()) / (x.max() - x.min()) - 1.
|
|
1368
|
+
return x
|
|
1369
|
+
|
|
1370
|
+
|
|
1371
|
+
class DiffusionWrapper(pl.LightningModule):
|
|
1372
|
+
def __init__(self, diff_model_config, conditioning_key):
|
|
1373
|
+
super().__init__()
|
|
1374
|
+
self.sequential_cross_attn = diff_model_config.pop("sequential_crossattn", False)
|
|
1375
|
+
|
|
1376
|
+
## sd-1.4
|
|
1377
|
+
model_name = "CompVis/stable-diffusion-v1-4"
|
|
1378
|
+
pipeline = StableDiffusionPipeline.from_pretrained(model_name)
|
|
1379
|
+
self.diffusion_model = pipeline.unet
|
|
1380
|
+
self.diffusion_model.requires_grad_(False)
|
|
1381
|
+
self.attn_procs = {}
|
|
1382
|
+
unet_sd = self.diffusion_model.state_dict()
|
|
1383
|
+
for name in self.diffusion_model.attn_processors.keys():
|
|
1384
|
+
cross_attention_dim = None if name.endswith("attn1.processor") else self.diffusion_model.config.cross_attention_dim
|
|
1385
|
+
if name.startswith("mid_block"):
|
|
1386
|
+
hidden_size = self.diffusion_model.config.block_out_channels[-1]
|
|
1387
|
+
elif name.startswith("up_blocks"):
|
|
1388
|
+
block_id = int(name[len("up_blocks.")])
|
|
1389
|
+
hidden_size = list(reversed(self.diffusion_model.config.block_out_channels))[block_id]
|
|
1390
|
+
elif name.startswith("down_blocks"):
|
|
1391
|
+
block_id = int(name[len("down_blocks.")])
|
|
1392
|
+
hidden_size = self.diffusion_model.config.block_out_channels[block_id]
|
|
1393
|
+
if cross_attention_dim is None:
|
|
1394
|
+
self.attn_procs[name] = AttnProcessor()
|
|
1395
|
+
else:
|
|
1396
|
+
layer_name = name.split(".processor")[0]
|
|
1397
|
+
weights = {
|
|
1398
|
+
"to_k_ip.weight": unet_sd[layer_name + ".to_k.weight"],
|
|
1399
|
+
"to_v_ip.weight": unet_sd[layer_name + ".to_v.weight"],
|
|
1400
|
+
}
|
|
1401
|
+
self.attn_procs[name] = IPAttnProcessor(hidden_size=hidden_size, cross_attention_dim=cross_attention_dim)
|
|
1402
|
+
self.attn_procs[name].load_state_dict(weights)
|
|
1403
|
+
self.diffusion_model.set_attn_processor(self.attn_procs)
|
|
1404
|
+
self.adapter_modules = torch.nn.ModuleList(self.diffusion_model.attn_processors.values())
|
|
1405
|
+
#ip-adapter
|
|
1406
|
+
self.image_proj_model = ImageProjModel(
|
|
1407
|
+
cross_attention_dim=self.diffusion_model.config.cross_attention_dim,
|
|
1408
|
+
extra_embeddings_dim=2048,
|
|
1409
|
+
clip_extra_context_tokens=64,
|
|
1410
|
+
)
|
|
1411
|
+
self.image_proj_model.to(self.device)
|
|
1412
|
+
self.ip_adapter = IPAdapter(self.diffusion_model, self.image_proj_model, self.adapter_modules)
|
|
1413
|
+
self.conditioning_key = conditioning_key
|
|
1414
|
+
assert self.conditioning_key in [None, 'concat', 'crossattn', 'hybrid', 'adm', 'hybrid-adm', 'crossattn-adm']
|
|
1415
|
+
|
|
1416
|
+
def forward(self, x, t, c_concat: list = None, c_crossattn: list = None, c_adm=None):
|
|
1417
|
+
if self.conditioning_key is None:
|
|
1418
|
+
out = self.diffusion_model(x, t)
|
|
1419
|
+
elif self.conditioning_key == 'concat':
|
|
1420
|
+
xc = torch.cat([x] + c_concat, dim=1)
|
|
1421
|
+
out = self.diffusion_model(xc, t)
|
|
1422
|
+
elif self.conditioning_key == 'crossattn':
|
|
1423
|
+
if not self.sequential_cross_attn:
|
|
1424
|
+
cc = torch.cat(c_crossattn, 1)
|
|
1425
|
+
else:
|
|
1426
|
+
cc = c_crossattn
|
|
1427
|
+
out = self.diffusion_model(x, t, context=cc)
|
|
1428
|
+
elif self.conditioning_key == 'hybrid':
|
|
1429
|
+
xc = torch.cat([x] + c_concat, dim=1)
|
|
1430
|
+
cc = torch.cat(c_crossattn, 1)
|
|
1431
|
+
out = self.diffusion_model(xc, t, context=cc)
|
|
1432
|
+
elif self.conditioning_key == 'hybrid-adm':
|
|
1433
|
+
assert c_adm is not None
|
|
1434
|
+
xc = torch.cat([x] + c_concat, dim=1)
|
|
1435
|
+
cc = torch.cat(c_crossattn, 1)
|
|
1436
|
+
out = self.diffusion_model(xc, t, context=cc, y=c_adm)
|
|
1437
|
+
elif self.conditioning_key == 'crossattn-adm':
|
|
1438
|
+
assert c_adm is not None
|
|
1439
|
+
cc = torch.cat(c_crossattn, 1)
|
|
1440
|
+
out = self.diffusion_model(x, t, context=cc, y=c_adm)
|
|
1441
|
+
elif self.conditioning_key == 'adm':
|
|
1442
|
+
cc = c_crossattn[0]
|
|
1443
|
+
out = self.diffusion_model(x, t, y=cc)
|
|
1444
|
+
else:
|
|
1445
|
+
raise NotImplementedError()
|
|
1446
|
+
|
|
1447
|
+
return out
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
class LatentUpscaleDiffusion(LatentDiffusion):
|
|
1451
|
+
def __init__(self, *args, low_scale_config, low_scale_key="LR", noise_level_key=None, **kwargs):
|
|
1452
|
+
super().__init__(*args, **kwargs)
|
|
1453
|
+
# assumes that neither the cond_stage nor the low_scale_model contain trainable params
|
|
1454
|
+
assert not self.cond_stage_trainable
|
|
1455
|
+
self.instantiate_low_stage(low_scale_config)
|
|
1456
|
+
self.low_scale_key = low_scale_key
|
|
1457
|
+
self.noise_level_key = noise_level_key
|
|
1458
|
+
|
|
1459
|
+
def instantiate_low_stage(self, config):
|
|
1460
|
+
model = instantiate_from_config(config)
|
|
1461
|
+
self.low_scale_model = model.eval()
|
|
1462
|
+
self.low_scale_model.train = disabled_train
|
|
1463
|
+
for param in self.low_scale_model.parameters():
|
|
1464
|
+
param.requires_grad = False
|
|
1465
|
+
|
|
1466
|
+
@torch.no_grad()
|
|
1467
|
+
def get_input(self, batch, k, cond_key=None, bs=None, log_mode=False):
|
|
1468
|
+
if not log_mode:
|
|
1469
|
+
z, c = super().get_input(batch, k, force_c_encode=True, bs=bs)
|
|
1470
|
+
else:
|
|
1471
|
+
z, c, x, xrec, xc = super().get_input(batch, self.first_stage_key, return_first_stage_outputs=True,
|
|
1472
|
+
force_c_encode=True, return_original_cond=True, bs=bs)
|
|
1473
|
+
x_low = batch[self.low_scale_key][:bs]
|
|
1474
|
+
x_low = rearrange(x_low, 'b h w c -> b c h w')
|
|
1475
|
+
x_low = x_low.to(memory_format=torch.contiguous_format).float()
|
|
1476
|
+
zx, noise_level = self.low_scale_model(x_low)
|
|
1477
|
+
if self.noise_level_key is not None:
|
|
1478
|
+
# get noise level from batch instead, e.g. when extracting a custom noise level for bsr
|
|
1479
|
+
raise NotImplementedError('TODO')
|
|
1480
|
+
|
|
1481
|
+
all_conds = {"c_concat": [zx], "c_crossattn": [c], "c_adm": noise_level}
|
|
1482
|
+
if log_mode:
|
|
1483
|
+
# TODO: maybe disable if too expensive
|
|
1484
|
+
x_low_rec = self.low_scale_model.decode(zx)
|
|
1485
|
+
return z, all_conds, x, xrec, xc, x_low, x_low_rec, noise_level
|
|
1486
|
+
return z, all_conds
|
|
1487
|
+
|
|
1488
|
+
@torch.no_grad()
|
|
1489
|
+
def log_images(self, batch, N=8, n_row=4, sample=True, ddim_steps=200, ddim_eta=1., return_keys=None,
|
|
1490
|
+
plot_denoise_rows=False, plot_progressive_rows=True, plot_diffusion_rows=True,
|
|
1491
|
+
unconditional_guidance_scale=1., unconditional_guidance_label=None, use_ema_scope=True,
|
|
1492
|
+
**kwargs):
|
|
1493
|
+
ema_scope = self.ema_scope if use_ema_scope else nullcontext
|
|
1494
|
+
use_ddim = ddim_steps is not None
|
|
1495
|
+
|
|
1496
|
+
log = dict()
|
|
1497
|
+
z, c, x, xrec, xc, x_low, x_low_rec, noise_level = self.get_input(batch, self.first_stage_key, bs=N,
|
|
1498
|
+
log_mode=True)
|
|
1499
|
+
N = min(x.shape[0], N)
|
|
1500
|
+
n_row = min(x.shape[0], n_row)
|
|
1501
|
+
log["inputs"] = x
|
|
1502
|
+
log["reconstruction"] = xrec
|
|
1503
|
+
log["x_lr"] = x_low
|
|
1504
|
+
log[f"x_lr_rec_@noise_levels{'-'.join(map(lambda x: str(x), list(noise_level.cpu().numpy())))}"] = x_low_rec
|
|
1505
|
+
if self.model.conditioning_key is not None:
|
|
1506
|
+
if hasattr(self.cond_stage_model, "decode"):
|
|
1507
|
+
xc = self.cond_stage_model.decode(c)
|
|
1508
|
+
log["conditioning"] = xc
|
|
1509
|
+
elif self.cond_stage_key in ["caption", "txt"]:
|
|
1510
|
+
xc = log_txt_as_img((x.shape[2], x.shape[3]), batch[self.cond_stage_key], size=x.shape[2] // 25)
|
|
1511
|
+
log["conditioning"] = xc
|
|
1512
|
+
elif self.cond_stage_key in ['class_label', 'cls']:
|
|
1513
|
+
xc = log_txt_as_img((x.shape[2], x.shape[3]), batch["human_label"], size=x.shape[2] // 25)
|
|
1514
|
+
log['conditioning'] = xc
|
|
1515
|
+
elif isimage(xc):
|
|
1516
|
+
log["conditioning"] = xc
|
|
1517
|
+
if ismap(xc):
|
|
1518
|
+
log["original_conditioning"] = self.to_rgb(xc)
|
|
1519
|
+
|
|
1520
|
+
if plot_diffusion_rows:
|
|
1521
|
+
# get diffusion row
|
|
1522
|
+
diffusion_row = list()
|
|
1523
|
+
z_start = z[:n_row]
|
|
1524
|
+
for t in range(self.num_timesteps):
|
|
1525
|
+
if t % self.log_every_t == 0 or t == self.num_timesteps - 1:
|
|
1526
|
+
t = repeat(torch.tensor([t]), '1 -> b', b=n_row)
|
|
1527
|
+
t = t.to(self.device).long()
|
|
1528
|
+
noise = torch.randn_like(z_start)
|
|
1529
|
+
z_noisy = self.q_sample(x_start=z_start, t=t, noise=noise)
|
|
1530
|
+
diffusion_row.append(self.decode_first_stage(z_noisy))
|
|
1531
|
+
|
|
1532
|
+
diffusion_row = torch.stack(diffusion_row) # n_log_step, n_row, C, H, W
|
|
1533
|
+
diffusion_grid = rearrange(diffusion_row, 'n b c h w -> b n c h w')
|
|
1534
|
+
diffusion_grid = rearrange(diffusion_grid, 'b n c h w -> (b n) c h w')
|
|
1535
|
+
diffusion_grid = make_grid(diffusion_grid, nrow=diffusion_row.shape[0])
|
|
1536
|
+
log["diffusion_row"] = diffusion_grid
|
|
1537
|
+
|
|
1538
|
+
if sample:
|
|
1539
|
+
# get denoise row
|
|
1540
|
+
with ema_scope("Sampling"):
|
|
1541
|
+
samples, z_denoise_row = self.sample_log(cond=c, batch_size=N, ddim=use_ddim,
|
|
1542
|
+
ddim_steps=ddim_steps, eta=ddim_eta)
|
|
1543
|
+
# samples, z_denoise_row = self.sample(cond=c, batch_size=N, return_intermediates=True)
|
|
1544
|
+
x_samples = self.decode_first_stage(samples)
|
|
1545
|
+
log["samples"] = x_samples
|
|
1546
|
+
if plot_denoise_rows:
|
|
1547
|
+
denoise_grid = self._get_denoise_row_from_list(z_denoise_row)
|
|
1548
|
+
log["denoise_row"] = denoise_grid
|
|
1549
|
+
|
|
1550
|
+
if unconditional_guidance_scale > 1.0:
|
|
1551
|
+
uc_tmp = self.get_unconditional_conditioning(N, unconditional_guidance_label)
|
|
1552
|
+
# TODO explore better "unconditional" choices for the other keys
|
|
1553
|
+
# maybe guide away from empty text label and highest noise level and maximally degraded zx?
|
|
1554
|
+
uc = dict()
|
|
1555
|
+
for k in c:
|
|
1556
|
+
if k == "c_crossattn":
|
|
1557
|
+
assert isinstance(c[k], list) and len(c[k]) == 1
|
|
1558
|
+
uc[k] = [uc_tmp]
|
|
1559
|
+
elif k == "c_adm": # todo: only run with text-based guidance?
|
|
1560
|
+
assert isinstance(c[k], torch.Tensor)
|
|
1561
|
+
#uc[k] = torch.ones_like(c[k]) * self.low_scale_model.max_noise_level
|
|
1562
|
+
uc[k] = c[k]
|
|
1563
|
+
elif isinstance(c[k], list):
|
|
1564
|
+
uc[k] = [c[k][i] for i in range(len(c[k]))]
|
|
1565
|
+
else:
|
|
1566
|
+
uc[k] = c[k]
|
|
1567
|
+
|
|
1568
|
+
with ema_scope("Sampling with classifier-free guidance"):
|
|
1569
|
+
samples_cfg, _ = self.sample_log(cond=c, batch_size=N, ddim=use_ddim,
|
|
1570
|
+
ddim_steps=ddim_steps, eta=ddim_eta,
|
|
1571
|
+
unconditional_guidance_scale=unconditional_guidance_scale,
|
|
1572
|
+
unconditional_conditioning=uc,
|
|
1573
|
+
)
|
|
1574
|
+
x_samples_cfg = self.decode_first_stage(samples_cfg)
|
|
1575
|
+
log[f"samples_cfg_scale_{unconditional_guidance_scale:.2f}"] = x_samples_cfg
|
|
1576
|
+
|
|
1577
|
+
if plot_progressive_rows:
|
|
1578
|
+
with ema_scope("Plotting Progressives"):
|
|
1579
|
+
img, progressives = self.progressive_denoising(c,
|
|
1580
|
+
shape=(self.channels, self.image_size, self.image_size),
|
|
1581
|
+
batch_size=N)
|
|
1582
|
+
prog_row = self._get_denoise_row_from_list(progressives, desc="Progressive Generation")
|
|
1583
|
+
log["progressive_row"] = prog_row
|
|
1584
|
+
|
|
1585
|
+
return log
|
|
1586
|
+
|
|
1587
|
+
|
|
1588
|
+
class LatentFinetuneDiffusion(LatentDiffusion):
|
|
1589
|
+
"""
|
|
1590
|
+
Basis for different finetunas, such as inpainting or depth2image
|
|
1591
|
+
To disable finetuning mode, set finetune_keys to None
|
|
1592
|
+
"""
|
|
1593
|
+
|
|
1594
|
+
def __init__(self,
|
|
1595
|
+
concat_keys: tuple,
|
|
1596
|
+
finetune_keys=("model.diffusion_model.input_blocks.0.0.weight",
|
|
1597
|
+
"model_ema.diffusion_modelinput_blocks00weight"
|
|
1598
|
+
),
|
|
1599
|
+
keep_finetune_dims=4,
|
|
1600
|
+
# if model was trained without concat mode before and we would like to keep these channels
|
|
1601
|
+
c_concat_log_start=None, # to log reconstruction of c_concat codes
|
|
1602
|
+
c_concat_log_end=None,
|
|
1603
|
+
*args, **kwargs
|
|
1604
|
+
):
|
|
1605
|
+
ckpt_path = kwargs.pop("ckpt_path", None)
|
|
1606
|
+
ignore_keys = kwargs.pop("ignore_keys", list())
|
|
1607
|
+
super().__init__(*args, **kwargs)
|
|
1608
|
+
self.finetune_keys = finetune_keys
|
|
1609
|
+
self.concat_keys = concat_keys
|
|
1610
|
+
self.keep_dims = keep_finetune_dims
|
|
1611
|
+
self.c_concat_log_start = c_concat_log_start
|
|
1612
|
+
self.c_concat_log_end = c_concat_log_end
|
|
1613
|
+
if exists(self.finetune_keys): assert exists(ckpt_path), 'can only finetune from a given checkpoint'
|
|
1614
|
+
if exists(ckpt_path):
|
|
1615
|
+
self.init_from_ckpt(ckpt_path, ignore_keys)
|
|
1616
|
+
|
|
1617
|
+
def init_from_ckpt(self, path, ignore_keys=list(), only_model=False):
|
|
1618
|
+
sd = torch.load(path, map_location="cpu")
|
|
1619
|
+
if "state_dict" in list(sd.keys()):
|
|
1620
|
+
sd = sd["state_dict"]
|
|
1621
|
+
keys = list(sd.keys())
|
|
1622
|
+
for k in keys:
|
|
1623
|
+
for ik in ignore_keys:
|
|
1624
|
+
if k.startswith(ik):
|
|
1625
|
+
print("Deleting key {} from state_dict.".format(k))
|
|
1626
|
+
del sd[k]
|
|
1627
|
+
|
|
1628
|
+
# make it explicit, finetune by including extra input channels
|
|
1629
|
+
if exists(self.finetune_keys) and k in self.finetune_keys:
|
|
1630
|
+
new_entry = None
|
|
1631
|
+
for name, param in self.named_parameters():
|
|
1632
|
+
if name in self.finetune_keys:
|
|
1633
|
+
print(
|
|
1634
|
+
f"modifying key '{name}' and keeping its original {self.keep_dims} (channels) dimensions only")
|
|
1635
|
+
new_entry = torch.zeros_like(param) # zero init
|
|
1636
|
+
assert exists(new_entry), 'did not find matching parameter to modify'
|
|
1637
|
+
new_entry[:, :self.keep_dims, ...] = sd[k]
|
|
1638
|
+
sd[k] = new_entry
|
|
1639
|
+
|
|
1640
|
+
missing, unexpected = self.load_state_dict(sd, strict=False) if not only_model else self.model.load_state_dict(
|
|
1641
|
+
sd, strict=False)
|
|
1642
|
+
print(f"Restored from {path} with {len(missing)} missing and {len(unexpected)} unexpected keys")
|
|
1643
|
+
if len(missing) > 0:
|
|
1644
|
+
print(f"Missing Keys: {missing}")
|
|
1645
|
+
if len(unexpected) > 0:
|
|
1646
|
+
print(f"Unexpected Keys: {unexpected}")
|
|
1647
|
+
|
|
1648
|
+
@torch.no_grad()
|
|
1649
|
+
def log_images(self, batch, N=8, n_row=4, sample=True, ddim_steps=200, ddim_eta=1., return_keys=None,
|
|
1650
|
+
quantize_denoised=True, inpaint=True, plot_denoise_rows=False, plot_progressive_rows=True,
|
|
1651
|
+
plot_diffusion_rows=True, unconditional_guidance_scale=1., unconditional_guidance_label=None,
|
|
1652
|
+
use_ema_scope=True,
|
|
1653
|
+
**kwargs):
|
|
1654
|
+
ema_scope = self.ema_scope if use_ema_scope else nullcontext
|
|
1655
|
+
use_ddim = ddim_steps is not None
|
|
1656
|
+
|
|
1657
|
+
log = dict()
|
|
1658
|
+
z, c, x, xrec, xc = self.get_input(batch, self.first_stage_key, bs=N, return_first_stage_outputs=True)
|
|
1659
|
+
c_cat, c = c["c_concat"][0], c["c_crossattn"][0]
|
|
1660
|
+
N = min(x.shape[0], N)
|
|
1661
|
+
n_row = min(x.shape[0], n_row)
|
|
1662
|
+
log["inputs"] = x
|
|
1663
|
+
log["reconstruction"] = xrec
|
|
1664
|
+
if self.model.conditioning_key is not None:
|
|
1665
|
+
if hasattr(self.cond_stage_model, "decode"):
|
|
1666
|
+
xc = self.cond_stage_model.decode(c)
|
|
1667
|
+
log["conditioning"] = xc
|
|
1668
|
+
elif self.cond_stage_key in ["caption", "txt"]:
|
|
1669
|
+
xc = log_txt_as_img((x.shape[2], x.shape[3]), batch[self.cond_stage_key], size=x.shape[2] // 25)
|
|
1670
|
+
log["conditioning"] = xc
|
|
1671
|
+
elif self.cond_stage_key in ['class_label', 'cls']:
|
|
1672
|
+
xc = log_txt_as_img((x.shape[2], x.shape[3]), batch["human_label"], size=x.shape[2] // 25)
|
|
1673
|
+
log['conditioning'] = xc
|
|
1674
|
+
elif isimage(xc):
|
|
1675
|
+
log["conditioning"] = xc
|
|
1676
|
+
if ismap(xc):
|
|
1677
|
+
log["original_conditioning"] = self.to_rgb(xc)
|
|
1678
|
+
|
|
1679
|
+
if not (self.c_concat_log_start is None and self.c_concat_log_end is None):
|
|
1680
|
+
log["c_concat_decoded"] = self.decode_first_stage(c_cat[:, self.c_concat_log_start:self.c_concat_log_end])
|
|
1681
|
+
|
|
1682
|
+
if plot_diffusion_rows:
|
|
1683
|
+
# get diffusion row
|
|
1684
|
+
diffusion_row = list()
|
|
1685
|
+
z_start = z[:n_row]
|
|
1686
|
+
for t in range(self.num_timesteps):
|
|
1687
|
+
if t % self.log_every_t == 0 or t == self.num_timesteps - 1:
|
|
1688
|
+
t = repeat(torch.tensor([t]), '1 -> b', b=n_row)
|
|
1689
|
+
t = t.to(self.device).long()
|
|
1690
|
+
noise = torch.randn_like(z_start)
|
|
1691
|
+
z_noisy = self.q_sample(x_start=z_start, t=t, noise=noise)
|
|
1692
|
+
diffusion_row.append(self.decode_first_stage(z_noisy))
|
|
1693
|
+
|
|
1694
|
+
diffusion_row = torch.stack(diffusion_row) # n_log_step, n_row, C, H, W
|
|
1695
|
+
diffusion_grid = rearrange(diffusion_row, 'n b c h w -> b n c h w')
|
|
1696
|
+
diffusion_grid = rearrange(diffusion_grid, 'b n c h w -> (b n) c h w')
|
|
1697
|
+
diffusion_grid = make_grid(diffusion_grid, nrow=diffusion_row.shape[0])
|
|
1698
|
+
log["diffusion_row"] = diffusion_grid
|
|
1699
|
+
|
|
1700
|
+
if sample:
|
|
1701
|
+
# get denoise row
|
|
1702
|
+
with ema_scope("Sampling"):
|
|
1703
|
+
samples, z_denoise_row = self.sample_log(cond={"c_concat": [c_cat], "c_crossattn": [c]},
|
|
1704
|
+
batch_size=N, ddim=use_ddim,
|
|
1705
|
+
ddim_steps=ddim_steps, eta=ddim_eta)
|
|
1706
|
+
# samples, z_denoise_row = self.sample(cond=c, batch_size=N, return_intermediates=True)
|
|
1707
|
+
x_samples = self.decode_first_stage(samples)
|
|
1708
|
+
log["samples"] = x_samples
|
|
1709
|
+
if plot_denoise_rows:
|
|
1710
|
+
denoise_grid = self._get_denoise_row_from_list(z_denoise_row)
|
|
1711
|
+
log["denoise_row"] = denoise_grid
|
|
1712
|
+
|
|
1713
|
+
if unconditional_guidance_scale > 1.0:
|
|
1714
|
+
uc_cross = self.get_unconditional_conditioning(N, unconditional_guidance_label)
|
|
1715
|
+
uc_cat = c_cat
|
|
1716
|
+
uc_full = {"c_concat": [uc_cat], "c_crossattn": [uc_cross]}
|
|
1717
|
+
with ema_scope("Sampling with classifier-free guidance"):
|
|
1718
|
+
samples_cfg, _ = self.sample_log(cond={"c_concat": [c_cat], "c_crossattn": [c]},
|
|
1719
|
+
batch_size=N, ddim=use_ddim,
|
|
1720
|
+
ddim_steps=ddim_steps, eta=ddim_eta,
|
|
1721
|
+
unconditional_guidance_scale=unconditional_guidance_scale,
|
|
1722
|
+
unconditional_conditioning=uc_full,
|
|
1723
|
+
)
|
|
1724
|
+
x_samples_cfg = self.decode_first_stage(samples_cfg)
|
|
1725
|
+
log[f"samples_cfg_scale_{unconditional_guidance_scale:.2f}"] = x_samples_cfg
|
|
1726
|
+
|
|
1727
|
+
return log
|
|
1728
|
+
|
|
1729
|
+
|
|
1730
|
+
class LatentInpaintDiffusion(LatentFinetuneDiffusion):
|
|
1731
|
+
"""
|
|
1732
|
+
can either run as pure inpainting model (only concat mode) or with mixed conditionings,
|
|
1733
|
+
e.g. mask as concat and text via cross-attn.
|
|
1734
|
+
To disable finetuning mode, set finetune_keys to None
|
|
1735
|
+
"""
|
|
1736
|
+
|
|
1737
|
+
def __init__(self,
|
|
1738
|
+
concat_keys=("mask", "masked_image"),
|
|
1739
|
+
masked_image_key="masked_image",
|
|
1740
|
+
*args, **kwargs
|
|
1741
|
+
):
|
|
1742
|
+
super().__init__(concat_keys, *args, **kwargs)
|
|
1743
|
+
self.masked_image_key = masked_image_key
|
|
1744
|
+
assert self.masked_image_key in concat_keys
|
|
1745
|
+
|
|
1746
|
+
@torch.no_grad()
|
|
1747
|
+
def get_input(self, batch, k, cond_key=None, bs=None, return_first_stage_outputs=False):
|
|
1748
|
+
# note: restricted to non-trainable encoders currently
|
|
1749
|
+
assert not self.cond_stage_trainable, 'trainable cond stages not yet supported for inpainting'
|
|
1750
|
+
z, c, x, xrec, xc = super().get_input(batch, self.first_stage_key, return_first_stage_outputs=True,
|
|
1751
|
+
force_c_encode=True, return_original_cond=True, bs=bs)
|
|
1752
|
+
|
|
1753
|
+
assert exists(self.concat_keys)
|
|
1754
|
+
c_cat = list()
|
|
1755
|
+
for ck in self.concat_keys:
|
|
1756
|
+
cc = rearrange(batch[ck], 'b h w c -> b c h w').to(memory_format=torch.contiguous_format).float()
|
|
1757
|
+
if bs is not None:
|
|
1758
|
+
cc = cc[:bs]
|
|
1759
|
+
cc = cc.to(self.device)
|
|
1760
|
+
bchw = z.shape
|
|
1761
|
+
if ck != self.masked_image_key:
|
|
1762
|
+
cc = torch.nn.functional.interpolate(cc, size=bchw[-2:])
|
|
1763
|
+
else:
|
|
1764
|
+
cc = self.get_first_stage_encoding(self.encode_first_stage(cc))
|
|
1765
|
+
c_cat.append(cc)
|
|
1766
|
+
c_cat = torch.cat(c_cat, dim=1)
|
|
1767
|
+
all_conds = {"c_concat": [c_cat], "c_crossattn": [c]}
|
|
1768
|
+
if return_first_stage_outputs:
|
|
1769
|
+
return z, all_conds, x, xrec, xc
|
|
1770
|
+
return z, all_conds
|
|
1771
|
+
|
|
1772
|
+
@torch.no_grad()
|
|
1773
|
+
def log_images(self, *args, **kwargs):
|
|
1774
|
+
log = super(LatentInpaintDiffusion, self).log_images(*args, **kwargs)
|
|
1775
|
+
log["masked_image"] = rearrange(args[0]["masked_image"],
|
|
1776
|
+
'b h w c -> b c h w').to(memory_format=torch.contiguous_format).float()
|
|
1777
|
+
return log
|
|
1778
|
+
|
|
1779
|
+
|
|
1780
|
+
class LatentDepth2ImageDiffusion(LatentFinetuneDiffusion):
|
|
1781
|
+
"""
|
|
1782
|
+
condition on monocular depth estimation
|
|
1783
|
+
"""
|
|
1784
|
+
|
|
1785
|
+
def __init__(self, depth_stage_config, concat_keys=("midas_in",), *args, **kwargs):
|
|
1786
|
+
super().__init__(concat_keys=concat_keys, *args, **kwargs)
|
|
1787
|
+
self.depth_model = instantiate_from_config(depth_stage_config)
|
|
1788
|
+
self.depth_stage_key = concat_keys[0]
|
|
1789
|
+
|
|
1790
|
+
@torch.no_grad()
|
|
1791
|
+
def get_input(self, batch, k, cond_key=None, bs=None, return_first_stage_outputs=False):
|
|
1792
|
+
# note: restricted to non-trainable encoders currently
|
|
1793
|
+
assert not self.cond_stage_trainable, 'trainable cond stages not yet supported for depth2img'
|
|
1794
|
+
z, c, x, xrec, xc = super().get_input(batch, self.first_stage_key, return_first_stage_outputs=True,
|
|
1795
|
+
force_c_encode=True, return_original_cond=True, bs=bs)
|
|
1796
|
+
|
|
1797
|
+
assert exists(self.concat_keys)
|
|
1798
|
+
assert len(self.concat_keys) == 1
|
|
1799
|
+
c_cat = list()
|
|
1800
|
+
for ck in self.concat_keys:
|
|
1801
|
+
cc = batch[ck]
|
|
1802
|
+
if bs is not None:
|
|
1803
|
+
cc = cc[:bs]
|
|
1804
|
+
cc = cc.to(self.device)
|
|
1805
|
+
cc = self.depth_model(cc)
|
|
1806
|
+
cc = torch.nn.functional.interpolate(
|
|
1807
|
+
cc,
|
|
1808
|
+
size=z.shape[2:],
|
|
1809
|
+
mode="bicubic",
|
|
1810
|
+
align_corners=False,
|
|
1811
|
+
)
|
|
1812
|
+
|
|
1813
|
+
depth_min, depth_max = torch.amin(cc, dim=[1, 2, 3], keepdim=True), torch.amax(cc, dim=[1, 2, 3],
|
|
1814
|
+
keepdim=True)
|
|
1815
|
+
cc = 2. * (cc - depth_min) / (depth_max - depth_min + 0.001) - 1.
|
|
1816
|
+
c_cat.append(cc)
|
|
1817
|
+
c_cat = torch.cat(c_cat, dim=1)
|
|
1818
|
+
all_conds = {"c_concat": [c_cat], "c_crossattn": [c]}
|
|
1819
|
+
if return_first_stage_outputs:
|
|
1820
|
+
return z, all_conds, x, xrec, xc
|
|
1821
|
+
return z, all_conds
|
|
1822
|
+
|
|
1823
|
+
@torch.no_grad()
|
|
1824
|
+
def log_images(self, *args, **kwargs):
|
|
1825
|
+
log = super().log_images(*args, **kwargs)
|
|
1826
|
+
depth = self.depth_model(args[0][self.depth_stage_key])
|
|
1827
|
+
depth_min, depth_max = torch.amin(depth, dim=[1, 2, 3], keepdim=True), \
|
|
1828
|
+
torch.amax(depth, dim=[1, 2, 3], keepdim=True)
|
|
1829
|
+
log["depth"] = 2. * (depth - depth_min) / (depth_max - depth_min) - 1.
|
|
1830
|
+
return log
|
|
1831
|
+
|
|
1832
|
+
|
|
1833
|
+
class LatentUpscaleFinetuneDiffusion(LatentFinetuneDiffusion):
|
|
1834
|
+
"""
|
|
1835
|
+
condition on low-res image (and optionally on some spatial noise augmentation)
|
|
1836
|
+
"""
|
|
1837
|
+
def __init__(self, concat_keys=("lr",), reshuffle_patch_size=None,
|
|
1838
|
+
low_scale_config=None, low_scale_key=None, *args, **kwargs):
|
|
1839
|
+
super().__init__(concat_keys=concat_keys, *args, **kwargs)
|
|
1840
|
+
self.reshuffle_patch_size = reshuffle_patch_size
|
|
1841
|
+
self.low_scale_model = None
|
|
1842
|
+
if low_scale_config is not None:
|
|
1843
|
+
print("Initializing a low-scale model")
|
|
1844
|
+
assert exists(low_scale_key)
|
|
1845
|
+
self.instantiate_low_stage(low_scale_config)
|
|
1846
|
+
self.low_scale_key = low_scale_key
|
|
1847
|
+
|
|
1848
|
+
def instantiate_low_stage(self, config):
|
|
1849
|
+
model = instantiate_from_config(config)
|
|
1850
|
+
self.low_scale_model = model.eval()
|
|
1851
|
+
self.low_scale_model.train = disabled_train
|
|
1852
|
+
for param in self.low_scale_model.parameters():
|
|
1853
|
+
param.requires_grad = False
|
|
1854
|
+
|
|
1855
|
+
@torch.no_grad()
|
|
1856
|
+
def get_input(self, batch, k, cond_key=None, bs=None, return_first_stage_outputs=False):
|
|
1857
|
+
# note: restricted to non-trainable encoders currently
|
|
1858
|
+
assert not self.cond_stage_trainable, 'trainable cond stages not yet supported for upscaling-ft'
|
|
1859
|
+
z, c, x, xrec, xc = super().get_input(batch, self.first_stage_key, return_first_stage_outputs=True,
|
|
1860
|
+
force_c_encode=True, return_original_cond=True, bs=bs)
|
|
1861
|
+
|
|
1862
|
+
assert exists(self.concat_keys)
|
|
1863
|
+
assert len(self.concat_keys) == 1
|
|
1864
|
+
# optionally make spatial noise_level here
|
|
1865
|
+
c_cat = list()
|
|
1866
|
+
noise_level = None
|
|
1867
|
+
for ck in self.concat_keys:
|
|
1868
|
+
cc = batch[ck]
|
|
1869
|
+
cc = rearrange(cc, 'b h w c -> b c h w')
|
|
1870
|
+
if exists(self.reshuffle_patch_size):
|
|
1871
|
+
assert isinstance(self.reshuffle_patch_size, int)
|
|
1872
|
+
cc = rearrange(cc, 'b c (p1 h) (p2 w) -> b (p1 p2 c) h w',
|
|
1873
|
+
p1=self.reshuffle_patch_size, p2=self.reshuffle_patch_size)
|
|
1874
|
+
if bs is not None:
|
|
1875
|
+
cc = cc[:bs]
|
|
1876
|
+
cc = cc.to(self.device)
|
|
1877
|
+
if exists(self.low_scale_model) and ck == self.low_scale_key:
|
|
1878
|
+
cc, noise_level = self.low_scale_model(cc)
|
|
1879
|
+
c_cat.append(cc)
|
|
1880
|
+
c_cat = torch.cat(c_cat, dim=1)
|
|
1881
|
+
if exists(noise_level):
|
|
1882
|
+
all_conds = {"c_concat": [c_cat], "c_crossattn": [c], "c_adm": noise_level}
|
|
1883
|
+
else:
|
|
1884
|
+
all_conds = {"c_concat": [c_cat], "c_crossattn": [c]}
|
|
1885
|
+
if return_first_stage_outputs:
|
|
1886
|
+
return z, all_conds, x, xrec, xc
|
|
1887
|
+
return z, all_conds
|
|
1888
|
+
|
|
1889
|
+
@torch.no_grad()
|
|
1890
|
+
def log_images(self, *args, **kwargs):
|
|
1891
|
+
log = super().log_images(*args, **kwargs)
|
|
1892
|
+
log["lr"] = rearrange(args[0]["lr"], 'b h w c -> b c h w')
|
|
1893
|
+
return log
|