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,101 @@
|
|
|
1
|
+
from typing import List, Literal, Optional, Tuple
|
|
2
|
+
|
|
3
|
+
from pydantic.dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from ..base import ModelConfig
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class LBMConfig(ModelConfig):
|
|
10
|
+
"""This is the Config for LBM Model class which defines all the useful parameters to be used in the model.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
|
|
14
|
+
source_key (str):
|
|
15
|
+
Key for the source image. Defaults to "source_image"
|
|
16
|
+
|
|
17
|
+
target_key (str):
|
|
18
|
+
Key for the target image. Defaults to "target_image"
|
|
19
|
+
|
|
20
|
+
mask_key (Optional[str]):
|
|
21
|
+
Key for the mask showing the valid pixels. Defaults to None
|
|
22
|
+
|
|
23
|
+
latent_loss_type (str):
|
|
24
|
+
Loss type to use. Defaults to "l2". Choices are "l2", "l1"
|
|
25
|
+
|
|
26
|
+
pixel_loss_type (str):
|
|
27
|
+
Pixel loss type to use. Defaults to "l2". Choices are "l2", "l1", "lpips"
|
|
28
|
+
|
|
29
|
+
pixel_loss_max_size (int):
|
|
30
|
+
Maximum size of the image for pixel loss.
|
|
31
|
+
The image will be cropped to this size to reduce decoding computation cost. Defaults to 512
|
|
32
|
+
|
|
33
|
+
pixel_loss_weight (float):
|
|
34
|
+
Weight of the pixel loss. Defaults to 0.0
|
|
35
|
+
|
|
36
|
+
timestep_sampling (str):
|
|
37
|
+
Timestep sampling to use. Defaults to "uniform". Choices are "uniform"
|
|
38
|
+
|
|
39
|
+
input_key (str):
|
|
40
|
+
Key for the input. Defaults to "image"
|
|
41
|
+
|
|
42
|
+
controlnet_input_key (str):
|
|
43
|
+
Key for the controlnet conditioning. Defaults to "controlnet_conditioning"
|
|
44
|
+
|
|
45
|
+
adapter_input_key (str):
|
|
46
|
+
Key for the adapter conditioning. Defaults to "adapter_conditioning"
|
|
47
|
+
|
|
48
|
+
ucg_keys (Optional[List[str]]):
|
|
49
|
+
List of keys for which we enforce zero_conditioning during Classifier-free guidance. Defaults to None
|
|
50
|
+
|
|
51
|
+
prediction_type (str):
|
|
52
|
+
Type of prediction to use. Defaults to "epsilon". Choices are "epsilon", "v_prediction", "flow
|
|
53
|
+
|
|
54
|
+
logit_mean (Optional[float]):
|
|
55
|
+
Mean of the logit for the log normal distribution. Defaults to 0.0
|
|
56
|
+
|
|
57
|
+
logit_std (Optional[float]):
|
|
58
|
+
Standard deviation of the logit for the log normal distribution. Defaults to 1.0
|
|
59
|
+
|
|
60
|
+
guidance_scale (Optional[float]):
|
|
61
|
+
The guidance scale. Useful for finetunning guidance distilled diffusion models. Defaults to None
|
|
62
|
+
|
|
63
|
+
selected_timesteps (Optional[List[float]]):
|
|
64
|
+
List of selected timesteps to be sampled from if using `custom_timesteps` timestep sampling. Defaults to None
|
|
65
|
+
|
|
66
|
+
prob (Optional[List[float]]):
|
|
67
|
+
List of probabilities for the selected timesteps if using `custom_timesteps` timestep sampling. Defaults to None
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
source_key: str = "source_image"
|
|
71
|
+
target_key: str = "target_image"
|
|
72
|
+
mask_key: Optional[str] = None
|
|
73
|
+
latent_loss_weight: float = 1.0
|
|
74
|
+
latent_loss_type: Literal["l2", "l1"] = "l2"
|
|
75
|
+
pixel_loss_type: Literal["l2", "l1", "lpips"] = "l2"
|
|
76
|
+
pixel_loss_max_size: int = 512
|
|
77
|
+
pixel_loss_weight: float = 0.0
|
|
78
|
+
timestep_sampling: Literal["uniform", "log_normal", "custom_timesteps"] = "uniform"
|
|
79
|
+
logit_mean: Optional[float] = 0.0
|
|
80
|
+
logit_std: Optional[float] = 1.0
|
|
81
|
+
selected_timesteps: Optional[List[float]] = None
|
|
82
|
+
prob: Optional[List[float]] = None
|
|
83
|
+
bridge_noise_sigma: float = 0.001
|
|
84
|
+
|
|
85
|
+
def __post_init__(self):
|
|
86
|
+
super().__post_init__()
|
|
87
|
+
if self.timestep_sampling == "log_normal":
|
|
88
|
+
assert isinstance(self.logit_mean, float) and isinstance(
|
|
89
|
+
self.logit_std, float
|
|
90
|
+
), "logit_mean and logit_std should be float for log_normal timestep sampling"
|
|
91
|
+
|
|
92
|
+
if self.timestep_sampling == "custom_timesteps":
|
|
93
|
+
assert isinstance(self.selected_timesteps, list) and isinstance(
|
|
94
|
+
self.prob, list
|
|
95
|
+
), "timesteps and prob should be list for custom_timesteps timestep sampling"
|
|
96
|
+
assert len(self.selected_timesteps) == len(
|
|
97
|
+
self.prob
|
|
98
|
+
), "timesteps and prob should be of same length for custom_timesteps timestep sampling"
|
|
99
|
+
assert (
|
|
100
|
+
sum(self.prob) == 1
|
|
101
|
+
), "prob should sum to 1 for custom_timesteps timestep sampling"
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
2
|
+
|
|
3
|
+
import lpips
|
|
4
|
+
import numpy as np
|
|
5
|
+
import torch
|
|
6
|
+
import torch.nn as nn
|
|
7
|
+
from diffusers.schedulers import FlowMatchEulerDiscreteScheduler
|
|
8
|
+
from tqdm import tqdm
|
|
9
|
+
|
|
10
|
+
from ..base.base_model import BaseModel
|
|
11
|
+
from ..embedders import ConditionerWrapper
|
|
12
|
+
from ..unets import DiffusersUNet2DCondWrapper, DiffusersUNet2DWrapper
|
|
13
|
+
from ..vae import AutoencoderKLDiffusers
|
|
14
|
+
from .lbm_config import LBMConfig
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class LBMModel(BaseModel):
|
|
18
|
+
"""This is the LBM class which defines the model."""
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def load_from_config(cls, config: LBMConfig):
|
|
22
|
+
return cls(config=config)
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
config: LBMConfig,
|
|
27
|
+
denoiser: Union[
|
|
28
|
+
DiffusersUNet2DWrapper,
|
|
29
|
+
DiffusersUNet2DCondWrapper,
|
|
30
|
+
] = None,
|
|
31
|
+
training_noise_scheduler: FlowMatchEulerDiscreteScheduler = None,
|
|
32
|
+
sampling_noise_scheduler: FlowMatchEulerDiscreteScheduler = None,
|
|
33
|
+
vae: AutoencoderKLDiffusers = None,
|
|
34
|
+
conditioner: ConditionerWrapper = None,
|
|
35
|
+
):
|
|
36
|
+
BaseModel.__init__(self, config)
|
|
37
|
+
|
|
38
|
+
self.vae = vae
|
|
39
|
+
self.denoiser = denoiser
|
|
40
|
+
self.conditioner = conditioner
|
|
41
|
+
self.sampling_noise_scheduler = sampling_noise_scheduler
|
|
42
|
+
self.training_noise_scheduler = training_noise_scheduler
|
|
43
|
+
self.timestep_sampling = config.timestep_sampling
|
|
44
|
+
self.latent_loss_type = config.latent_loss_type
|
|
45
|
+
self.latent_loss_weight = config.latent_loss_weight
|
|
46
|
+
self.pixel_loss_type = config.pixel_loss_type
|
|
47
|
+
self.pixel_loss_max_size = config.pixel_loss_max_size
|
|
48
|
+
self.pixel_loss_weight = config.pixel_loss_weight
|
|
49
|
+
self.logit_mean = config.logit_mean
|
|
50
|
+
self.logit_std = config.logit_std
|
|
51
|
+
self.prob = config.prob
|
|
52
|
+
self.selected_timesteps = config.selected_timesteps
|
|
53
|
+
self.source_key = config.source_key
|
|
54
|
+
self.target_key = config.target_key
|
|
55
|
+
self.mask_key = config.mask_key
|
|
56
|
+
self.bridge_noise_sigma = config.bridge_noise_sigma
|
|
57
|
+
|
|
58
|
+
self.num_iterations = nn.Parameter(
|
|
59
|
+
torch.tensor(0, dtype=torch.float32), requires_grad=False
|
|
60
|
+
)
|
|
61
|
+
if self.pixel_loss_type == "lpips" and self.pixel_loss_weight > 0:
|
|
62
|
+
self.lpips_loss = lpips.LPIPS(net="vgg")
|
|
63
|
+
|
|
64
|
+
else:
|
|
65
|
+
self.lpips_loss = None
|
|
66
|
+
|
|
67
|
+
def on_fit_start(self, device: torch.device | None = None, *args, **kwargs):
|
|
68
|
+
"""Called when the training starts"""
|
|
69
|
+
super().on_fit_start(device=device, *args, **kwargs)
|
|
70
|
+
if self.vae is not None:
|
|
71
|
+
self.vae.on_fit_start(device=device, *args, **kwargs)
|
|
72
|
+
if self.conditioner is not None:
|
|
73
|
+
self.conditioner.on_fit_start(device=device, *args, **kwargs)
|
|
74
|
+
|
|
75
|
+
def forward(self, batch: Dict[str, Any], step=0, batch_idx=0, *args, **kwargs):
|
|
76
|
+
self.num_iterations += 1
|
|
77
|
+
|
|
78
|
+
# Get inputs/latents
|
|
79
|
+
if self.vae is not None:
|
|
80
|
+
vae_inputs = batch[self.target_key]
|
|
81
|
+
z = self.vae.encode(vae_inputs)
|
|
82
|
+
downsampling_factor = self.vae.downsampling_factor
|
|
83
|
+
else:
|
|
84
|
+
z = batch[self.target_key]
|
|
85
|
+
downsampling_factor = 1
|
|
86
|
+
|
|
87
|
+
if self.mask_key in batch:
|
|
88
|
+
valid_mask = batch[self.mask_key].bool()[:, 0, :, :].unsqueeze(1)
|
|
89
|
+
invalid_mask = ~valid_mask
|
|
90
|
+
valid_mask_for_latent = ~torch.max_pool2d(
|
|
91
|
+
invalid_mask.float(),
|
|
92
|
+
downsampling_factor,
|
|
93
|
+
downsampling_factor,
|
|
94
|
+
).bool()
|
|
95
|
+
valid_mask_for_latent = valid_mask_for_latent.repeat((1, z.shape[1], 1, 1))
|
|
96
|
+
|
|
97
|
+
else:
|
|
98
|
+
valid_mask = torch.ones_like(batch[self.target_key]).bool()
|
|
99
|
+
valid_mask_for_latent = torch.ones_like(z).bool()
|
|
100
|
+
|
|
101
|
+
source_image = batch[self.source_key]
|
|
102
|
+
source_image = torch.nn.functional.interpolate(
|
|
103
|
+
source_image,
|
|
104
|
+
size=batch[self.target_key].shape[-2:],
|
|
105
|
+
mode="bilinear",
|
|
106
|
+
align_corners=False,
|
|
107
|
+
).to(z.dtype)
|
|
108
|
+
if self.vae is not None:
|
|
109
|
+
z_source = self.vae.encode(source_image)
|
|
110
|
+
|
|
111
|
+
else:
|
|
112
|
+
z_source = source_image
|
|
113
|
+
|
|
114
|
+
conditioning = self._get_conditioning(batch, *args, **kwargs)
|
|
115
|
+
|
|
116
|
+
timestep = self._timestep_sampling(n_samples=z.shape[0], device=z.device)
|
|
117
|
+
sigmas = self._get_sigmas(
|
|
118
|
+
self.training_noise_scheduler, timestep, n_dim=4, device=z.device
|
|
119
|
+
)
|
|
120
|
+
noisy_sample = (
|
|
121
|
+
sigmas * z_source
|
|
122
|
+
+ (1.0 - sigmas) * z
|
|
123
|
+
+ self.bridge_noise_sigma
|
|
124
|
+
* (sigmas * (1.0 - sigmas)) ** 0.5
|
|
125
|
+
* torch.randn_like(z)
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
for i, t in enumerate(timestep):
|
|
129
|
+
if t.item() == self.training_noise_scheduler.timesteps[0]:
|
|
130
|
+
noisy_sample[i] = z_source[i]
|
|
131
|
+
|
|
132
|
+
prediction = self.denoiser(
|
|
133
|
+
sample=noisy_sample,
|
|
134
|
+
timestep=timestep,
|
|
135
|
+
conditioning=conditioning,
|
|
136
|
+
*args,
|
|
137
|
+
**kwargs,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
target = z_source - z
|
|
141
|
+
denoised_sample = noisy_sample - prediction * sigmas
|
|
142
|
+
target_pixels = batch[self.target_key]
|
|
143
|
+
|
|
144
|
+
if self.latent_loss_weight > 0:
|
|
145
|
+
loss = self.latent_loss(prediction, target.detach(), valid_mask_for_latent)
|
|
146
|
+
latent_recon_loss = loss.mean()
|
|
147
|
+
else:
|
|
148
|
+
loss = torch.zeros(z.shape[0], device=z.device)
|
|
149
|
+
latent_recon_loss = torch.zeros_like(loss)
|
|
150
|
+
|
|
151
|
+
if self.pixel_loss_weight > 0:
|
|
152
|
+
denoised_sample = self._predicted_x_0(
|
|
153
|
+
model_output=prediction,
|
|
154
|
+
sample=noisy_sample,
|
|
155
|
+
sigmas=sigmas,
|
|
156
|
+
)
|
|
157
|
+
pixel_loss = self.pixel_loss(
|
|
158
|
+
denoised_sample, target_pixels.detach(), valid_mask
|
|
159
|
+
)
|
|
160
|
+
loss += self.pixel_loss_weight * pixel_loss
|
|
161
|
+
else:
|
|
162
|
+
pixel_loss = torch.zeros_like(latent_recon_loss)
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
"loss": loss.mean(),
|
|
166
|
+
"latent_recon_loss": latent_recon_loss,
|
|
167
|
+
"pixel_recon_loss": pixel_loss.mean(),
|
|
168
|
+
"predicted_hr": denoised_sample,
|
|
169
|
+
"noisy_sample": noisy_sample,
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
def latent_loss(self, prediction, model_input, valid_latent_mask):
|
|
173
|
+
if self.latent_loss_type == "l2":
|
|
174
|
+
return torch.mean(
|
|
175
|
+
(
|
|
176
|
+
(prediction * valid_latent_mask - model_input * valid_latent_mask)
|
|
177
|
+
** 2
|
|
178
|
+
).reshape(model_input.shape[0], -1),
|
|
179
|
+
1,
|
|
180
|
+
)
|
|
181
|
+
elif self.latent_loss_type == "l1":
|
|
182
|
+
return torch.mean(
|
|
183
|
+
torch.abs(
|
|
184
|
+
prediction * valid_latent_mask - model_input * valid_latent_mask
|
|
185
|
+
).reshape(model_input.shape[0], -1),
|
|
186
|
+
1,
|
|
187
|
+
)
|
|
188
|
+
else:
|
|
189
|
+
raise NotImplementedError(f"Loss type {self.latent_loss_type} not implemented")
|
|
190
|
+
|
|
191
|
+
def pixel_loss(self, prediction, model_input, valid_mask):
|
|
192
|
+
latent_crop = self.pixel_loss_max_size // self.vae.downsampling_factor
|
|
193
|
+
input_crop = self.pixel_loss_max_size
|
|
194
|
+
|
|
195
|
+
crop_h = max((prediction.shape[2] - latent_crop), 0)
|
|
196
|
+
crop_w = max((prediction.shape[3] - latent_crop), 0)
|
|
197
|
+
|
|
198
|
+
input_crop_h = max((model_input.shape[2] - self.pixel_loss_max_size), 0)
|
|
199
|
+
input_crop_w = max((model_input.shape[3] - self.pixel_loss_max_size), 0)
|
|
200
|
+
|
|
201
|
+
if crop_h == 0:
|
|
202
|
+
offset_h = 0
|
|
203
|
+
else:
|
|
204
|
+
offset_h = torch.randint(0, crop_h, (1,)).item()
|
|
205
|
+
|
|
206
|
+
if crop_w == 0:
|
|
207
|
+
offset_w = 0
|
|
208
|
+
else:
|
|
209
|
+
offset_w = torch.randint(0, crop_w, (1,)).item()
|
|
210
|
+
input_offset_h = offset_h * self.vae.downsampling_factor
|
|
211
|
+
input_offset_w = offset_w * self.vae.downsampling_factor
|
|
212
|
+
|
|
213
|
+
prediction = prediction[
|
|
214
|
+
:,
|
|
215
|
+
:,
|
|
216
|
+
crop_h - offset_h : min(crop_h - offset_h + latent_crop, prediction.shape[2]),
|
|
217
|
+
crop_w - offset_w : min(crop_w - offset_w + latent_crop, prediction.shape[3]),
|
|
218
|
+
]
|
|
219
|
+
|
|
220
|
+
model_input = model_input[
|
|
221
|
+
:,
|
|
222
|
+
:,
|
|
223
|
+
input_crop_h - input_offset_h : min(input_crop_h - input_offset_h + input_crop, model_input.shape[2]),
|
|
224
|
+
input_crop_w - input_offset_w : min(input_crop_w - input_offset_w + input_crop, model_input.shape[3]),
|
|
225
|
+
]
|
|
226
|
+
|
|
227
|
+
valid_mask = valid_mask[
|
|
228
|
+
:,
|
|
229
|
+
:,
|
|
230
|
+
input_crop_h - input_offset_h : min(input_crop_h - input_offset_h + input_crop, valid_mask.shape[2]),
|
|
231
|
+
input_crop_w - input_offset_w : min(input_crop_w - input_offset_w + input_crop, valid_mask.shape[3]),
|
|
232
|
+
]
|
|
233
|
+
|
|
234
|
+
decoded_prediction = self.vae.decode(prediction).clamp(-1, 1)
|
|
235
|
+
|
|
236
|
+
if self.pixel_loss_type == "l2":
|
|
237
|
+
return torch.mean(
|
|
238
|
+
((decoded_prediction * valid_mask - model_input * valid_mask) ** 2).reshape(model_input.shape[0], -1),
|
|
239
|
+
1,
|
|
240
|
+
)
|
|
241
|
+
elif self.pixel_loss_type == "l1":
|
|
242
|
+
return torch.mean(
|
|
243
|
+
torch.abs(decoded_prediction * valid_mask - model_input * valid_mask).reshape(model_input.shape[0], -1),
|
|
244
|
+
1,
|
|
245
|
+
)
|
|
246
|
+
elif self.pixel_loss_type == "lpips":
|
|
247
|
+
return self.lpips_loss(decoded_prediction * valid_mask, model_input * valid_mask).mean()
|
|
248
|
+
|
|
249
|
+
def _get_conditioning(self, batch: Dict[str, Any], ucg_keys: List[str] = None, set_ucg_rate_zero=False, *args, **kwargs):
|
|
250
|
+
if self.conditioner is not None:
|
|
251
|
+
return self.conditioner(batch, ucg_keys=ucg_keys, set_ucg_rate_zero=set_ucg_rate_zero, vae=self.vae, *args, **kwargs)
|
|
252
|
+
return None
|
|
253
|
+
|
|
254
|
+
def _timestep_sampling(self, n_samples=1, device="cpu"):
|
|
255
|
+
if self.timestep_sampling == "uniform":
|
|
256
|
+
idx = torch.randint(0, self.training_noise_scheduler.config.num_train_timesteps, (n_samples,), device="cpu")
|
|
257
|
+
return self.training_noise_scheduler.timesteps[idx].to(device=device)
|
|
258
|
+
elif self.timestep_sampling == "log_normal":
|
|
259
|
+
u = torch.normal(mean=self.logit_mean, std=self.logit_std, size=(n_samples,), device="cpu")
|
|
260
|
+
u = torch.nn.functional.sigmoid(u)
|
|
261
|
+
indices = (u * self.training_noise_scheduler.config.num_train_timesteps).long()
|
|
262
|
+
return self.training_noise_scheduler.timesteps[indices].to(device=device)
|
|
263
|
+
elif self.timestep_sampling == "custom_timesteps":
|
|
264
|
+
idx = np.random.choice(len(self.selected_timesteps), n_samples, p=self.prob)
|
|
265
|
+
return torch.tensor(self.selected_timesteps, device=device, dtype=torch.long)[idx]
|
|
266
|
+
|
|
267
|
+
def _predicted_x_0(self, model_output, sample, sigmas=None):
|
|
268
|
+
return sample - model_output * sigmas
|
|
269
|
+
|
|
270
|
+
def _get_sigmas(self, scheduler, timesteps, n_dim=4, dtype=torch.float32, device="cpu"):
|
|
271
|
+
sigmas = scheduler.sigmas.to(device=device, dtype=dtype)
|
|
272
|
+
schedule_timesteps = scheduler.timesteps.to(device)
|
|
273
|
+
timesteps = timesteps.to(device)
|
|
274
|
+
step_indices = [(schedule_timesteps == t).nonzero().item() for t in timesteps]
|
|
275
|
+
sigma = sigmas[step_indices].flatten()
|
|
276
|
+
while len(sigma.shape) < n_dim:
|
|
277
|
+
sigma = sigma.unsqueeze(-1)
|
|
278
|
+
return sigma
|
|
279
|
+
|
|
280
|
+
@torch.no_grad()
|
|
281
|
+
def sample(
|
|
282
|
+
self,
|
|
283
|
+
z: torch.Tensor,
|
|
284
|
+
num_steps: int = 20,
|
|
285
|
+
conditioner_inputs: Optional[Dict[str, Any]] = None,
|
|
286
|
+
max_samples: Optional[int] = None,
|
|
287
|
+
verbose: bool = False,
|
|
288
|
+
mask: Optional[torch.Tensor] = None, # 💡 新增参数
|
|
289
|
+
):
|
|
290
|
+
self.sampling_noise_scheduler.set_timesteps(
|
|
291
|
+
sigmas=np.linspace(1, 1 / num_steps, num_steps)
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
sample = z # 这里的 z 是背景 source 的 latent
|
|
295
|
+
z_bg = z.clone() # 💡 保存原始背景作为融合参考
|
|
296
|
+
|
|
297
|
+
conditioning = self._get_conditioning(conditioner_inputs, set_ucg_rate_zero=True, device=z.device)
|
|
298
|
+
|
|
299
|
+
if max_samples is not None:
|
|
300
|
+
sample = sample[:max_samples]
|
|
301
|
+
z_bg = z_bg[:max_samples]
|
|
302
|
+
if mask is not None:
|
|
303
|
+
mask = mask[:max_samples]
|
|
304
|
+
|
|
305
|
+
if conditioning:
|
|
306
|
+
conditioning["cond"] = {k: v[:max_samples] for k, v in conditioning["cond"].items()}
|
|
307
|
+
|
|
308
|
+
for i, t in tqdm(enumerate(self.sampling_noise_scheduler.timesteps), disable=not verbose):
|
|
309
|
+
if hasattr(self.sampling_noise_scheduler, "scale_model_input"):
|
|
310
|
+
denoiser_input = self.sampling_noise_scheduler.scale_model_input(sample, t)
|
|
311
|
+
else:
|
|
312
|
+
denoiser_input = sample
|
|
313
|
+
|
|
314
|
+
pred = self.denoiser(
|
|
315
|
+
sample=denoiser_input,
|
|
316
|
+
timestep=t.to(z.device).repeat(denoiser_input.shape[0]),
|
|
317
|
+
conditioning=conditioning,
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
sample = self.sampling_noise_scheduler.step(pred, t, sample, return_dict=False)[0]
|
|
321
|
+
|
|
322
|
+
# 💡 核心注入点:Latent Mask Blending
|
|
323
|
+
if mask is not None:
|
|
324
|
+
sample = sample * mask + z_bg * (1.0 - mask)
|
|
325
|
+
|
|
326
|
+
if i < len(self.sampling_noise_scheduler.timesteps) - 1:
|
|
327
|
+
timestep = self.sampling_noise_scheduler.timesteps[i + 1].to(z.device).repeat(sample.shape[0])
|
|
328
|
+
sigmas = self._get_sigmas(self.sampling_noise_scheduler, timestep, n_dim=4, device=z.device)
|
|
329
|
+
sample = sample + self.bridge_noise_sigma * (sigmas * (1.0 - sigmas)) ** 0.5 * torch.randn_like(sample)
|
|
330
|
+
sample = sample.to(z.dtype)
|
|
331
|
+
|
|
332
|
+
if self.vae is not None:
|
|
333
|
+
decoded_sample = self.vae.decode(sample)
|
|
334
|
+
else:
|
|
335
|
+
decoded_sample = sample
|
|
336
|
+
|
|
337
|
+
return decoded_sample
|
|
338
|
+
|
|
339
|
+
def log_samples(self, batch: Dict[str, Any], input_shape: Optional[Tuple[int, int, int]] = None, max_samples: Optional[int] = None, num_steps: Union[int, List[int]] = 20):
|
|
340
|
+
if isinstance(num_steps, int):
|
|
341
|
+
num_steps = [num_steps]
|
|
342
|
+
logs = {}
|
|
343
|
+
N = max_samples if max_samples is not None else len(batch[self.source_key])
|
|
344
|
+
batch = {k: v[:N] for k, v in batch.items()}
|
|
345
|
+
if input_shape is None:
|
|
346
|
+
if self.vae is not None:
|
|
347
|
+
input_shape = batch[self.target_key].shape[2:]
|
|
348
|
+
input_shape = (self.vae.latent_channels, input_shape[0] // self.vae.downsampling_factor, input_shape[1] // self.vae.downsampling_factor)
|
|
349
|
+
else:
|
|
350
|
+
raise ValueError("input_shape must be passed when no VAE is used in the model")
|
|
351
|
+
|
|
352
|
+
for num_step in num_steps:
|
|
353
|
+
source_image = batch[self.source_key]
|
|
354
|
+
source_image = torch.nn.functional.interpolate(source_image, size=batch[self.target_key].shape[2:], mode="bilinear", align_corners=False).to(dtype=self.dtype)
|
|
355
|
+
z = self.vae.encode(source_image) if self.vae is not None else source_image
|
|
356
|
+
|
|
357
|
+
with torch.autocast(dtype=self.dtype, device_type="cuda"):
|
|
358
|
+
logs[f"samples_{num_step}_steps"] = self.sample(z, num_steps=num_step, conditioner_inputs=batch, max_samples=N)
|
|
359
|
+
return logs
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains a collection of U-Net models.
|
|
3
|
+
The :mod:`cr.models.unets` module includes the following classes:
|
|
4
|
+
|
|
5
|
+
- :class:`DiffusersUNet2DWrapper`: A 2D U-Net model for diffusers.
|
|
6
|
+
- :class:`DiffusersUNet2DCondWrapper`: A 2D U-Net model for diffusers with conditional input.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .unet import DiffusersUNet2DCondWrapper, DiffusersUNet2DWrapper
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"DiffusersUNet2DWrapper",
|
|
13
|
+
"DiffusersUNet2DCondWrapper",
|
|
14
|
+
]
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
from typing import Dict, List, Optional, Union
|
|
2
|
+
|
|
3
|
+
import torch
|
|
4
|
+
from diffusers.models import UNet2DConditionModel, UNet2DModel
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class DiffusersUNet2DWrapper(UNet2DModel):
|
|
8
|
+
"""
|
|
9
|
+
Wrapper for the UNet2DModel from diffusers
|
|
10
|
+
|
|
11
|
+
See diffusers' UNet2DModel for more details
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, *args, **kwargs):
|
|
15
|
+
UNet2DModel.__init__(self, *args, **kwargs)
|
|
16
|
+
|
|
17
|
+
def forward(
|
|
18
|
+
self,
|
|
19
|
+
sample: torch.Tensor,
|
|
20
|
+
timestep: Union[torch.Tensor, float, int],
|
|
21
|
+
conditioning: Dict[str, torch.Tensor] = None,
|
|
22
|
+
*args,
|
|
23
|
+
**kwargs,
|
|
24
|
+
):
|
|
25
|
+
"""
|
|
26
|
+
The forward pass of the model
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
|
|
30
|
+
sample (torch.Tensor): The input sample
|
|
31
|
+
timesteps (Union[torch.Tensor, float, int]): The number of timesteps
|
|
32
|
+
"""
|
|
33
|
+
if conditioning is not None:
|
|
34
|
+
class_labels = conditioning["cond"].get("vector", None)
|
|
35
|
+
concat = conditioning["cond"].get("concat", None)
|
|
36
|
+
|
|
37
|
+
else:
|
|
38
|
+
class_labels = None
|
|
39
|
+
concat = None
|
|
40
|
+
|
|
41
|
+
if concat is not None:
|
|
42
|
+
sample = torch.cat([sample, concat], dim=1)
|
|
43
|
+
|
|
44
|
+
return super().forward(sample, timestep, class_labels).sample
|
|
45
|
+
|
|
46
|
+
def freeze(self):
|
|
47
|
+
"""
|
|
48
|
+
Freeze the model
|
|
49
|
+
"""
|
|
50
|
+
self.eval()
|
|
51
|
+
for param in self.parameters():
|
|
52
|
+
param.requires_grad = False
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class DiffusersUNet2DCondWrapper(UNet2DConditionModel):
|
|
56
|
+
"""
|
|
57
|
+
Wrapper for the UNet2DConditionModel from diffusers
|
|
58
|
+
|
|
59
|
+
See diffusers' Unet2DConditionModel for more details
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __init__(self, *args, **kwargs):
|
|
63
|
+
UNet2DConditionModel.__init__(self, *args, **kwargs)
|
|
64
|
+
# BaseModel.__init__(self, config=ModelConfig())
|
|
65
|
+
|
|
66
|
+
def forward(
|
|
67
|
+
self,
|
|
68
|
+
sample: torch.Tensor,
|
|
69
|
+
timestep: Union[torch.Tensor, float, int],
|
|
70
|
+
conditioning: Dict[str, torch.Tensor],
|
|
71
|
+
ip_adapter_cond_embedding: Optional[List[torch.Tensor]] = None,
|
|
72
|
+
down_block_additional_residuals: torch.Tensor = None,
|
|
73
|
+
mid_block_additional_residual: torch.Tensor = None,
|
|
74
|
+
down_intrablock_additional_residuals: torch.Tensor = None,
|
|
75
|
+
*args,
|
|
76
|
+
**kwargs,
|
|
77
|
+
):
|
|
78
|
+
"""
|
|
79
|
+
The forward pass of the model
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
|
|
83
|
+
sample (torch.Tensor): The input sample
|
|
84
|
+
timesteps (Union[torch.Tensor, float, int]): The number of timesteps
|
|
85
|
+
conditioning (Dict[str, torch.Tensor]): The conditioning data
|
|
86
|
+
down_block_additional_residuals (List[torch.Tensor]): Residuals for the down blocks.
|
|
87
|
+
These residuals typically are used for the controlnet.
|
|
88
|
+
mid_block_additional_residual (List[torch.Tensor]): Residuals for the mid blocks.
|
|
89
|
+
These residuals typically are used for the controlnet.
|
|
90
|
+
down_intrablock_additional_residuals (List[torch.Tensor]): Residuals for the down intrablocks.
|
|
91
|
+
These residuals typically are used for the T2I adapters.middle block outputs. Defaults to False
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
assert isinstance(conditioning, dict), "conditionings must be a dictionary"
|
|
95
|
+
# assert "crossattn" in conditioning["cond"], "crossattn must be in conditionings"
|
|
96
|
+
|
|
97
|
+
class_labels = conditioning["cond"].get("vector", None)
|
|
98
|
+
crossattn = conditioning["cond"].get("crossattn", None)
|
|
99
|
+
concat = conditioning["cond"].get("concat", None)
|
|
100
|
+
|
|
101
|
+
# concat conditioning
|
|
102
|
+
if concat is not None:
|
|
103
|
+
sample = torch.cat([sample, concat], dim=1)
|
|
104
|
+
|
|
105
|
+
# down_intrablock_additional_residuals needs to be cloned, since unet will modify it
|
|
106
|
+
if down_intrablock_additional_residuals is not None:
|
|
107
|
+
down_intrablock_additional_residuals_clone = [
|
|
108
|
+
curr_residuals.clone()
|
|
109
|
+
for curr_residuals in down_intrablock_additional_residuals
|
|
110
|
+
]
|
|
111
|
+
else:
|
|
112
|
+
down_intrablock_additional_residuals_clone = None
|
|
113
|
+
|
|
114
|
+
# Check diffusers.models.embeddings.py > MultiIPAdapterImageProjectionLayer > forward() for implementation
|
|
115
|
+
# Exepected format : List[torch.Tensor] of shape (batch_size, num_image_embeds, embed_dim)
|
|
116
|
+
# with length = number of ip_adapters loaded in the ip_adapter_wrapper
|
|
117
|
+
if ip_adapter_cond_embedding is not None:
|
|
118
|
+
added_cond_kwargs = {
|
|
119
|
+
"image_embeds": [
|
|
120
|
+
ip_adapter_embedding.unsqueeze(1)
|
|
121
|
+
for ip_adapter_embedding in ip_adapter_cond_embedding
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
else:
|
|
125
|
+
added_cond_kwargs = None
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
super()
|
|
129
|
+
.forward(
|
|
130
|
+
sample=sample,
|
|
131
|
+
timestep=timestep,
|
|
132
|
+
encoder_hidden_states=crossattn,
|
|
133
|
+
class_labels=class_labels,
|
|
134
|
+
added_cond_kwargs=added_cond_kwargs,
|
|
135
|
+
down_block_additional_residuals=down_block_additional_residuals,
|
|
136
|
+
mid_block_additional_residual=mid_block_additional_residual,
|
|
137
|
+
down_intrablock_additional_residuals=down_intrablock_additional_residuals_clone,
|
|
138
|
+
)
|
|
139
|
+
.sample
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
def freeze(self):
|
|
143
|
+
"""
|
|
144
|
+
Freeze the model
|
|
145
|
+
"""
|
|
146
|
+
self.eval()
|
|
147
|
+
for param in self.parameters():
|
|
148
|
+
param.requires_grad = False
|